From 10e37d29a863a238c13c227000b6737896411dd1 Mon Sep 17 00:00:00 2001 From: maomaochong-ai Date: Sun, 6 Sep 2026 20:29:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(create):=20=E9=A6=96=E9=A1=B5=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=B8=B2=E6=9F=93=E4=B8=8E=E5=8E=86=E5=8F=B2=E6=8A=BD?= =?UTF-8?q?=E5=B1=89=E7=BB=86=E8=8A=82=E6=89=B9=20-=20=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E5=A4=B4=E5=AF=B9=E7=A7=B0/=E6=93=8D=E4=BD=9C=E7=BB=84?= =?UTF-8?q?=E6=82=AC=E5=81=9C/=E8=BE=93=E5=85=A5=E6=9D=A1=E7=B4=A7?= =?UTF-8?q?=E5=87=91/=E6=B0=94=E6=B3=A1=E5=BE=AE=E8=B0=83/=E8=A1=8C?= =?UTF-8?q?=E8=B7=9D,=20=E5=8E=86=E5=8F=B2=E8=A1=8C=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E5=9B=BE=E6=A0=87/=E4=B8=89=E7=82=B9=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=9B=BE=E6=A0=87+=E6=96=87=E5=AD=97/=E5=AF=BC=E5=87=BA=20Mark?= =?UTF-8?q?down/=E6=96=B0=E5=BB=BA=E5=8D=A1=E4=BD=9C=E7=94=A8=E5=9F=9F?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plans/boardui-absorption-plan.mdx | 11 +- docs/plans/home-chat-optimization-plan.mdx | 57 ++++++++ docs/plans/ui-design-system.mdx | 4 +- docs/plans/ui-kit-rollout-plan.mdx | 6 +- .../assets/asset-library-picker-modal.tsx | 3 +- .../ui/product/settings-row/index.ts | 1 + .../ui/product/settings-row/settings-row.tsx | 31 ++++ web/src/pages/settings/index.tsx | 97 ++++++------ web/src/styles/globals.css | 138 +++++++++++++++--- 9 files changed, 265 insertions(+), 83 deletions(-) create mode 100644 web/src/components/ui/product/settings-row/index.ts create mode 100644 web/src/components/ui/product/settings-row/settings-row.tsx diff --git a/docs/plans/boardui-absorption-plan.mdx b/docs/plans/boardui-absorption-plan.mdx index 109da3da2..1549403a1 100644 --- a/docs/plans/boardui-absorption-plan.mdx +++ b/docs/plans/boardui-absorption-plan.mdx @@ -35,7 +35,7 @@ BoardUI 是面向 AI/agent 界面的 React 组件库(62+ 源码组件、400+ | BoardUI 资产 | 内容 | 本项目落点 | |---|---|---| | agent-log 的 reveal/连接线形态(等第二消费点:画布 TaskLog 升级时抽共享组件,参考 WorkingDots 路径) | 形态参考 | Canvas 任务运行面板(TaskLog 升级,进行中) | -| notification-center | 通知中心(含 agent 完成/失败分组) | 全局通知浮层 / 后台 | +| ~~notification-center~~ 🚫**已禁用**(2026-09-06:产品未立项、无真实推送源与聚合需求证据;现有“系统公告中心(运营广播)+ 更新日志 + 任务状态就地呈现”均非用户级任务通知,不构成同类实现;如需再立,先补需求与消费点证据,当前一律禁用) | 通知中心(含 agent 完成/失败分组) | ~~全局通知浮层 / 后台~~ | | styles/typography.css | text-* 排版复合类体系 | 对照 `ui-design-system.mdx` 融入 globals.css(rollout §6.2 缺口) | | utils/cx.ts(tailwind-merge) | 类名合并 | 与项目 `lib/utils.ts` 对齐补 cn() | | AGENTS.md / .cursor/rules | AI 协作纪律(组件规则、命名、无障碍) | 供项目 AGENTS.md 参考沉淀组件纪律 | @@ -60,10 +60,7 @@ BoardUI 最典型消费场景是「数据变化时数字平滑滚动」。已在 1. ✅ **Canvas AI 助手应用层**(已完成 2026-09-06):agent-thinking / composer-loader 形态落地于 `canvas-agent-chat-ui` 工作态与发送态;待浏览器视觉验收。 2. **Typography 复合类**:吸收 boardui 排版节奏到 globals.css 的 `@theme`(font-size/weight/leading 映射),供主界面使用。 -3. **通知中心**:把 agent-log/notification-center 形态用于任务完成/失败推送浮层。 -4. 每步遵循 rollout 计划阶段门:先建组件 → 单页替换样板 → 批量消费审计。 -2. **Typography 复合类**:吸收 boardui 排版节奏到 globals.css 的 `@theme`(font-size/weight/leading 映射),供主界面使用。 -3. **通知中心**:把 agent-log/notification-center 形态用于任务完成/失败推送浮层。 +3. ~~通知中心~~:~~把 agent-log/notification-center 形态用于任务完成/失败推送浮层。~~(🚫 已禁用,见 §2.2) 4. 每步遵循 rollout 计划阶段门:先建组件 → 单页替换样板 → 批量消费审计。 ## 5. 备注 @@ -93,7 +90,7 @@ BoardUI 最典型消费场景是「数据变化时数字平滑滚动」。已在 1. **C1 create 空态灵感建议卡 —— ✅ 已覆盖,无需吸收(审计修正)**:盘点子代理漏报;`CreationEmptySuggest`(index.tsx 1825)已有 hero 大卡(含 rays 光效)+ 3 张可点击网格卡(含“从参考图开始”→开素材库),点击按模式回填输入框并聚焦,能力与视觉均 ≥ boardui pro-prompt-card。结论:不新增,保留现状。 2. **C2 会话导出 —— ✅ 已实施(2026-09-06)**:历史抽屉行更多菜单新增“导出对话”(index.tsx 1160);`buildConversationExportMarkdown`(1864)按 角色/时间/模式标签/思考过程 拼 Markdown,`downloadCreationConversation` 下载 `.md`(标题净化文件名)。不做 Web Share(桌面场景下载更稳)。 -3. **C3 settings 行三列配方**(源:settings-rows `220px_1fr_auto` 标签/控件/提示行):我方各设置 Pane 行式由 AntD Form 拼装、形态不一。吸收为共享行组件渐进替换。价值=一致性,成本=全套 Pane 触碰,**需用户决策是否立项**。 +3. **C3 settings 行式配方 —— ✅ 已立项,试点完成(2026-09-06)**:共享组件 `SettingsRow`(components/ui/product/settings-row,左标签/说明 + 右控件 + 行分隔线,末行无线)已建;「生成偏好」Pane 由纵向 Form 改行式并验收基线 tsc 通过(6fc1d92a)。**待办:其余 Pane 批量推广前需用户浏览器验收试点**。 4. **弱候选(默认不做,留痕)**:会话列表“未读点/标记未读”(需求证据弱,我方已有选中/删除);dashboard 图表卡(recharts 已在仓内、admin 已有 analytics-panel,主界面无看板场景);pro rays 光效引擎(create 空态 hero 卡已用等价 CSS 光效,不再引 WebGL 引擎)。 ### 6.3 语义/结构备注(domain 对齐) @@ -103,4 +100,4 @@ BoardUI 最典型消费场景是「数据变化时数字平滑滚动」。已在 ### 6.4 建议下一步 -C3(settings 行三列配方)立项与否待用户决策——若立项:先抽共享行组件(`components/settings/`),再单 Pane 试点替换,最后批量审计,遵循 §4 门。其余候选均按上文处置。 \ No newline at end of file +C3(settings 行式配方)**已立项并完成试点**——待用户浏览器验收「生成偏好」后,再按 §4 门批量推广到其余 Pane(本地运行/模型/音频节点等键值型行;渠道/设备管理重型表单不强推行式)。其余候选均按上文处置。 \ No newline at end of file diff --git a/docs/plans/home-chat-optimization-plan.mdx b/docs/plans/home-chat-optimization-plan.mdx index 8ac95fe9e..15efa9344 100644 --- a/docs/plans/home-chat-optimization-plan.mdx +++ b/docs/plans/home-chat-optimization-plan.mdx @@ -97,3 +97,60 @@ - 每个 Phase 独立提交(`feat/fix/refactor` 前缀按仓库规范),提交前 `bunx tsc --noEmit`,改动后同步 `docs/content/docs/progress/pending-test.mdx` 验收段落(含本次删除任务通知已记录的条目)。 - 所有改动保持工作树干净;本计划文档随首轮实施一并提交。 - BoardUI 只读参照;若其视觉与本站 token(明暗自适应)冲突,以本站 token 体系为准。 + +## 6. 对话消息渲染逐项对照自查(BoardUI 参照) + +> 本节按「消息渲染」维度(布局/对齐/气泡/富内容/状态/可达性)逐项列出现状与建议,2026-09-06 代码与 CSS 实测核对。 +> 状态图例:✅已对齐|🔧微调(小改)|🛠结构性(中等)|❓待产品决策 + +### 6.1 布局与对齐 + +| 编号 | 现状(已实测) | BoardUI 参照 | 建议 | 状态 | +| --- | --- | --- | --- | --- | +| L1 | 会话列 `min(820px, 100% - 48px)` 居中 | 列表同宽居中 | 维持 | ✅ | +| L2 | 助手消息 `width: min(760px, 100%)`,行距原 `space-10`(40px) | 消息垂直间距约 20px、分组更密 | **已实施**:用户/助手消息行距统一降为 `space-8`(32px),长会话视密度更紧凑 | ✅已实施 | +| L3 | 正文列 `padding-left: space-8(32px)`(含头部 mark 对齐) | 无 mark、正文贴左 | 保留 mark 头设计(本站特色);正文/媒体/错误三线缩进统一到 32px | ✅ | +| L4 | 错误/空态行沿用旧 34px 缩进(未见 home 覆盖) | — | **已实施**:新增 home 覆盖 `max-width:720px; padding:16px 0 0 space-8`;窄屏随正文归零 | ✅已实施 | +| L5 | 媒体结果 `max-width 680`、图片 `min(320px)` flex 换行、视频 `min(680px)` | 结果区宽于正文、右缘对齐 | 对齐原则一致;核对图片 gap 与圆角是否 token 化 | 🔧 | + +### 6.2 用户气泡 + +| 编号 | 现状(已实测) | BoardUI 参照 | 建议 | 状态 | +| --- | --- | --- | --- | --- | +| U1 | 气泡为 `copy-wrap`:半径 `r-lg/r-lg/4/r-lg`,`accent 10%` 混底 | `rounded-2xl`(四角 16px)实底 `background-primary` | 尾巴角 4px 是聊天拟物风,保留可;若想更板正可改 16/16/6/16 | ❓ | +| U2 | 气泡原无阴影(`box-shadow:none`) | `shadow-card` | **已实施**:深浅双主题 1px 柔和投影(暗 rgb(0 0 0/.18)、亮 rgb(15 23 42/.08)) | ✅已实施 | +| U3 | 宽度 `min(560px,86%)` 右对齐,内边距原 `10/14` | `max-w-[75%] px-3 py-[11px]` | **已实施**:横向 14→12px,与 boardui `px-3`≈12px 一致 | ✅已实施 | +| U4 | 元信息(你/时间/复制钮)在气泡**上方** meta 行 | 元信息在消息动作行,时间紧随 | 现布局合理;复制钮为幽灵钮 opacity .66→1 | ✅ | +| U5 | 多段/换行由 markdown 渲染 p;无逐段折叠 | 单正文段落 | 维持 | ✅ | + +### 6.3 助手消息形态 + +| 编号 | 现状 | BoardUI 参照 | 建议 | 状态 | +| --- | --- | --- | --- | --- | +| A1 | 头部:mark 块 + 名称 + 模型 + 时间 + 状态徽标 + 变体操作(右缘) | 无头部行、消息下挂操作 | 头部信息密度高(模型/时间常驻);可评估:空闲时模型/时间降为 hover 显示,仅保留名称+状态 | ❓ | +| A2 | 操作在头部右缘(variant-action 幽灵钮) | 28px `rounded-md` 操作钮,`opacity-0`→`group-hover` 浮现,focus-within 常显 | **已实施**:`@media(hover:hover)` 内 hover/focus-within 浮现;触屏(pointer:coarse)保持常显 | ✅已实施 | +| A3 | 思考/流式中间态:pending 帧 + 思维卡片(自研 reasoning) | 独立 thinking 占位(dots/星星/彗星动效、`font-mono` 计时) | **已实施**:流式中 250ms 节流实时秒数(`font-mono tabular-nums`),结束后展示总时长 | ✅已实施 | +| A4 | 生成卡(GenerationToolCard):头部行 + 可折叠正文 | 工具卡以正文内折叠块呈现 | 核对折叠态图标方向与 aria-expanded | ✅ | + +### 6.4 富内容与媒体 + +| 编号 | 现状 | BoardUI 参照 | 建议 | 状态 | +| --- | --- | --- | --- | --- | +| C1 | 代码块:shiki 双主题 + 流式光标(上轮已落地) | — | 复核行号默认关闭、未知语言降级策略 | ✅ | +| C2 | 待生成媒体帧:呼吸渐变 + 取消钮 | — | 与 loader 语义一致,已达标 | ✅ | +| C3 | 视频容器 `aspect-ratio:16/9` 常驻(base 层),home 仅改宽 680;`object-fit:contain` 等比留边 | — | **已核实**:容器比例稳定无闪跳风险,无需改动 | ✅已核实 | + +### 6.5 可达性与状态 + +| 编号 | 现状 | BoardUI 参照 | 建议 | 状态 | +| --- | --- | --- | --- | --- | +| X1 | hover 浮现类动效须尊重 `prefers-reduced-motion` | 同 | A2 隐藏规则仅作用于 `hover:fine` 设备;时长走 `--motion-state`,reduced-motion 由全局规则降级——待浏览器实测 | 🔧待实测 | +| X2 | 行/钮焦点:`:focus-visible` 描边 | `focus-visible:ring-2` | 已一致 | ✅ | +| X3 | 会话列表已接 `role="log"` 与 aria-live | — | 保持 | ✅ | + +### 6.6 建议执行顺序 + +1. ✅ **P1(微调批,已实施)**:L2 行距 32px、L4 错误行 32px、U2 深浅双主题投影、U3 内边距 12px、A2 hover/focus 浮现(触屏常显)。 +2. ✅ **P2(结构性,已实施)**:A3 流式 mono 计时(250ms 节流);C3 已核实 base `16/9` 常驻无需改动。 +3. ⏳ **P3(待决策,未动)**:U1 圆角风格、A1 头部信息 hover 显隐——等产品定调后实施。 +4. ✅ Phase A 历史抽屉(行 hover 菜单/重命名/相对时间)代码已在册;浏览器实测待预览环境补做。 diff --git a/docs/plans/ui-design-system.mdx b/docs/plans/ui-design-system.mdx index bbeb2601a..2b1dc98f8 100644 --- a/docs/plans/ui-design-system.mdx +++ b/docs/plans/ui-design-system.mdx @@ -13,7 +13,7 @@ | base | `ui/base/` | 原语 + 基础件:`buttons/`、`badges/`、`kbd/`、`segmented-control/` 等 | | product | `ui/product/` | 跨页面模式件:`empty-state/`、`callout/`、`loading-state/`、`section-card/`、`property-row/`、`text-tooltip/` | | fx | `ui/fx/` | 特效件(现 `aceternity/*` 归位至此命名空间,引用随用随迁,不重写) | -| application | `ui/application/` | 产品块(P3 起):agent-chat、notification-center、app-shell 等,对齐 BoardUI application | +| application | `ui/application/` | 产品块(P3 起):agent-chat、app-shell 等,对齐 BoardUI application(~~notification-center~~ 🚫已禁用,不实施) | 替换完成前 AntD 用法与皮肤仍由 `web/src/lib/app-theme.ts` 统一管理;**同一控件职能不允许两套实现并存超过一个替换周期**。 @@ -95,7 +95,7 @@ Button/Input 全量、Dialog/Modal、Drawer、Popconfirm、Tabs、Combobox/Selec ### P3(阶段 E,先立证据) -application 产品块:agent-chat(composer/history/message)、agent-thinking 指示、notification-center、app-shell、data-table——映射影策 AI 工作台场景。 + application 产品块:agent-chat(composer/history/message)、agent-thinking 指示、app-shell、data-table——映射影策 AI 工作台场景(~~notification-center/通知中心~~ 🚫已禁用,不实施)。 ### fx diff --git a/docs/plans/ui-kit-rollout-plan.mdx b/docs/plans/ui-kit-rollout-plan.mdx index 59be0d58a..cffdeda7d 100644 --- a/docs/plans/ui-kit-rollout-plan.mdx +++ b/docs/plans/ui-kit-rollout-plan.mdx @@ -42,7 +42,7 @@ | 图标由调用方传任意尺寸 class | Icon 以**组件引用**传入,尺寸/颜色由宿主组件用 token 决定(`@remixicon/react`) | ✅ §8 图标契约(本项目沿用 lucide-react) | | 动效无统一纪律 | `button-press-motion` 等工具类 + `::before` 渐变悬停交叉淡化 + `prefers-reduced-motion` | ✅ §9 动效纪律(本项目已有 motion v12) | | 组件注释缺溯源 | 每个组件头注释标注 Figma 源节点、尺寸表、明暗差异 | ✅ §10 注释规范(引用 token 组 + 对标对象) | -| 无"agentic 界面"沉淀 | `application/agent-chat`(composer/history/message)、`agent-thinking`、`notification-center`、`app-shell`、`data-table` 等产品块 | ✅ §12 backlog 的 P3 application 层(对齐影策 AI 工作台) | +| 无"agentic 界面"沉淀 | `application/agent-chat`(composer/history/message)、`agent-thinking`、`app-shell`、`data-table` 等产品块(~~notification-center~~ 🚫已禁用,不实施) | ✅ §12 backlog 的 P3 application 层(对齐影策 AI 工作台) | ### 2.3 BoardUI 事实基线(2026-09-05 勘察) @@ -88,7 +88,7 @@ web/src/ base/ # 原语 + 基础件:buttons/ badges/ kbd/ segmented-control/ … product/ # 模式件:empty-state/ callout/ loading-state/ section-card/ property-row/ … fx/ # 特效件(现 aceternity/ 归位命名空间,引用随用随迁) - application/ # 产品块(P3 起):agent-chat/ notification-center/ app-shell/ …(对齐 BoardUI application) + application/ # 产品块(P3 起):agent-chat/ app-shell/ …(对齐 BoardUI application;~~notification-center~~ 🚫已禁用,不实施) ``` 导入约定:一律深路径 `@/components/ui/{base,product,fx,application}//`(或族级 barrel);不建全局 barrel。 @@ -196,7 +196,7 @@ NodeTypeBadge、TextTooltip、LoadingState、SectionCard、PropertyRow、IconGro - 验证:`tsc --noEmit` + `vite build` 通过(跳过与本次无关的 build:bridge 预构建);浏览器目验清单见 `docs/content/docs/progress/pending-test.mdx`(UI 组件同角色迁移节)。git 改动未提交。 ### 阶段 E:application 产品块(P3,按需立项) -对齐 BoardUI `application/`:agent-chat(composer/history/message)、agent-thinking 指示、notification-center、app-shell、data-table 等,映射影策 AI 工作台场景(画布 AI 助手面板、生成/转写日志、通知中心)。每块立项前先有真实页面需求与 ≥2 处重复证据。 + 对齐 BoardUI `application/`:agent-chat(composer/history/message)、agent-thinking 指示、app-shell、data-table 等,映射影策 AI 工作台场景(画布 AI 助手面板、生成/转写日志等;~~notification-center/通知中心~~ 🚫已禁用,不实施)。每块立项前先有真实页面需求与 ≥2 处重复证据。 ## 12. 组件 backlog(汇总) diff --git a/web/src/components/assets/asset-library-picker-modal.tsx b/web/src/components/assets/asset-library-picker-modal.tsx index b3cc3b0d8..13a324baa 100644 --- a/web/src/components/assets/asset-library-picker-modal.tsx +++ b/web/src/components/assets/asset-library-picker-modal.tsx @@ -128,7 +128,7 @@ export function AssetLibraryPickerModal({ }); const remoteItems = useMemo(() => (remoteQuery.data?.assets || []).filter((asset) => asset.kind !== "entity" && asset.kind !== "model").map((asset) => ({ id: asset.id, title: asset.title, category: asset.category || "other", archived: asset.status === "archived", asset, - kindLabel: asset.kind === "image" ? "图片" : asset.kind === "video" ? "视频" : asset.kind === "audio" ? "音频" : "文本", searchText: asset.tags.join(" "), + kindLabel: asset.kind === "image" ? "图片" : asset.kind === "video" ? "视频" : asset.kind === "audio" ? "音频" : "文本", searchText: (asset.tags ?? []).join(" "), ...(items.find((item) => item.id === asset.id) || { disabledReason: "此素材不适用于当前操作" }), })), [remoteQuery.data, items]); const effectivePagination = remoteEnabled ? { current: remotePage, pageSize: remotePageSize, total: remoteQuery.data?.total || 0, onChange: (page: number, pageSize: number) => { setRemotePage(page); setRemotePageSize(pageSize); } } : pagination; @@ -355,6 +355,7 @@ export function AssetLibraryPickerModal({ return ( +
+ {label} + {description ? {description} : null} +
+ {control ?
{control}
: null} + + ); +} diff --git a/web/src/pages/settings/index.tsx b/web/src/pages/settings/index.tsx index 57fcdcacf..d71d37009 100644 --- a/web/src/pages/settings/index.tsx +++ b/web/src/pages/settings/index.tsx @@ -1,5 +1,6 @@ -import { App, Button, Form, Input, InputNumber } from "antd"; +import { App, Button, Input, InputNumber } from "antd"; import { Select } from "@/components/ui/base/select"; +import { SettingsRow } from "@/components/ui/product/settings-row"; import { ArrowLeft, Boxes, Bug, Cloud, MessageSquareText, MonitorUp, RadioTower, SlidersHorizontal, SquareTerminal, Workflow } from "lucide-react"; import { useEffect, useMemo, useState, type ReactNode } from "react"; import { useNavigate, useSearchParams } from "react-router"; @@ -140,13 +141,14 @@ export default function SettingsPage() {
-
-
-
-

画布生成

-

设置新建生成任务时使用的初始值,节点内仍可单独覆盖。

-
- +
+
+

画布生成

+

设置新建生成任务时使用的初始值,节点内仍可单独覆盖。

+
+ updateConfig("canvasImageCount", normalizeImageCount(String(value ?? defaultConfig.canvasImageCount)))} /> - -
-
-
-

音频默认值

-

用于新建音频节点和未单独设置参数的生成任务。

-
-
- - updateConfig("audioFormat", value)} /> - - - updateConfig("audioSpeed", normalizeAudioSpeedValue(String(value ?? defaultConfig.audioSpeed)))} - /> - -
-
-
-
-

音频指令

-

在音频节点没有单独填写时使用。

-
-
- - updateConfig("audioInstructions", event.target.value)} /> - -
-
- + } + controlClassName="w-[200px]" + /> +
+
+
+

音频默认值

+

用于新建音频节点和未单独设置参数的生成任务。

+
+ updateConfig("audioVoice", value)} />} controlClassName="w-[200px]" /> + updateConfig("audioFormat", value)} />} controlClassName="w-[200px]" /> + updateConfig("audioSpeed", normalizeAudioSpeedValue(String(value ?? defaultConfig.audioSpeed)))} + /> + } + controlClassName="w-[200px]" + /> +
+
+
+

音频指令

+

在音频节点没有单独填写时使用。

+
+ updateConfig("audioInstructions", event.target.value)} />} + controlClassName="w-full max-w-[480px]" + /> +
), diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css index 0e4ce5c5e..8107a55e4 100644 --- a/web/src/styles/globals.css +++ b/web/src/styles/globals.css @@ -10260,6 +10260,15 @@ html:not(.dark) .creation-chat-reference:hover:not(:disabled) { background: rgba color: var(--creation-text) !important; } +.creation-chat-control[aria-pressed="true"], +.creation-chat-control[aria-pressed="true"]:hover { + background: rgba(6, 182, 212, .16) !important; + color: #4dd6ea !important; +} +.creation-chat-control[aria-pressed="true"] > svg { color: #4dd6ea !important; } +.creation-chat-control[aria-pressed="true"]:disabled, +.creation-chat-control[aria-pressed="true"]:disabled:hover { background: rgba(6, 182, 212, .1) !important; color: #4dd6ea !important; opacity: .42 !important; } + .creation-chat-control > svg { width: 14px; height: 14px; } .creation-chat-control > svg:last-child { width: 12px; height: 12px; color: var(--creation-faint); } .creation-chat-composer .creation-model-picker.canvas-composer-model-picker { width: min(180px, 30vw) !important; justify-content: flex-start; } @@ -10271,6 +10280,18 @@ html:not(.dark) .creation-chat-control.is-mode, html:not(.dark) .creation-chat-control:hover, html:not(.dark) .creation-chat-composer .creation-model-picker.canvas-composer-model-picker:hover { background: rgba(29, 33, 37, .06) !important; color: var(--creation-text) !important; } +.creation-chat-control:disabled { + opacity: .42 !important; + cursor: not-allowed; + background: transparent !important; + color: var(--creation-muted) !important; + transform: none !important; +} +html:not(.dark) .creation-chat-control:disabled { background: transparent !important; color: var(--creation-muted) !important; } +html:not(.dark) .creation-chat-control[aria-pressed="true"], +html:not(.dark) .creation-chat-control[aria-pressed="true"]:hover { background: rgba(6, 182, 212, .13) !important; color: #0e7490 !important; } +html:not(.dark) .creation-chat-control[aria-pressed="true"] > svg { color: #0e7490 !important; } + .creation-control-popover-surface, .creation-model-picker-surface { overflow: hidden; @@ -12953,12 +12974,26 @@ html:not(.dark) .creation-history-drawer-root { .creation-history-list > li { position: relative; min-width: 0; } .creation-history-row { position: relative; display: flex; min-width: 0; align-items: center; border-radius: var(--r-sm); transition: background-color 150ms ease; } .creation-history-row:hover { background: var(--creation-history-hover); } -.creation-history-row .creation-history-item-main { display: flex; min-width: 0; flex: 1; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3px; border: 0; border-radius: var(--r-sm); background: transparent; padding: 8px 62px 8px 12px; color: var(--creation-history-text); text-align: left; } +.creation-history-row .creation-history-item-main { display: flex; min-width: 0; flex: 1; flex-direction: row; align-items: center; justify-content: flex-start; gap: 12px; border: 0; border-radius: var(--r-sm); background: transparent; padding: 8px 62px 8px 12px; color: var(--creation-history-text); text-align: left; } .creation-history-row .creation-history-item-main:hover { background: transparent; } .creation-history-row .creation-history-item-main:focus-visible { outline: 2px solid color-mix(in srgb, var(--creation-history-accent) 68%, transparent); outline-offset: -2px; } .creation-history-list > li.is-active .creation-history-row { background: color-mix(in srgb, var(--creation-history-accent) 9%, var(--creation-history-surface)); } .creation-history-list > li.is-active .creation-history-row:hover { background: color-mix(in srgb, var(--creation-history-accent) 14%, var(--creation-history-surface)); } .creation-history-item-heading { width: 100%; overflow: hidden; font-size: var(--fs-label); font-weight: 650; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; } +.creation-history-item-text { display: flex; min-width: 0; flex: 1; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3px; } +.creation-history-item-icon { + display: grid; + width: 34px; + height: 34px; + flex: 0 0 auto; + place-items: center; + border-radius: 99px; + background: color-mix(in srgb, var(--creation-history-accent) 16%, transparent); + color: var(--creation-history-accent); + transition: background-color 150ms ease, color 150ms ease; +} +.creation-history-item-icon svg { width: 16px; height: 16px; } +.creation-history-list > li.is-active .creation-history-item-icon { background: color-mix(in srgb, var(--creation-history-accent) 24%, transparent); color: var(--creation-history-accent); } .creation-history-snippet { display: flex; width: 100%; min-width: 0; align-items: baseline; gap: 6px; overflow: hidden; color: color-mix(in srgb, var(--creation-history-muted) 88%, transparent); font-size: var(--fs-micro); line-height: 1.45; } .creation-history-snippet em { flex: 0 0 auto; color: color-mix(in srgb, var(--creation-history-muted) 80%, transparent); font-size: var(--fs-micro); font-style: normal; font-weight: 600; } .creation-history-snippet span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @@ -12980,6 +13015,8 @@ html:not(.dark) .creation-history-drawer-root { .creation-history-empty { display: grid; min-height: 180px; place-items: center; color: var(--creation-history-muted); font-size: var(--fs-label); } .creation-history-menu-overlay .ant-dropdown-menu { border-radius: var(--r-md); padding: 4px; min-width: 168px; } .creation-history-menu-overlay .ant-dropdown-menu .ant-dropdown-menu-item { border-radius: 6px; } +.creation-history-menu-overlay .ant-dropdown-menu-item-icon { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; } +.creation-history-menu-overlay .ant-dropdown-menu-item-icon svg { display: block; width: 14px; height: 14px; } @media (pointer: coarse) { .creation-history-more { opacity: 1; } .creation-history-row:hover .creation-history-time-slot { opacity: 1; } @@ -15562,8 +15599,8 @@ html.dark .ai-message-codeblock-pre .shiki span { color: var(--shiki-dark) !impo max-width: none; flex-direction: column; align-items: flex-end; - gap: var(--space-2); - margin: 0 0 var(--space-10) auto; + gap: var(--space-3); + margin: 0 0 var(--space-8) auto; border-radius: 0; background: transparent; padding: 0; @@ -15580,15 +15617,44 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; color: var(--creation-faint); font-size: var(--fs-label); } +.creation-home .creation-user-avatar { + display: grid; + width: 26px; + height: 26px; + flex: 0 0 26px; + place-items: center; + overflow: hidden; + border: 0; + border-radius: 50%; + background: rgba(255, 255, 255, .08); + color: var(--creation-muted); +} +.creation-home .creation-user-avatar svg { width: 15px; height: 15px; } +.creation-home .creation-user-avatar img { width: 100%; height: 100%; object-fit: cover; } +.creation-home .creation-user-message-meta strong { + color: var(--creation-text); + font-size: var(--fs-body); + font-weight: 620; + white-space: nowrap; +} +html:not(.dark) .creation-home .creation-user-avatar { background: rgba(15, 23, 42, .07); color: var(--creation-faint); } + .creation-home .creation-user-message-meta time, .creation-home .creation-message-heading time { color: var(--creation-faint); font-size: var(--fs-micro); } -.creation-home .creation-user-message-copy { +.creation-home .creation-user-message-actions { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 2px; + margin-top: 6px; + transition: opacity var(--motion-state) ease; +} +.creation-home .creation-user-message-actions button { display: grid; width: var(--space-5); height: var(--space-5); - flex: 0 0 var(--space-5); place-items: center; border: 0; border-radius: var(--r-xs); @@ -15599,23 +15665,27 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; opacity: .66; transition: background-color var(--motion-state) ease, color var(--motion-state) ease, opacity var(--motion-state) ease; } - -.creation-home .creation-user-message-copy:hover { +.creation-home .creation-user-message-actions button svg { width: 15px; height: 15px; } +.creation-home .creation-user-message-actions button:hover { background: var(--creation-surface-hover); color: var(--creation-text); opacity: 1; } - -.creation-home .creation-user-message-copy:focus-visible { outline: 2px solid var(--creation-accent); outline-offset: 1px; } -.creation-home .creation-user-message-copy svg { width: var(--space-3); height: var(--space-3); } +.creation-home .creation-user-message-actions button svg { width: var(--space-3); height: var(--space-3); } +.creation-home .creation-user-message-actions button:focus-visible { outline: 2px solid var(--creation-accent); outline-offset: 1px; } +@media (hover: hover) and (pointer: fine) { + .creation-home .creation-user-message:not(:hover):not(:focus-within) .creation-user-message-actions { opacity: 0; } +} .creation-home .creation-user-message-copy-wrap { width: fit-content; max-width: 100%; border-radius: var(--r-lg) var(--r-lg) 4px var(--r-lg); background: color-mix(in srgb, var(--creation-accent) 10%, var(--creation-surface)); - padding: 10px 14px; + padding: 10px 12px; + box-shadow: 0 1px 2px 0 rgb(0 0 0 / .18); } +html:not(.dark) .creation-home .creation-user-message-copy-wrap { box-shadow: 0 1px 2px 0 rgb(15 23 42 / .08); } .creation-home .creation-user-message-copy-wrap p { margin: 0; @@ -15630,7 +15700,7 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; .creation-home .creation-assistant-message { width: min(760px, 100%); max-width: none; - margin: 0 0 var(--space-10); + margin: 0 0 var(--space-8); background: transparent; } @@ -15661,12 +15731,32 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; .creation-home .creation-message-variant-action:hover { background: var(--creation-surface-hover); color: var(--creation-text); } .creation-home .creation-message-variant-action:focus-visible { outline: 2px solid var(--creation-accent); outline-offset: 1px; } .creation-home .creation-message-variant-action svg { width: var(--space-3); height: var(--space-3); } +@media (hover: hover) and (pointer: fine) { + .creation-home .creation-assistant-message:not(:hover):not(:focus-within) .creation-message-variant-action { opacity: 0; } + .creation-home .creation-message-variant-action { transition: opacity var(--motion-state) ease, background-color var(--motion-state) ease, color var(--motion-state) ease; } +} .creation-home .creation-message-content { max-width: 720px; padding: var(--space-3) 0 0 var(--space-8); } +.creation-home .creation-message-error { + max-width: 720px; + padding: 16px 0 0 var(--space-8); +} +.creation-home .creation-message-reasoning-wrap { + max-width: 720px; + padding: var(--space-3) 0 0 var(--space-8); +} +.creation-home .creation-message-reasoning-wrap > div { margin-bottom: 0; } + + +.creation-home .creation-thread-composer .creation-chat-writing-surface { min-height: 0; } +.creation-home .creation-thread-composer .creation-chat-editor textarea { min-height: 44px; } +.creation-home .creation-thread-composer .creation-reference-panel { margin-bottom: var(--space-1); } +.creation-home .creation-thread-composer .creation-reference-track-wrapper { min-height: 40px; } +.creation-home .creation-thread-composer .creation-reference-track.is-empty { padding-top: 0; padding-bottom: 0; } .creation-home .creation-media-pending { position: relative; display: grid; @@ -15811,6 +15901,8 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; .creation-home .creation-thread-stage { padding-top: var(--space-5); } .creation-home .creation-user-message { width: 92%; max-width: none; } .creation-home .creation-message-content, + .creation-home .creation-message-error, + .creation-home .creation-message-reasoning-wrap, .creation-home .creation-media-result { padding-left: 0; } .creation-home .creation-media-pending { width: min(var(--creation-media-pending-max-width), 100%); margin-left: 0; } .creation-home .creation-media-error { width: 100%; margin-left: 0; } @@ -15978,7 +16070,7 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; /* —— 创建页历史抽屉:新建置顶卡 + 时间分组(吸收 boardui agent-chat-history)—— */ -.creation-home .creation-history-new { +.creation-history-new { display: flex; width: calc(100% - 4px); align-items: center; @@ -15993,9 +16085,9 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; cursor: pointer; transition: background-color 150ms ease, border-color 150ms ease, transform 150ms ease; } -.creation-home .creation-history-new:hover { border-color: color-mix(in srgb, var(--creation-history-accent) 74%, var(--creation-history-line)); background: color-mix(in srgb, var(--creation-history-accent) 10%, transparent); } -.creation-home .creation-history-new:focus-visible { outline: 2px solid color-mix(in srgb, var(--creation-history-accent) 70%, transparent); outline-offset: 1px; } -.creation-home .creation-history-new-icon { +.creation-history-new:hover { border-color: color-mix(in srgb, var(--creation-history-accent) 74%, var(--creation-history-line)); background: color-mix(in srgb, var(--creation-history-accent) 10%, transparent); } +.creation-history-new:focus-visible { outline: 2px solid color-mix(in srgb, var(--creation-history-accent) 70%, transparent); outline-offset: 1px; } +.creation-history-new-icon { display: grid; width: 34px; height: 34px; @@ -16005,12 +16097,12 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; background: color-mix(in srgb, var(--creation-history-accent) 16%, transparent); color: var(--creation-history-accent); } -.creation-home .creation-history-new-icon svg { width: 16px; height: 16px; } -.creation-home .creation-history-new-copy { display: flex; min-width: 0; flex-direction: column; gap: 1px; } -.creation-home .creation-history-new-copy strong { font-size: var(--fs-label); font-weight: 650; } -.creation-home .creation-history-new-copy small { overflow: hidden; color: var(--creation-history-muted); font-size: var(--fs-micro); text-overflow: ellipsis; white-space: nowrap; } -.creation-home .creation-history-group-head { position: sticky; z-index: 1; top: 0; margin-top: 4px; padding: 10px 4px 5px; background: linear-gradient(to bottom, var(--creation-history-bg) 78%, transparent); } -.creation-home .creation-history-group-head h4 { +.creation-history-new-icon svg { width: 16px; height: 16px; } +.creation-history-new-copy { display: flex; min-width: 0; flex-direction: column; gap: 1px; } +.creation-history-new-copy strong { font-size: var(--fs-label); font-weight: 650; } +.creation-history-new-copy small { overflow: hidden; color: var(--creation-history-muted); font-size: var(--fs-micro); text-overflow: ellipsis; white-space: nowrap; } +.creation-history-group-head { position: sticky; z-index: 1; top: 0; margin-top: 4px; padding: 10px 4px 5px; background: linear-gradient(to bottom, var(--creation-history-bg) 78%, transparent); } +.creation-history-group-head h4 { display: flex; align-items: baseline; gap: 6px; @@ -16020,4 +16112,4 @@ html:not(.dark) .creation-home .creation-user-message { background: transparent; font-weight: 640; letter-spacing: .04em; } -.creation-home .creation-history-group-head h4::after { content: ""; flex: 1; height: 1px; background: var(--creation-history-line); transform: translateY(-2px); } +.creation-history-group-head h4::after { content: ""; flex: 1; height: 1px; background: var(--creation-history-line); transform: translateY(-2px); }