Skip to content

feat(web): 统一界面图标层与菜单体系,重做 Computer 入口与权限弹窗 - #1177

Merged
qqqqqf-q merged 15 commits into
mainfrom
codex/ui-live-preview
Sep 11, 2026
Merged

qqqqqf-q merged 15 commits into
mainfrom
codex/ui-live-preview

Conversation

@qqqqqf-q

@qqqqqf-q qqqqqf-q commented Sep 7, 2026

Copy link
Copy Markdown
Member

目的

收敛这轮 UI 联调:界面图标层、菜单/滚动容器、Computer 选择与连接入口统一为共享实现,并修复联调与对抗性审查中发现的问题。配套组件库 PR:felinics/ui#19 指向 2a54118,已推送)。

主要改动

  • 界面图标层:@memohai/icon/ui 新增语义图标入口,统一几何、1.75 默认笔画与光学校准契约(许可证随包),菜单/设置/工具栏入口完成迁移。
  • 菜单与滚动:Select、DropdownMenu、ContextMenu 与模型虚拟列表共用 MenuScrollArea viewport;patches/reka-ui@2.10.1.patch 修复 reka 异步 focus/pointer 事件在 await 后读到 currentTarget = null 的系列问题(子菜单重开、Select 划过聚焦与离开高亮);MenuItem pointerup 维持现状(拖放松开不执行为可接受行为)。
  • Computer 入口:composer 的 Continue-on 按账号状态分流——零电脑显示 Add your computer 并原地打开连接向导(不跳设置页),有电脑显示 Manage access 打开权限 dialog;权限 dialog 只管授权,footer 的 Manage computers 跳设置 → Computers(删除/改名等生命周期操作在那边);dialog 零状态改为幽灵行(Your computer + Add computer 原地向导)。修复权限 dialog 跳转设置页时不关闭、悬浮层滞留目标页的问题。
  • 远程图标缓存:ProviderIcon 的 URL 图标经共享缓存(fetch → data URL、LRU 128 项、单项 512KiB、CORS/解码失败回退原 URL),并消除回退时的备胎图标闪烁与 24→16px 尺寸跳变。
  • 输入框 placeholder 不随流式切换:revert feat(queue): add live steer and follow-up session input queues #1105followUpPlaceholder(queue/steer 功能保留,placeholder 恒为 chat.inputPlaceholder)。
  • 设置页表面收敛:多处手写卡片外壳迁移到 SettingsSection(深色去边框是既定设计方向);Connectors 右侧子菜单。

依赖与落地顺序

  1. 先合 feat: 统一菜单滚动容器、控件视觉规范与深色卡片边界 ui#19,再合本 PR——图标槽尺寸、Button tone、DialogPanel、MenuScrollArea 等新 API 由组件库提供。
  2. 已 rebase 到 main 0bc1e4947(含 feat(agents): authorize before creation and install runtimes automatically #1195/refactor(web): simplify bot details navigation and advanced settings #1209/feat(apps): authorize connectors during installation #1210)并解决冲突:locale 与 import 为机械并集,文案取本分支设计稿;适配两处上游重构——feat(agents): authorize before creation and install runtimes automatically #1195 connectors 页签并入 apps(Manage connectors 深链改指 tab=apps)、refactor(web): simplify bot details navigation and advanced settings #1209 把 Desktop 实时画面改为 Dialog 预览(本分支对该内联区块的 SettingsSection 迁移随之让位,其余迁移保留)。
  3. Reka 补丁在发布/上游修复前需保留;独立 UI 消费方不会自动获得该补丁。

验证

  • 改动文件 ESLint 0 error;check-ui-contract.mjs 通过(3 条既有基线警告)。
  • vitest 11 通过(preload / ui-icon-contract / model-options);Go 全量测试随提交钩子通过。
  • 浏览器走查:顶部菜单、Recents 右键、语言 Select、Connectors 子菜单;Computer 菜单零电脑原地向导、权限 dialog 开关与 Manage computers 出口;权限 dialog 滞留 bug 已复现并验证修复。
  • 未验证:全量 web typecheck 仍失败(含既有控件值类型与 UI #/ 路径解析,待清理);深浅主题全面检查、键盘/无障碍遍历、窄屏与长虚拟列表未系统过。

已识别未修(后续跟进)

  • ui-icon-contract.test.ts 为 4 文件白名单守卫且不进 CI;withUiStroke 会静默吞掉 kebab 写法 :stroke-width;图标缓存无负缓存(CORS 拒绝的 host 每次开菜单会重试一次注定失败的请求);bot 设置页的 Connect 入口未接 connect=1

代码量自审

已核验远端 base 0bc1e4947、head 2179c747c;按三点 diff 共 50 文件,+1193/−475。

分类 新增 删除
生产代码与配置(含组件、样式) 817 449
i18n(三语言) 27 24
测试(契约/缓存) 138 1
契约文档(icons README/AGENTS) 60 0
依赖补丁 + lockfile 136 6
UI gitlink 1 1

注意 diff 行数的两个放大因素:SettingsSection 表面迁移的整块重新缩进(仅 detail.vue、mcp-server-detail、channel-settings-panel 三个文件就贡献约 ±440 行纯缩进 churn),以及图标/类的机械替换;真实新逻辑(Computer 入口、Connectors 子菜单、图标缓存、图标层本体)约 320 行。

图标层本体约 50 行,大头是菜单/滚动容器接入、Computer 入口重做与设置页表面迁移;Reka 补丁含 dist 双格式与 src 三处同步。本 PR 的行为变化(菜单方向、深色去边框、菜单高度封顶与滚动、图标笔画统一)均为已确认的设计方向。

@qqqqqf-q qqqqqf-q changed the title UI 检查点:统一图标层并保存菜单与电脑入口联调 feat(web): 统一界面图标层与菜单体系,重做 Computer 入口与权限弹窗 Sep 11, 2026
@qqqqqf-q
qqqqqf-q force-pushed the codex/ui-live-preview branch from 9d4839a to 8782f8c Compare September 11, 2026 13:36
@qqqqqf-q
qqqqqf-q marked this pull request as ready for review September 11, 2026 13:55
@qqqqqf-q
qqqqqf-q requested review from a team as code owners September 11, 2026 13:55
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-11T14:57:34.308143Z 77a3a42 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8782f8cfbc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<UploadIcon />
<span class="min-w-0 flex-1 truncate">{{ $t('chat.attachFiles') }}</span>
</DropdownMenuItem>
<ComposerConnectorsMenu

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 按服务能力隐藏 Connectors 子菜单

在未配置 Connect-It 的部署中(/ping.connectors=false),这里仍会无条件渲染 Connectors 子菜单;用户打开它后,composer-connectors-menu.vue 会请求返回 connector_not_configured 的 catalog 和 bot connectors 接口,最终只显示“加载失败”。同一聊天页面的 provideConnectorLogos 已按 capabilities.connectors 门控这些请求,此入口也应复用该能力标志,避免默认自托管部署出现不可用菜单。

AGENTS.md reference: apps/web/AGENTS.md:L481-L487

Useful? React with 👍 / 👎.

Comment on lines +24 to +27
<span
v-else-if="isUrl"
class="inline-block"
v-bind="$attrs"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 为预加载占位符保留 size 尺寸

当 URL 图标调用方仅通过组件的 size 属性指定尺寸(例如 provider/voice 页面使用的 size="1.5em")时,这个空 span 没有应用 widthheight,加载期间实际为 0×0;fetch/decode 完成并换成带尺寸的 img 后仍会发生布局跳动,正好违背这里消除尺寸跳变的目的。占位符需要根据 size 设置宽高,而不能仅依赖可能不存在的 $attrs.class

Useful? React with 👍 / 👎.

Comment on lines +84 to +86
function onAddComputer(): void {
open.value = false
void startConnect()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 不要在启动连接向导前卸载宿主

当访问弹窗中的电脑列表变为空(例如最后一台电脑在另一标签页被撤销)并点击“添加电脑”时,这里先把 open 设为 false;在 composer 宿主中该组件由 v-if="accessDialogOpen" 挂载,因此会立即连同内部的 ConnectComputerDialog 一起卸载。随后 startConnect() 即使成功创建凭据也无处展示向导,用户看不到任何反馈,待连接凭据只能等服务端过期;应让向导由不会随访问弹窗关闭而卸载的父组件持有,或在切换弹窗时保留当前组件。

Useful? React with 👍 / 👎.

CloudIcon 注明其语义为 Memoh 托管工作区(Cloud Computer),与远程电脑 ComputerIcon 区分;交接文档 UI 远端 head 由过期值 4f199290 更正为实际推送的 2a8a7ba 并加修订说明。
- reka 2.10.1 补丁扩展到 SelectItem 的 pointermove/pointerleave:
  await 后 event.currentTarget 恒为 null,导致 Select 划过不聚焦、
  移出后高亮残留;MenuItem pointerup 维持现状(拖放松开不执行是
  可接受行为)。
- ProviderIcon 的 URL 图标在缓存未命中时不再渲染 fallback slot
  (fallback 不吃 $attrs,会以默认 24px 闪现再跳回 16px),改为
  带调用方尺寸的占位空框,加载完成后直接呈现真图。
- 菜单项按账号状态分流:零电脑显示 Add your computer 原地开连接
  向导(不跳设置页);有电脑显示 Manage access 打开权限 dialog。
  账号查询未落地时该项不渲染,避免错误文案帧。
- 权限 dialog footer 改为 Manage computers,跳转设置 → Computers
  (删除/改名等资产生命周期入口);dialog 只保留授权职责。
- 列表零状态改为幽灵行(Your computer / Not connected + Add
  computer 按钮),原地开向导;旧 CTA 行与跳转退役。
- 修复权限 dialog 跳转设置页时不关闭、悬浮层滞留到目标页的问题
  (CTA 与 footer 按钮行为不一致)。
- Cloud Computer 行去掉副标题,与下方行排版对齐。
- 新增 use-connect-computer composable 共享建凭据→向导流程;
  清理退役 key(emptyComputers/connectCta/nativeAlwaysOn)。
诊断、checkpoint 与 handoff 是协作过程产物,不属于仓库长期内容;
图标层契约保留在 packages/icons/README.md。
预览数据只服务截图验证,不进产品代码;两个消费方的 preview
分支一并删除,菜单与 logo 预热只走真实目录查询。
main 将 bot 详情的 connectors 页签并入 apps(BotApps),原
tab=connectors 深链会在能力探测后弹回 overview;composer 的
Manage connectors 改指 tab=apps。detail.vue 的 Plug 导入随页签
删除一并清理。
- composer-connectors-menu 补上 capabilities.connectors 门控:未配置
  ConnectIt 的部署上子菜单不再渲染(其余消费者均已门控,此前划过
  即触发两个注定失败的请求)。
- ACL 弹窗幽灵行 Add computer 改为向上抛事件,向导由
  composer-continue-on 在自己的组件树上原地打开:此前向导挂在被
  v-if 销毁的弹窗子树内,凭据往返回来时宿主已卸载,按钮到达即死。
- 删除 chat.continueOn.noAccess 死 key(三语言,全仓 0 引用)。
queue/steer 功能保留,仅移除 streaming 时的 'Write the next
message…' 切换;placeholder 恒为 chat.inputPlaceholder(只读会话
仍显示 readonlyHint)。followUpPlaceholder 三语言 key 一并删除。
@qqqqqf-q
qqqqqf-q force-pushed the codex/ui-live-preview branch from 2ee33fd to 77a3a42 Compare September 11, 2026 14:42
@qqqqqf-q

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 77a3a4278d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// "Ready" = the account query has answered (or failed) at least once. On
// error the safe fallback is the management dialog, which carries its own
// retry surface.
const runtimesReady = computed(() => runtimes.value !== undefined || runtimesError.value !== undefined)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 不要把初始 null 当作查询已完成

在冷启动或请求较慢时,Pinia Colada 的 error.value 初始值为 null,因此这里的 runtimesError.value !== undefined 会立即为真,使 runtimesReady 在账号电脑查询尚未返回时就变为 true。零电脑账号会先看到并可点击“管理访问”,随后才切换成“添加你的电脑”,违背上方注释要求的无错误帧行为;应依据查询状态,或仅在 error.value 非空时将失败视为已完成。

Useful? React with 👍 / 👎.

@pinia/colada 的 error ref 类型为 TError|null、初值 null,
runtimesError.value !== undefined 恒真导致冷启动门控失效:零电脑
账号会先显示一帧 Manage access 再翻转。isPending 覆盖首次成功与
首次失败两种终态。(Codex review P2)
@qqqqqf-q
qqqqqf-q merged commit c7aa9e8 into main Sep 11, 2026
9 checks passed
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