Files
DemonGatanjieu-Anomalous_Mo…/docs/plans/customizable-tool-shortcuts.md
T
DemonGatanjieuandClaude Opus 5.5 bd7fb8beaa chore(shortcuts): remove the never-wired shortcut organizer
ui_shortcut_organizer.js and shortcut_layout.js only referenced each other;
the bottom bar is the fixed one built in ui_toolbox.js. Also drops their
eleven locale keys and marks the customizable-shortcuts plan as abandoned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 17:57:41 +08:00

13 KiB

工具箱与快捷栏自定义:交给 Gemini 的实施计划

状态:已放弃。当前是固定快捷栏(见 ui_toolbox.js);按本计划写的 shortcut_layout.js、ui_shortcut_organizer.js 从未接入,已删除。只作历史参考,不要照此实施。 基线:77ae7ce88;开工时以实际 Git 差异和现有代码为准,不回退后续工作。

目标与范围

把左下角做成用户可整理的快捷栏:工具箱的工具能拖到栏中,栏中的可移动工具能拖回工具箱,也能调整顺序。 同时完成短文字、详细提示的出现时间与位置调整。保留当前紧凑布局、工具箱外框尺寸和现有工具行为。 先阅读 AGENTS.md、docs/architecture/frontend.md、docs/architecture/update-guide.md,仅加载本次相关内容。 本任务有拖动状态与持久化,按下面阶段实施;不借机重写整个侧栏、换 UI 框架或引入拖拽依赖。

一、交互设计定稿要求

实施前用简短文字或草图说明:正常、拖出、拖回、排序、容量已满、取消六种状态。 按本计划做出完整方案后直接实施;常规视觉细节由 Gemini 决定,不增加多轮审批。若与现有代码冲突,优先保持业务语义。

1. 工具箱是完整目录,底栏是快捷入口

  • 工具箱始终保留所有可用工具。拖到快捷栏代表“固定”,工具箱卡片仍在,并标注“已固定”。
  • 从快捷栏拖回工具箱代表“从快捷栏移除”,不删除工具、不关闭正在执行的任务、不更改数据。
  • 第一版固定两个锚点:最左的工具箱、最右的设置。它们不能被拖走,防止用户丢失整理和恢复入口。
  • 中间最多 4 个可自定义入口,默认依旧是扫描、模型医生、节点助手、素材库,总共最多 6 个按钮。
  • 工具箱中现有的导入导出中心、提示词工坊、翻译助手、模型来源也能固定到中间位置。
  • 工具箱卡片顺序固定,快捷栏顺序由用户决定。第一版不做工具箱内部自由排序、分组、分页或自由浮动窗口。
  • 拖出只接受快捷栏区域;丢到画布、图库、模型卡片或窗口外一律取消,不能生成节点或触发文件操作。
  • 容量已满时不自动挤走其他工具,提示“快捷栏已满,请先将一个工具移回工具箱”;菜单固定与拖动规则一致。
  • 重复固定不产生副本;已固定工具拖到快捷栏只调整已有位置。
  • 提供“恢复默认快捷栏”,只重置本布局,不调用重置插件全部设置的功能。

2. 工具箱内的可发现性

  • 在工具箱空白背景区域设置低干扰、可读的提示:“拖到下方,固定常用工具;拖回这里,收起快捷入口”。
  • 使用独立的提示/放置区域,不把文字覆盖在卡片上;空间不足时改为底部短提示,不能撑大工具箱。
  • 保持工具箱外框尺寸,工具增多只让内部列表滚动;底部提示/放置区保持可见,不遮挡卡片和关闭按钮。
  • 工具卡片悬停或键盘聚焦时显露小拖动把手和“更多”操作入口;不要用常驻的大段教程挤占工具区域。
  • 拖动快捷入口进入工具箱时,放置区域高亮并显示“松开,从快捷栏移除”;工具箱按钮本身也可作为拖回目标。
  • 工具箱关闭时,拖到工具箱按钮上约 350 毫秒后自动展开;计时离开即取消。只在确实拖动快捷入口时启用。
  • 没有完成放置时,不提前改动排列或保存设置。预览插入位置使用占位符/指示线。

3. 前一轮文字、时间与布局调整(本任务必做)

元素 第一版参数与行为
按钮内短文字 鼠标停留约 100 毫秒后,以约 120 毫秒的向上淡入替换图标;保持按钮尺寸与点击区域不变
完整说明框 从进入按钮开始累计约 600 毫秒后出现;不是短文字结束后再多等 600 毫秒
离开按钮 取消未触发的等待,详细提示立即隐藏;图标在约 100 毫秒内恢复,不保留离场延迟
说明框位置 默认在按钮上方,间隔约 8 像素;左右限制在实际侧栏边界内,并兼顾视口
排版 名称稍突出;正文常规字重、颜色稍淡、自然换行;不把整段解释都加粗
键盘 focus-visible 立即显示短文字和清晰焦点,详细说明遵循约 600 毫秒等待;失焦立即清理
无悬停设备 短文字直接可见;提供点击“更多”的整理方式,不依赖悬停或长按才能使用
减少动态效果 保留识别文字,但取消位移动画,遵守已有 prefers-reduced-motion 规则

这些时间是初始设计值,真实浏览器验证时允许小幅调整,最终只在一处定义,不能散落在多个模块。 从一个按钮快速移到另一个时,重新计时,不闪现上一个按钮的说明。 拖动开始立即隐藏所有按钮提示,拖动期间不显示短文字过渡和说明框;结束后等待新的悬停/聚焦再触发。 提示框不能拦截点击、遮挡拖放目标;不要再使用超宽且正文加粗的提示框。 当前 tooltip 使用伪元素:若要分开标题/正文或准确限制边界,替换这一组按钮的提示渲染为一个共享提示节点,并移除旧提示属性/规则,避免出现两套提示。 不要改动插件所有其他 tooltip。新增可固定工具也必须有短标签、完整名称、说明与中英文翻译。

4. 拖动和普通点击必须分清

  • 鼠标按下不立即拖动,移动超过约 6 CSS 像素才进入拖动态;工具箱优先从把手起拖,卡片正文点击继续打开工具。
  • 快捷栏支持按住按钮拖动。超过阈值后的 pointerup/click 不能打开工具或触发扫描,即使最后取消也不能误点击。
  • 执行原有动作只允许来自明确的普通点击或键盘激活;拖动预览不能调用工具 action。
  • 拖动时保留来源占位、显示小型拖动预览和有效放置提示,不扩大按钮、推动整个侧栏或影响画布缩放。
  • 拖动过程暂缓工具箱的“点击外部关闭”。与现有 document mousedown 关闭监听统一协调,不能边拖边把目标关闭。
  • Esc、pointercancel、失焦、关闭插件、语言切换或重建相关视图均取消拖动并恢复原布局;清理指针捕获、全局监听、计时器和预览。
  • 自动展开的工具箱取消后恢复此前开关状态;原本打开的工具箱保持打开。放置后可保留打开,方便继续整理。
  • 在插件缩放和停靠模式下统一使用视口坐标与 getBoundingClientRect,不能混用缩放前尺寸计算落点。

5. 不会拖动也能完成整理

工具箱的“更多”操作提供“固定到快捷栏/从快捷栏移除”;快捷入口提供“左移/右移/移回工具箱”。 不要仅提供右键菜单,也不要依赖鼠标。使用真实 button、可读名称、可见焦点;操作后把焦点留在合理的位置。 菜单和拖动走同一个布局修改函数,包含相同的容量、去重、固定入口约束;成功放置可用 aria-live 简短播报。

二、工程结构

现有责任与风险

  • web/modules/ui_sidebar.js:目前拥有工具箱卡片、侧栏按钮、扫描状态、打开/关闭和语言刷新;它已经很大,新完整拖动实现不要继续塞入 createDOM。
  • web/modules/sidebar_actions.js:目前只认识六个硬编码 DOM ID;自定义后必须让新增快捷工具也能获取标签和用途。
  • web/modules/ui_lifecycle.js:复用视图资源清理机制;不要新建永久全局拖动监听。
  • web/styles.css:找到现有 sidebar-actions、toolbox、tooltip 规则并修改,移除本次取代的规则;禁止追加覆盖包。
  • web/modules/ui_update_guide.js:保持上方手动入口,不因自定义布局或新引导版本恢复自动弹窗。

建议职责拆分(可按仓库命名习惯调整,不为拆分增加空壳)

  1. 工具定义:一个稳定 ID 对应一份名称键、短标签键、说明键、图标和可固定属性;目录和快捷栏共用。动作回调在侧栏装配时显式传入,纯数据模块不读取画布。
  2. 布局状态:单独的小模块负责默认值、去重/过滤、增删排序、容量与存储;只保存可移动 ID 的顺序,固定两端由视图添加。
  3. 整理视图:独立模块负责拖动、放置预览、菜单与取消清理。只在有效放置/菜单确认时调用布局修改接口。
  4. 现有 sidebar_actions 模块负责短标签和说明提示,可改为接收工具定义;禁止同时保留两套工具元信息和两套点击动作。

不要直接搬移或克隆工具 DOM 来实现固定:这会带走旧关闭逻辑、造成重复 ID 或丢失状态。 每个工具在两处调用同一个动作。保留现有隐藏其他面板、初始化、扫描中状态和错误反馈;不要通过隐藏按钮的 .click() 间接调用。 特别核对 setScanButtonState、anomalous-scan-btn 及语言刷新的所有调用方:扫描运行中移动入口,不能丢失进度、重复启动、产生失效引用。 DOM ID 保证唯一;两个可见入口用稳定 toolId 关联。当前未固定的工具也不能因为入口不在底栏而失去业务状态。

持久化与兼容

  • 使用一个带 schemaVersion 的独立 localStorage 键,例如 anomalous_shortcut_layout_v1,内容仅为 { schemaVersion: 1, pinned: [...] }。
  • 首次使用采用原来的四个中间入口;显式的空数组是合法选择,不得又补回默认值。
  • 读取时拒绝错误结构/未知版本;去掉未知工具 ID、重复项和固定锚点,限制容量;删除工具或升级后仍能打开界面。
  • 不保存 DOM、翻译文本、回调代码或文件路径;不修改后端配置、工作流或素材数据。
  • 写入失败保留当前会话布局,准确提示刷新后可能丢失;禁止伪报“已保存”,也不能让插件打不开。
  • 第一版只在当前浏览器配置中持久化,不实现账户同步、多设备同步或布局导入导出。

三、不能改变的产品边界

  • 导入导出快捷入口只打开现有已验证的 AMB0/AMB1 中心,仍是同一个中心;不能恢复配方、素材库、提示词工坊的独立文件导入导出。
  • 保留素材提示词自动同步、来源标注和不可在工坊删除来源卡片的规则。
  • 不修改图片/工作流哈希、模型识别、模型扫描内容、节点写入语义或用户文件。
  • 不新增全局自动教程;功能上线后再更新引导内容配置和双语文案,仍由用户点击感叹号查看。

四、实施顺序与验收

  1. 设计与状态:说明六种交互状态,提取工具定义和布局纯逻辑,验证默认、空数组、去重、容量、损坏数据及存储失败。此阶段保留旧界面可运行。
  2. 无拖动整理:先让目录与快捷栏共用动作,通过菜单完成固定、移除、排序、恢复默认和刷新恢复;核对扫描状态、语言刷新、唯一 DOM ID。验证通过即本地提交。
  3. 拖动与提示:接入同一状态接口,实现阈值、放置、取消和文字/说明时间布局;验证后再提交,不另造第二套状态。
  4. 交付:仅更新改变的架构契约与用户可见更新说明。汇报实际验证、未测环境及本地提交,不推送 GitHub。

自动测试加载真实布局模块与交互模块,只模拟 DOM/存储边界。拖动至少覆盖成功放置、移出目标取消、Esc/父视图关闭清理、拖后不触发点击。 现有相关测试是 node --experimental-vm-modules tests/update_guide.mjs;扫描动作和已验证导入导出入口发生接线变化时追加相应回归,不默认跑全部后端测试。 新增测试确保被 Git 跟踪。语法/模块链接检查不能代替下面的浏览器操作:

  • 工具箱 → 快捷栏、快捷栏 → 工具箱、栏内排序、重复固定、满栏拒绝、取消拖动;默认工具都能打开且只执行一次。
  • 刷新、恢复默认、所有可移动项移除、扫描中移动入口、中英文切换;工具箱与设置始终可达。
  • 快速掠过不闪说明,停留出现分层文案,边缘按钮提示不越出侧栏;拖动无提示遮挡。
  • 普通窗口、窄侧栏、插件缩放、侧边停靠;工具箱尺寸稳定、内部可滚动、拖放坐标准确。
  • 键盘菜单能完成同样操作;点击感叹号才显示更新引导。至少验证常用主题,未测环境如实说明。

按 AGENTS.md 及时保存阶段快照;若额度将尽或任务中断,保存有明确“验证待完成”说明的恢复快照,而不是无提交地把全部工作留到最后。