✨ 增加脚本回收站功能#1585
Conversation
从回收站(trashScript:)彻底销毁脚本及其关联的 scriptCode:/compiled_resource: 数据,并广播既有的 deleteScripts 事件供下游 4 个清理订阅者(value/permission/ resource/favicon)消费。作为回收站功能的销毁终点,暂无生产调用方,由后续任务 接入。
- Toolbar 新增 leading 槽位,tabs 传入后取代「已安装脚本 + 数量」标题 - 回收站顶栏 = tabs + 搜索 + 清空回收站,与已安装 tab 共用同一条 h-14 顶栏 - 保留提示移到 chips 行右侧;批量栏改为独立条件行 - 脚本数量不再丢失:改由 tab 角标显示(已安装 = scriptList.length,回收站 = trashCount) - 回收站为空时仍渲染带 tabs 的顶栏,避免用户被困在回收站 tab
- prepareScriptByCode 在所有活跃表查找之后增查回收站,命中则复用其 uuid 并置 oldInTrash - 复用 uuid 即保住 storageName → value 与权限不丢;移出回收站由 installScript 的 upsert 不变量保证 - InstallView.inTrash 透出;主按钮改为 还原 / 还原并更新(按版本是否变化) - 安装页新增 in_trash_hint 提示条,告知用户还原会保留原有数据
- zh-CN「7 天」→「7天」:对齐同文件既有的「6小时」体例(空格是我在 plan 里带进去的,zh-TW 自由翻译时就没这个问题) - ja-JP「なし」→「無期限」:该行标签是「ゴミ箱の保存期間」,值为「なし」会被读成「不保存/立刻删」,与「永不清理」语义相反
端到端验证真实扩展时发现:删除脚本后「已安装」列表的行不消失、popup 也不更新, 再点一次删除会报「删除失败: scripts not found」。 根因:Task 3 把删除的广播从 deleteScripts 改为 trashScripts 时,只迁移了 SW 侧的 4 个订阅者(spec 统计的「8 个订阅者」只涵盖 SW 侧),漏了两个页面侧的: - ScriptList/hooks.ts —— 负责从「已安装」列表移除该行 - popup/usePopupData.ts —— popup 列表 单元测试全部 mock 掉消息层,跨上下文的 topic 不匹配跑不出来,3165 个用例无一发现。 同时新增静态护栏 trash_event_partition.test.ts 钉死事件二分: - trashScripts(6) = 脚本不再活跃:注销/停 cron/刷 badge/云端删除/列表移行/popup 移行 - deleteScripts(4) = 销毁数据:value/权限/资源/图标(只在彻底删除时触发) 护栏已验证有牙:把任一订阅者订错边,测试立即失败。
|
1584 不用退回嗎 |
呀好像有force push退回? |
是的,退回了 |
|
@CodFrm 刪掉的記錄,特別是代碼部份,可以改用OPFS儲存嗎?? |
确实可以,我调整一下 |
唉,本來的scriptdao那個代碼我都不知道怎麼migrate了 |
这个影响太大了,不要动吧 |
showTrashTab = trashEnabled || trashCount > 0:关闭只影响以后,站内残留条目仍可见可清, 清空后 tab 才消失。桌面/移动两份重复实现各自补上;回落用渲染期状态比较模式(同 Logger/hooks.ts 写法)而非 effect 内同步 setState,避免 react-hooks/set-state-in-effect。
trashEnabled 为 false 时 requestDeleteScripts 已彻底销毁脚本,之前仍复用 「已移入回收站」文案 + 撤销按钮;点击撤销会因 SW 侧找不到回收站记录而 reject,onClick 里的 void undo() 又把这个 rejection 悄悄吞掉,用户毫无 反馈。改为关闭态只提示删除成功、不给撤销入口;顺手给 undo() 补上 try/catch,异常也会走既有的 trash_undo_failed 提示,不再是无声失败。
…与自定义天数边界 - script.test.ts:钉住 TrashScriptDAO 自身不得默认开缓存(否则安装页/编辑器/ 导入页 new 出来的实例会把整个 storage 常驻内存);buildService() 改为直接 返回 service.trashScriptDAO / service.scriptCodeDAO,不再另 new 一份未缓存 实例,避免测试今后按“先写后读”之外的顺序断言时命中冷热缓存不一致的假红 - GeneralSection:自定义天数输入框与保留时间下拉的 aria-label 曾同为 「回收站保留时间」,读屏会报两个同名控件;改用有区分度的 settings:trash_retention_custom(自定义) - GeneralSection:切到自定义时用 String(days) 播种草稿,存储值为 0(永不) 时会播种出非法的 "0"(低于 Input min=1,UI 显示自相矛盾且永远提交不了), 改为 String(days || 30) - 测试补齐:自定义天数 1/3650 边界必须接受、3651 必须拒绝;「永不」切自定义 时草稿播种为合法默认值
把多选态操作栏从 BatchActionsBar 里抽成独立的 SelectionBar + SelectionBarButton, 回收站表格改为复用它,两边不再各写一套。随之删掉重复的 script:trash_selected — 计数文案改由 SelectionBar 内部统一承载。
单条/批量删除确认框按 trash_enabled 分支:开启态改用可还原文案(修正此前 误用「无法撤销」的既有 bug),关闭态保留原「无法撤销」文案。回收站视图的 清理提示与倒计时同样按 trash_enabled 分支:关闭时天数归零、hint 换成 「回收站已关闭」,避免倒数一个 cleanupExpiredTrash 不会再触发的期限。
审查结论做了一轮完整审查,覆盖了 Service Worker 服务层、消息事件划分、DAO 与缓存、安装、导入、订阅、同步链路、桌面与移动端回收站界面、8 个语言文件,以及相关测试和护栏。 整体设计是扎实的。两阶段删除流程、 审查过程中发现 4 个实际问题,均已在本地修复并补充测试,共拆分为 4 个独立 commit,暂未 push。 已修复问题1.
|
|
@CodFrm 设计层面的观察 的7点你看看需不需要处理吧 |
chrome.alarms.create 对同名 alarm 会取消重建并重置倒计时;SW 在活跃使用时 频繁冷启动,无条件 create 会让 cleanupTrash 永远数不满 12 小时,到期脚本 一直不被清理。对齐 checkUpdate / agentTaskScheduler 已有的 get 守卫模式。 此改动无单元测试:ServiceWorkerManager 的初始化无法在单测中构造, 同模式的 checkUpdate/agentTaskScheduler 守卫亦无测试覆盖。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
取消订阅与订阅更新移除脚本都未传 deleteBy,回收站里这些条目被记成 「本机删除」,来源筛选的「订阅」chip 永远筛不出任何东西。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 还原/彻底删除的条目可能已被其他窗口或到期清理抢先处理,SW 抛 trash scripts not found 时此前是未捕获的 rejection:界面毫无反馈, 陈旧行还留在列表里。现在失败会提示错误并重拉列表对齐真实状态。 - 保留时间为「永不」(0) 时空状态说明会插值出「保留 0 天」;关闭态下 「删除的脚本会先移到这里」也不再成立。分别改用 trash_empty_desc_never (8 语言新增)与既有的关闭态提示文案。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
备份导入会给 ScriptDAO 开缓存后在循环里逐脚本调用 prepareScriptByCode; 回收站查找固定走非缓存路径时,每个导入脚本都触发一次全量 storage 反序列化,大备份导入被拖垮。dao 开了缓存时回收站查找也走同一份模块级缓存。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
检查清单
描述
测试
截图
trash-ui-ux.zip
备注
此前的 #1584 曾被误操作直接合并;main 已恢复到合并前提交,本 PR 用于重新进行正常审阅。
关联 Issue