From b7440d8c39b550afb913a9ec981aef5f673fc10a Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Tue, 6 Oct 2026 01:25:43 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=AD=E9=9F=B3=E6=8F=90=E7=A4=BA=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E5=B8=B8=E9=A9=BB=20+=20=E6=A8=A1=E5=9E=8B=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E9=92=AE=E8=A1=A5=20title=20+=20=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E6=9D=A1=20DOM=20=E7=BA=A7=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - D-B:`voiceNotice` 只在 mic 的 `onNotice` 里 set、从不清理(会常驻到组件卸载)→ 改成「拿到转写就收掉」(`onTranscript` 里 `setVoiceNotice('')`);提示是上一次动作的回执,选这个时机而不是 6s 定时,避免与 toast 的 6s 语义混在一起 - D-B 用例(改前红):`chat-composer.suite.ts`「语音提示是上一次动作的回执:拿到转写后不再常驻」——录音 + `onerror({error:'network'})` → `project-chat-composer-notice` 出现「语音识别服务…」;再 `emitTranscript('做一个小游戏')` → 该行消失且节点脱离文档(旧实现里它一直在) - D-C:模型触发钮最窄可缩到 64px、名字走省略号但没有 `title`,截断后无从查看 → 触发钮补 `title={triggerLabel}`(与显示名同源),并加属性断言:`title` == 触发钮文本 - 测试加强(评审说偏声明级):`chat-composer.suite.ts` 新增「AI 润色钮在工具条这一行里(DOM 位置级)」——润色钮必须位于 `.project-chat-composer-controls` 内、父链在 `-controls-actions` 挂点里、不在 `.resource-reference-input` 里、空态工具条外没有第二行按钮(用真实挂载的 Direct 输入区断言);同排几何(top 差 ≤1px、两两不相交、七宽度)由无头 Chromium 夹具实测(240/280/296/320/360/438/900 全通过) - 校验:`appSurface + chatDialogFrameLayout` **227 passed / 9 skipped**;typecheck pass 3 / fail 0;eslint、prettier、encoding 5327 files、spacetime-schema 92 tables、diff-check 全绿 Refs #600, PR #607 --- .../ConversationModelSelect.tsx | 7 +- .../DirectProjectComposer.tsx | 7 +- .../tests/appSurface/chat-composer.suite.ts | 73 +++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx index aed89fa26..66dfa522a 100644 --- a/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx +++ b/apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx @@ -98,6 +98,9 @@ export function ConversationModelSelect({ const [busy, setBusy] = useState(!initialCatalog); const [error, setError] = useState(''); const [notice, setNotice] = useState(''); + /** 触发钮上显示的模型名(目录还没读完时用「模型」占位);同时用作触发钮的 `title`。 */ + const triggerLabel = + models.find((model) => model.id === selected)?.displayName ?? '模型'; const [manualRefreshBusy, setManualRefreshBusy] = useState(false); const [open, setOpen] = useState(false); const containerRef = useRef(null); @@ -502,6 +505,8 @@ export function ConversationModelSelect({ type="button" className="conversation-model-trigger" aria-label="对话模型" + /* 触发钮最窄可缩到 64px,模型名靠省略号收住:补 `title` 让被截断的名字仍可查看。 */ + title={triggerLabel} aria-haspopup="listbox" aria-expanded={open} disabled={disabled} @@ -517,7 +522,7 @@ export function ConversationModelSelect({ /> {/* 控件位只显示已选模型名;目录还没读完时用「模型」占位(加载提示留在菜单里)。 */} - {models.find((model) => model.id === selected)?.displayName ?? '模型'} + {triggerLabel}