强度区也抬成共享样式面:首页带同一份思维强度,滑块点色变浅、点与轨道同高
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m7s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m46s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m27s
Project CI / Frontend tests (pull_request) Successful in 3m27s
Project CI / Backend tests (pull_request) Successful in 8m4s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m5s
Project CI / Repository checks (pull_request) Successful in 6m48s
Project CI / Native shell tests (pull_request) Successful in 9m12s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m7s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 4m46s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m27s
Project CI / Frontend tests (pull_request) Successful in 3m27s
Project CI / Backend tests (pull_request) Successful in 8m4s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m5s
Project CI / Repository checks (pull_request) Successful in 6m48s
Project CI / Native shell tests (pull_request) Successful in 9m12s
- 用户口径:①「把思维强度也加进去,保持所有地方的样式一致,不需要做区分」;②「点的颜色做浅一点,进度条的高度和滑块高度一致」 - ① 首页:`view/home/index.tsx` 给那颗 `ConversationModelSelect` 传**同一个** `ComposerReasoningEffortSelect`(`presentation=section`),读写仍是组件自己的 `read_game_creator_app_config` / `select_game_creator_reasoning_effort`,首页不新写 state;强度区(`.project-chat-reasoning-effort.is-section` / `.project-chat-composer-strength-*`)与外壳锚点(`position: absolute; right: 0; bottom: calc(100% + 8px)`)一并抬到共享样式面,宿主作用域只剩工具栏几何 - ① 实测(无头 Chromium,同一夹具同一裁剪框):首页 1200/447 两档都是外壳 260×262.5、强度区 234×60.5、列表 234×170、滑块 222×26,与工作台逐项一致;工作台回归后外壳/强度区/列表/滑块逐值不变(抬升过程中必须删掉两条给旧独立「推理档」控件排版的死重规则,否则它们以更高特异性盖掉共享面的 `display: grid`,把强度区算宽 24px) - ② 点色:`--platform-text-strong` → `color-mix(in srgb, var(--platform-text-strong) 60%, var(--platform-subpanel-border))`;实测点 rgb(126,100,85) / 相邻轨道 rgb(230,213,198) ⇒ 对比度 3.83:1(上一版 10.5:1,仍守住 ≥3:1)。边界:点落在橙色已选段上时只有 1.54:1——「变浅」与「已选段也 ≥3:1」不可兼得,按「不抢戏」优先,取值可由这条 color-mix 的百分比统一调 - ② 变体 A(落地,默认):填充段=轨道高度 6px(本来就是轨道渐变的一段),档位点也收到 6px(不再上下各露 0.5px);实测轨道 6.0 / 填充 6.0 / 点 6.0 / 圆钮 20(range 盒 26)。变体 B(只出图、未提交):填充段与点都做成 20px=圆钮高度;实测 20/20/20/20(range 盒 34)。447 下圆钮中心到最近可见点中心 37.5px(A) / 30.5px(B),不重叠、不溢出 - 测试:`home.suite.ts` 的首页用例补断言(首页菜单里确实有 `input[type=range]`,`aria-label=思维强度`、`aria-valuetext=默认`);`chatDialogFrameLayout.test.ts` 的强度区选择器改到共享面、并断言点 6px == 轨道高度、点色来自 color-mix、无描边 - 校验:相关 vitest 221 passed / 9 skipped、typecheck、eslint、prettier、encoding 5268 files、spacetime-schema 91 tables、diff-check;对照图与变体图见 PR #607 Refs #600, PR #607
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@ import type { ProjectStartMode } from '../../app/types';
|
||||
import { resolveHomeCreationFailureMessage } from '../../features/app-shell/homeCreationFailure';
|
||||
import { ConversationModelSelect } from '../../features/project-workspace/ConversationModelSelect';
|
||||
import type { GameTemplateEntry } from '../../features/template-library/templateLibraryModel';
|
||||
import { ComposerReasoningEffortSelect } from '../project-development/chat/components/DirectProjectComposer/ComposerControls';
|
||||
import RichInputArea, { UploadButton } from './components/RichInputArea';
|
||||
import {
|
||||
richTextToAttachments,
|
||||
@@ -297,6 +298,14 @@ export default function HomeView({
|
||||
<ConversationModelSelect
|
||||
className="home-input-model-select"
|
||||
disabled={homeCreationBusy || creationBusy}
|
||||
/* 与工作台同一形态:思维强度区在模型菜单顶部(同一个组件、同一份配置通道)。
|
||||
首页没有浮层宿主,所以状态文案沿用控件内的 `inline`(Direct 那边是 toast)。 */
|
||||
strengthSection={
|
||||
<ComposerReasoningEffortSelect
|
||||
disabled={homeCreationBusy || creationBusy}
|
||||
presentation="section"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<button
|
||||
className="grid size-7 cursor-pointer place-items-center rounded-full border-0 bg-(image:--platform-button-primary-fill) p-0 text-(--platform-button-primary-text) shadow-(--platform-profile-action-shadow) transition-transform hover:scale-105 disabled:cursor-not-allowed disabled:opacity-55"
|
||||
|
||||
@@ -212,6 +212,19 @@ export function registerClientHomeTests() {
|
||||
expect(menu.classList.contains('conversation-model-menu')).toBe(true);
|
||||
expect(menu.closest('.conversation-model-select')).not.toBeNull();
|
||||
expect(menu.closest('.game-workbench-chat')).toBeNull();
|
||||
// 首页这颗也有「思维强度」区(同一个组件、同一份配置通道),且菜单里有原生滑块。
|
||||
const group = document.querySelector(
|
||||
'.home-input-model-select [role="group"]',
|
||||
);
|
||||
expect(group?.getAttribute('aria-label')).toBe('思维强度');
|
||||
const slider = document.querySelector<HTMLInputElement>(
|
||||
'.home-input-model-select input[type="range"]',
|
||||
);
|
||||
expect(slider).not.toBeNull();
|
||||
expect(slider?.getAttribute('aria-label')).toBe('思维强度');
|
||||
await waitFor(() =>
|
||||
expect(slider?.getAttribute('aria-valuetext')).toBe('默认'),
|
||||
);
|
||||
|
||||
const rules = parseStyleSheet(
|
||||
readFileSync(
|
||||
|
||||
@@ -164,10 +164,12 @@ const SHARED_CARD = '.conversation-model-select .conversation-model-menu';
|
||||
const SHARED_SHELL =
|
||||
'.conversation-model-select .conversation-model-menu-shell';
|
||||
const SHARED_CARD_IN_SHELL = `${SHARED_SHELL} .conversation-model-menu`;
|
||||
/** 强度滑块与它那排装饰档位点(issue #600 的复核点:点被轨道压住、横向与圆钮错位)。 */
|
||||
const STRENGTH_RANGE = `${COMPOSER} .project-chat-composer-strength-range`;
|
||||
/** 强度区与它那排装饰档位点(issue #600 的复核点:点被轨道压住、横向与圆钮错位)。
|
||||
这些规则与卡片一样已经抬到共享样式面(组件自带类名,不带宿主祖先链)。 */
|
||||
const STRENGTH_SECTION = '.project-chat-reasoning-effort.is-section';
|
||||
const STRENGTH_RANGE = '.project-chat-composer-strength-range';
|
||||
const STRENGTH_THUMB = `${STRENGTH_RANGE}::-webkit-slider-thumb`;
|
||||
const STRENGTH_STOPS = `${COMPOSER} .project-chat-composer-strength-stops`;
|
||||
const STRENGTH_STOPS = '.project-chat-composer-strength-stops';
|
||||
const STRENGTH_STOPS_DOT = `${STRENGTH_STOPS} span`;
|
||||
const STRENGTH_STOPS_DOT_ACTIVE = `${STRENGTH_STOPS} span.is-active`;
|
||||
const TOPBAR = `${CHAT} .project-chat-topbar`;
|
||||
@@ -361,12 +363,8 @@ describe('陶泥儿对话区:Codex 三段式(顶栏 / 唯一滚动区 / 文
|
||||
SHARED_CARD,
|
||||
SHARED_CARD_IN_SHELL,
|
||||
);
|
||||
const section = desktopDeclarations(
|
||||
`${COMPOSER} .project-chat-reasoning-effort.is-section`,
|
||||
);
|
||||
const range = desktopDeclarations(
|
||||
`${COMPOSER} .project-chat-composer-strength-range`,
|
||||
);
|
||||
const section = desktopDeclarations(STRENGTH_SECTION);
|
||||
const range = desktopDeclarations(STRENGTH_RANGE);
|
||||
/**
|
||||
* 共享样式面为了压过基础规则里那几条 `!important`,自己也是按 `!important` 声明的;
|
||||
* 断言时只看最终值,去掉后缀。
|
||||
@@ -425,13 +423,14 @@ describe('陶泥儿对话区:Codex 三段式(顶栏 / 唯一滚动区 / 文
|
||||
|
||||
// 当前档位那一点不画:圆钮已经压在那儿,再画出来就是"靶心"。
|
||||
expect(pixelValue(activeDot, 'opacity')).toBe(0);
|
||||
// 点的填充与描边都来自暖色 token(对比度数值在真机夹具里量,见 PR 正文)。
|
||||
// 点:直径 == 轨道高度(6px,不再上下各露 0.5px),浅暖色从既有 token 派生(对比度实测见 PR)。
|
||||
expect(pixelValue(dot, 'width')).toBe(6);
|
||||
expect(pixelValue(dot, 'height')).toBe(pixelValue(stops, 'height'));
|
||||
expect(declaration(dot, 'background')).toContain('color-mix');
|
||||
expect(declaration(dot, 'background')).toContain(
|
||||
'var(--platform-text-strong)',
|
||||
);
|
||||
expect(declaration(dot, 'border')).toContain(
|
||||
'var(--platform-input-highlight)',
|
||||
'var(--platform-subpanel-border)',
|
||||
);
|
||||
expect(dot.has('border')).toBe(false);
|
||||
});
|
||||
|
||||
it('窄屏(390px)输入盒仍在文档流、四周有边距,列表底部没有留白', () => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 2026-10-05 PR #607 复核修复:档位点对齐/对比度、状态文案也走浮层、键盘去重、卸载 flush
|
||||
|
||||
- **档位点被轨道压住且与圆钮错位(D1)**:旧实现把 5 个点放进 `grid-auto-columns: 1fr`,点中心落在 22.19 / 66.59 / 110.98 / 155.39 / 199.80,而圆钮中心只在 `10 + ratio * (W - 20)`(10 / 60.5 / 111 / 161.5 / 212)——两端各差 **±12.2px**;且点画在 range(`z-index: 1`)**下面**,实测点中心像素被 6px 轨道盖成轨道色,点填充与相邻轨道对比度只有 **1.21:1**。现行口径:容器 `display: flex; justify-content: space-between; padding: 0 6.5px`(6.5 = 圆钮半径 10 − 半点宽 3.5),首末点的**中心**因此正好落在圆钮两端极限位置;容器 `z-index: 2`(高于 range)把点画到轨道之上;**当前档位那一点 `opacity: 0`**(圆钮已经压在那儿,再画就是"靶心");点 7px、`background: var(--platform-text-strong)`、`border: 1.5px solid var(--platform-input-highlight)`。实测(无头 Chromium / 222px 轨道):5 个点中心与圆钮算式偏移 **全部 0.00px**(旧实现 +12.19/+6.09/−0.02/−6.11/−12.20),点中心像素 `rgb(61,31,16)`、与相邻轨道对比度 **10.51~10.59:1**(旧 1.21~1.23:1);当前档位那一点被圆钮覆盖(点中心像素 = 圆钮填充色,圆钮中心与点中心差 ≤0.5px)。
|
||||
- **档位点被轨道压住且与圆钮错位(D1)**:旧实现把 5 个点放进 `grid-auto-columns: 1fr`,点中心落在 22.19 / 66.59 / 110.98 / 155.39 / 199.80,而圆钮中心只在 `10 + ratio * (W - 20)`(10 / 60.5 / 111 / 161.5 / 212)——两端各差 **±12.2px**;且点画在 range(`z-index: 1`)**下面**,实测点中心像素被 6px 轨道盖成轨道色,点填充与相邻轨道对比度只有 **1.21:1**。现行口径:容器 `display: flex; justify-content: space-between; padding: 0 7px`(7 = 圆钮半径 10 − 半点宽 3),首末点的**中心**因此正好落在圆钮两端极限位置;容器 `z-index: 2`(高于 range)把点画到轨道之上;**当前档位那一点 `opacity: 0`**(圆钮已经压在那儿,再画就是"靶心");点 6px(= 轨道高度)、`background: color-mix(in srgb, var(--platform-text-strong) 60%, var(--platform-subpanel-border))`。实测(无头 Chromium / 222px 轨道):5 个点中心与圆钮算式偏移 **全部 0.00px**(旧实现 +12.19/+6.09/−0.02/−6.11/−12.20),点中心像素 `rgb(126,100,85)`、与相邻轨道对比度 **3.83:1**(旧 1.21~1.23:1;再上一版深棕点是 10.5:1,用户口径"做浅一点"后取这个值,仍 ≥3:1);当前档位那一点被圆钮覆盖(点中心像素 = 圆钮填充色,圆钮中心与点中心差 ≤0.5px)。**边界**:点落在**橙色已选段**(`--platform-accent`)上时对比度只有 1.54:1——"变浅"和"已选段上也 ≥3:1"不可兼得(两边都要 ≥3:1 只能是接近黑棕),本项目按"不抢戏"优先,取值由这条 `color-mix` 的百分比统一调。
|
||||
- **状态文案(`role="status"`)也会顶高那一排(D2)**:`notice`(「模型列表已刷新」「正在刷新模型列表」「默认模型已停用」、推理档读取/保存失败)原先无条件渲染成控件里的 `role="status"`,`toast` 形态只接管了 `error`,于是 Direct 输入区仍会被一行状态文字顶成两行高。现行口径:`toast` 形态下失败与状态**分两条通道**(`onUnavailable` / `onNotice`,各自去重、清空后可再报),状态用 `tone="neutral"`、失败用 `tone="error"`;`errorPresentation === 'toast'` 时两种常驻行都不渲染。判据:`chat-composer.suite.ts`「routes model-list notices to the toast…」断言 Direct 输入区子树里 `[role='status']` 与 `[role='alert']` **都为 0**,且浮层在输入区之外。
|
||||
- **键盘长按每个事件都落盘(D5)**:range 的方向键在 Chromium 里每次重复都会补 `change`,旧行为 ~30 次/秒全量写盘(写链 + 持久化 + 回读)。现行口径:`selectEffort` 先比对「最近一次**落盘成功**的档位」(`persistedEffortRef`,挂载回读时就种上),相同则不写;连续调整只写**每个新档位**一次,钳位后的重复事件 0 次。实测(真实按键序列):单击方向键 **1** 次落盘;长按 1.5s(34 个重复事件)**4** 次(`low/medium/high/max`,即每个新档位一次);已在最高档继续长按 1.2s(28 个事件)**0** 次。
|
||||
- **拖动中途卸载会丢档位(D6)**:预览值只在 `change`/`keyup`/`pointerup`/`blur` 落盘,拖到一半被 Esc 关掉菜单或宿主卸载时不会提交。现行口径:卸载 cleanup 里 flush 一次(读 ref,不碰已卸载组件的 state)。实测:拖动到「中」未松手时落盘 0 次,`unmount()` 后恰好 **1** 次(`medium`);单次拖动(按下 + 6 步横移 + 松手)全程 **1** 次(`high`),终值 = 松手位置。
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
- **现象**:工作台那颗 `ConversationModelSelect` 已经改成「强度区 + 模型列表」的卡片观感,但首页输入区右下角那颗(`className="home-input-model-select"`,同一个组件)还是**旧卡片**:161px 窄卡、10px 圆角、5px 内边距、32px 行高、旧灰投影。用户口径是"这个样式同步到首页里去,复用起来"。
|
||||
- **成因**:#600 那轮把卡片 / 列表的新观感全挂在 `.game-workbench-chat .project-chat-surface.is-direct-codex .project-chat-composer.is-direct-codex …` 这条**宿主祖先链**上,于是只有工作台那一处命中;同一个组件换个宿主就退回基础规则。
|
||||
- **处理(现行口径)**:卡片 / 列表 / 行 / hover / 选中 pill / 细滚动条这套观感抬到**组件自带的共享样式面**——选择器只用组件类名(`.conversation-model-select .conversation-model-menu-shell`、`.conversation-model-select .conversation-model-menu`、`… .conversation-model-menu button…`),**不带任何宿主祖先链**;宿主专属的东西(工作台输入区的锚点 `position/right/bottom/z-index`、与工具栏的几何关系、强度区布局)继续留在工作台作用域。合并形态(有外壳)与独立形态(首页/策划/画布直接渲染菜单)**同一套值**:卡 16px 圆角 / 12px 内边距 / 1px `--platform-line-soft` 描边 / `--platform-desktop-hover-shadow`;行 34px、圆角 9px、hover `--platform-nav-item-icon-fill`、选中 `--platform-warm-bg` + 600;独立形态的卡片自己就是滚动区(`max-height: 194 = 170 + 上下各 12`,与合并形态同高),外壳形态的列表 `max-height: 170`(5×34,不出现半行)。
|
||||
- **首页不加强度区**:首页那颗没有 effort 的 state / props(`view/home/index.tsx` 只传 `className` 与 `disabled`),加了等于新增一个首页从未暴露过的设置项。
|
||||
- **判据/取证**:`tests/appSurface/home.suite.ts`「首页模型菜单复用同一套共享样式面」——首页实例的 `.conversation-model-menu` 的祖先链里**没有** `.game-workbench-chat`,而只靠 `.conversation-model-select …` 就能解析出 16px 圆角 / 12px 内边距 / 34px 行;`tests/chatDialogFrameLayout.test.ts` 的外壳用例按新选择器集合更新(锚点仍来自工作台链、卡片观感来自共享面)。真机实测(无头 Chromium,同一夹具同一裁剪框):首页那颗 161×309 / 10px / 5px / 32px → **260×194 / 16px / 12px / 34px**(与工作台卡片逐项一致);工作台那颗外壳 260×262.5、内层列表 234×170、行 34/9px **前后逐值不变**。
|
||||
- **处理(现行口径)**:卡片 / 列表 / 行 / hover / 选中 pill / 细滚动条这套观感抬到**组件自带的共享样式面**——选择器只用组件类名(`.conversation-model-select .conversation-model-menu-shell`、`.conversation-model-select .conversation-model-menu`、`… .conversation-model-menu button…`),**不带任何宿主祖先链**;留在宿主作用域的只有工具栏几何(控制排的宽高与收缩、队列 chip、模型触发钮),**弹层锚点也是组件级**(`position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 20`,见下方"后续")。合并形态(有外壳)与独立形态(策划/画布直接渲染菜单)**同一套值**:卡 16px 圆角 / 12px 内边距 / 1px `--platform-line-soft` 描边 / `--platform-desktop-hover-shadow`;行 34px、圆角 9px、hover `--platform-nav-item-icon-fill`、选中 `--platform-warm-bg` + 600;独立形态的卡片自己就是滚动区(`max-height: 194 = 170 + 上下各 12`,与合并形态同高),外壳形态的列表 `max-height: 170`(5×34,不出现半行)。
|
||||
- **首页当时不加强度区**(后来按用户口径改掉,见下方"后续"):那一版首页那颗没有 effort 的 state / props(`view/home/index.tsx` 只传 `className` 与 `disabled`),加了等于新增一个首页从未暴露过的设置项——所以先只同步卡片观感,强度区留给用户确认。
|
||||
- **判据/取证**:`tests/appSurface/home.suite.ts`「首页模型菜单复用同一套共享样式面」——首页实例的 `.conversation-model-menu` 的祖先链里**没有** `.game-workbench-chat`,而只靠 `.conversation-model-select …` 就能解析出 16px 圆角 / 12px 内边距 / 34px 行,且菜单里确实有原生滑块(`input[type="range"]` 带 `aria-label="思维强度"`);`tests/chatDialogFrameLayout.test.ts` 的外壳用例按新选择器集合更新(锚点与卡片观感都来自共享面,工作台作用域只剩工具栏几何)。真机实测(无头 Chromium,同一夹具同一裁剪框):首页那颗 161×309 / 10px / 5px / 32px → **260×194 / 16px / 12px / 34px**(与工作台卡片逐项一致);工作台那颗外壳 260×262.5、内层列表 234×170、行 34/9px **前后逐值不变**。
|
||||
- **边界**:策划面与画布也复用同一个组件 → 它们的菜单观感同样变成这张卡片(有意为之;窄面板下卡片最小宽度 260px,仍受 `calc(100vw - 24px)` 与各自锚点约束)。若某个宿主需要另一套尺寸,在**该宿主作用域**里覆盖,不要再把观感抄第二份。
|
||||
- **后续(同一轮用户追加)**:强度区与外壳锚点也一并抬到共享面——`view/home/index.tsx` 给首页那颗传了**同一个** `ComposerReasoningEffortSelect`(`presentation="section"`,读写仍是组件自己的 `read_game_creator_app_config` / `select_game_creator_reasoning_effort`),首页因此与工作台逐项同形:外壳 260×262.5、强度区 234×60.5、列表 234×170、滑块 222×26(447 与 1200 两档实测一致;工作台回归后逐值不变)。抬升时必须删掉工作台作用域里两条**死重**规则(给旧独立「推理档」控件排版的 `display: inline-flex` 一族),否则它们会以更高特异性盖掉共享面的 `display: grid`,把强度区重新算宽 24px。
|
||||
- **滑块两点(用户口径)**:①档位点从深棕改成派生浅暖色(见本文件 2026-10-05 D1 条);②"进度条高度与滑块高度一致"按**变体 A** 落地——填充段本来就是轨道高度(6px),把档位点也收到 6px(不再上下各露 0.5px);变体 B(填充段与点都做成 20px = 圆钮高度)只在夹具里渲染出图,未提交。
|
||||
|
||||
## 2026-10-04 把非素材任务塞进「生成任务」账本:taskType 维度、v1 兼容与 live 集合
|
||||
|
||||
|
||||
Reference in New Issue
Block a user