Skip to content

💄 安装页桌面端主操作移入身份卡,滚出后吸底;本会话允许收进下拉 - #1817

Merged
CodFrm merged 5 commits into
mainfrom
feature/install-action-prominence
Nov 2, 2026
Merged

CodFrm merged 5 commits into
mainfrom
feature/install-action-prominence

Conversation

@CodFrm

@CodFrm CodFrm commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

N/A — 第一项:来自用户反馈,没有对应 issue。

背景

有用户反馈,桌面端安装页的安装按钮在右下角,不够明显,容易被忽略。原因是正文限宽 864px 居中,而吸底操作栏是整屏宽,按钮又被 md:ml-auto 推到窗口最右(InstallLayout.tsx、InstallActions.tsx)。按布局推算,1600 宽时主按钮比内容列右缘多出约 340px,1920 宽时约 500px。另外,外部接入更新请求里的「本会话允许」按钮是灰底蓝字,和旁边的描边、实心按钮混排,观感不协调,放进信息卡后还会挤压标题。

方案对比过四种 mockup:操作栏对齐内容列、放进信息卡右上、信息卡底部操作条、悬浮操作坞。维护者选定了「信息卡右上」,并让「本会话允许」收进下拉菜单。

本次改动

  • 桌面端(≥768px),脚本 / 订阅 / Skill 三种安装页:
    • 按钮组放进首屏信息卡右上角,整组放大一号;启用开关挪到按钮下方(Skill 页没有开关);说明文字移到信息卡底部,文案不变。
    • 按钮完全滚出可视区后,底部才出现一条与内容列同宽的紧凑吸底栏,左侧是图标、名称、版本,右侧是同一组按钮。按钮还在可视区时不渲染这条栏,所以首屏只有一个 install-primary。
    • 失败提示只渲染一份,跟着当前看得见的那组按钮走。
  • 外部接入更新请求:不再有独立的「本会话允许」按钮,改为主按钮下拉菜单的第一项「更新并本会话允许」,行为不变。所有宽度都生效,新文案已补进 10 个语言包;外部接入确认页仍在用旧 key,所以旧 key 保留。
  • 手机端(<768px):布局不变。
  • 长文本换行:信息卡的标题、作者名、描述加了 wrap-anywhere,脚本页和 Skill 页都改了。按钮挪到标题旁边后,没有空格的超长英文标题会直接盖住安装按钮;作者名和描述里的超长链接原来就会溢出、出现横向滚动条,属于同一原因,一起修了。

实现考虑

  • InstallLayout 改为按位置渲染按钮组(actions(placement),位置分 card / footer / sticky),信息卡通过 identity(slots) 接收按钮组、失败提示和说明文字三个插槽。失败提示改由 InstallLayout 根据 failure 自己渲染,这样才能保证只有一份。
  • 用 IntersectionObserver 观察信息卡里的按钮组,观察区域是正文滚动区。回调取同一批记录里的最后一条;切换到手机布局时丢弃旧的可见状态;吸底栏退出动画的 200ms 内设为 inert,期间不可点击。
  • 吸底栏里的按钮组是滚动途中才挂载的副本,不会触发 autoFocus,不抢焦点。
  • tests/mockIntersectionObserver.ts 原本没有任何地方使用,这次改成可以手动推送可见 / 不可见事件的版本。

已知限制

  • 吸底栏消失时有 200ms 退出动画,这段时间它还在 DOM 里(处于 inert 状态),信息卡里的失败提示可能同时存在。这是在「消失要有过渡」和「回到可视区时不在页面上」两条要求之间取了前者,首屏不受影响。
  • 全量 vitest 在 main 上本来就不稳定,见「验证」。

建议审查重点

  • InstallLayout.tsx:可见状态的切换,包括跨断点切换和退出动画期间的处理。
  • App.tsx / SkillInstallView.tsx 迁移到新接口后,各场景下按钮组合是否和原来一致:普通、更新、回收站、监听文件、外部接入。

验证

本 PR 基于 main e88d0eb6,头为 8c335cdc。

  • 改动涉及的 5 个测试文件:npx vitest run … 86/86 通过;tsc --noEmit、eslint、pnpm run check:i18n 均通过。
  • 全量 npx vitest run:exit 1。失败文件数每次都不一样:main 上观察到 140 和 271 个,本分支上为 79 到 217 个。本分支改动的文件都不在失败列表里,失败文件单独跑都能通过。疑似原因是 ui / fast 项目关闭了文件间隔离(isolate:false),而有些测试文件会调用 vi.unstubAllGlobals,连带撤掉了全局初始化注入的 chrome 等对象。未在本 PR 处理。
  • 运行时验证在构建产物上做(pnpm run build + e2e/session.mjs 无头会话),对照 spec 的 13 条要求全部成立:
    • 在 800 / 1600 / 1920 宽和手机 390 宽、亮暗两套主题下检查了首屏、滚出后、滚回后三个状态。吸底栏内层宽度与内容列完全一致(1600 宽为 [368,1232])。
    • 外部接入用本机 sctl 起了一个隔离的守护进程发真实的 edit 请求:点「更新并本会话允许」后脚本更新成功,下一次编辑无需确认、自动通过。中止 sctl 客户端(操作作废)后再点更新,得到真实的失败:提示条只有一份并跟随按钮组,没有重试按钮。
    • 动画:进出各 200ms,ease-out;减少动态效果下不播放进入动画。
    • 运行时验证基于变基前的 1eb2992f;变基后与它相比只多了上游的 package.json / pnpm-lock.yaml,src 和 tests 完全一致。
  • 长文本(8c335cdc):纯排版问题,happy-dom 不做布局,按测试文档的例外规则,在构建产物上对照修复前后。样例包括中文长标题、无空格英文长标题、带空格英文长标题、超长作者名、描述里的超长链接、Skill 长名称和长描述,各测 1600 和 800 宽。修复前,无空格英文标题与操作组重叠,作者名溢出所在列,描述和 Skill 页出现横向滚动;修复后所有样例都没有重叠、卡片没有溢出、页面没有横向滚动,吸底栏里的名字仍然截断。相关测试文件 53/53 通过,tsc 和 eslint 通过。

Screenshots / 截图

桌面 1600×900 首屏:按钮组在信息卡右上,说明文字在卡片底部,没有吸底栏

desktop-first-screen

桌面滚出后(暗色,1600×600):与内容列同宽的紧凑吸底栏

desktop-sticky-after-scroll-dark

外部接入更新请求(真实 sctl 触发):「更新并本会话允许」在主按钮下拉首项

external-access-update-menu

手机端 390 宽:布局不变

mobile-unchanged

@CodFrm
CodFrm merged commit 79f2a99 into main Nov 2, 2026
11 checks passed
@CodFrm
CodFrm deleted the feature/install-action-prominence branch November 2, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant