# Changelog ## 1.1.1 ### 版权与署名 - 版权人改为 **LSY(个人创作)**:`LICENSE`、`package.json` 的 `author`、`NOTICE`、README、 以及 `index.js` / `client.js` 两个源码文件的文件头都写了同一句。 - 版权声明按 MIT 原文格式写在 `LICENSE` 里(`Copyright (c) 2026 LSY (个人创作)`), 这样 GitHub 仍然识别为 MIT,而不是 `NOASSERTION`。 - 代码本身没有任何变化;只是署名。 ## 1.1.0 ### 新增:触发时机与播放频率 **触发时机**(`trigger`):`appStart` 启动应用 / `pageRefresh` 页面刷新 / `newConversation` 新对话 / `anySession` 任意会话。 默认 `pageRefresh`,也就是 1.0.0 的行为。 「启动应用」与「页面刷新」由**宿主**判定:宿主半每次 DSH 运行只挂载一次,它数自己服务过多少次首页渲染—— 第 1 次就是启动应用。这样触发判定和「要不要盖住首帧」用的是同一个计数器,两者不可能互相矛盾。 会话触发没有现成的客户端事件可用(事件表里只有 `connection/reset`、`locale/change`、`slots/changed`、`theme/change`), 所以**保守地包了一层** `uiWorkspace` 的 `startSession` / `openSession` / `connectWorkspace`: 先调用原方法并原样返回其结果,通知失败不影响导航,赋值不成功就不包,卸载时逐个还原。 **播放频率**(`frequency`):`every` 每次 / `daily` 每天一次 / `once` 只播一次 / `times` 限播 N 次。 默认 `every`。计数**存在宿主**(`play-state.json`)而不是浏览器里——只存浏览器的话刷新就忘了、开第二个窗口就各算各的。 播放权由宿主唯一判定并当场扣一次(`POST /claim`),被拒绝的请求不扣,只有真的开播才计数。 次数用完后连首帧遮罩都不再注入,不会先黑屏再放出来。设置页有「重置计数」,否则「只播一次」是一扇只能改文件才能打开的门。 `daily` 按**本机本地日期**判定,不是 24 小时窗口。 ### 变更 - 自带片头改名 `media/default2.mp4` → `media/视频测试.mp4`(路径含非 ASCII,媒体流按 UTF-8 percent-encoding 提供,已验证)。 - 验证从 169 项增加到 252 项,新增:触发×频率判定矩阵、`claim` 真的扣账、被拒绝不扣账、 次数用尽的页面加载不注入遮罩、页面加载时 claim 的是宿主给的 occasion、会话触发在页面加载时一次都不 claim、 会话包装原样返回导航结果并且能被还原。 ## 1.0.0 首个公开版本。 ### 这个插件解决什么 别人的开机动画把「开声音」和「进全屏」绑在同一个动作里——点一下画面,声音来了,窗口也变成了全屏。 本插件把两件事拆开: - `sound: true` 时**先尝试带声音起播**(平台放行就是零点击出声)。 - 被自动播放策略拦下时,画面照常静音播放,**窗口里任意位置**的第一次点击或按键就开声,窗口大小不变。 - `requestFullscreen()` 在整个 `client.js` 里**只有一个调用点**,就在那个**默认关闭**的全屏按钮里;开声那条路径碰不到它。 ### 已修的严重缺陷 **动画结束后整个界面点不动。** 覆盖层是 `position: fixed; inset: 0; z-index: 2147483000` 的全屏盒子, 而槽位注册表会让组件在整个页面生命周期里保持挂载。原来的渲染判断只看了「这次页面加载该不该播」, 没有看「动画是不是已经结束了」: ```js if (!active) return null // 错的:active 永远为 true,播完后那一层还在,继续吞掉所有点击 ``` 于是两个症状同时出现:播完后 `opacity` 淡到 0,界面看起来正常但那层透明盒子仍在吃点击; 点「跳过」则停在状态文字正好落在的「正在加载视频…」那一屏。 修法是把「该不该播」和「现在还在不在播」分开,并让所有 effect 跟着它走 (渲染返回 null **不会**卸载组件,effect 的清理函数不会自己跑): ```js const running = active && phase !== 'done' if (!running) return null ``` 同时加了三道互相独立的保险,因为「界面点不动」是最不能接受的失败: | 保险 | 作用 | |---|---| | `pointerEvents` 跟着淡出绑定 | 一开始淡出就放行点击,即使渲染判断将来又被写坏也吞不掉输入 | | 10 分钟硬上限 | 不依赖任何媒体事件,`ended` / `duration` 全都不来时也一定收场 | | `Esc` 永远可以退出 | 任何退出模式下都生效——全屏层吞得掉鼠标,吞不掉键盘 | ### 其他 - 只在**一次页面加载**时播放:宿主注入的首帧遮罩在 `
` 里就是本次加载;遮罩关掉时退回按页面年龄判断。 这样把插件当场启用、或 HMR 把模块塞进一个开了很久的页面,都不会突然盖住正在干活的窗口。 - 每次真实启动的结果写进 `