From 1afeb2cdb5568c5848816e045d7c29c5b523505e Mon Sep 17 00:00:00 2001 From: Yaojia Wang Date: Sun, 12 Jul 2026 19:32:18 +0200 Subject: [PATCH] =?UTF-8?q?feat(ui):=20=E5=BC=BA=E5=8C=96=20AI=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E4=B8=AD=E5=8A=A8=E6=95=88=E2=80=94=E2=80=94=E6=9E=84?= =?UTF-8?q?=E6=80=9D=E5=8D=A0=E4=BD=8D/=E6=B5=81=E5=BC=8F=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E6=9D=A1/=E6=B3=A2=E5=8A=A8=E4=B8=89=E7=82=B9/?= =?UTF-8?q?=E8=BD=AC=E5=9C=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 动效基元:ai-dot 波动(三点竖跳)、ai-stream 不确定进度条、ai-breathe 呼吸微光(均带 reduced-motion 回退) - ThinkingIndicator 升级为明显波动;新增 Spinner / StreamingBar / GenerationSkeleton 原子件;Button 加 loading 态 - 写作台:首 token 前正文区『AI 正在构思本章…』占位(补最大缺口,不再空白像卡死)+ 流式顶部进度条 - 整章重写流式进度条;续写/润色忙碌骨架 + 触发键转圈;生成器/角色/世界观改用 Button loading --- apps/web/app/globals.css | 74 +++++++++++++++++++ apps/web/components/ThinkingIndicator.tsx | 6 +- .../generation/CharacterGenerator.tsx | 4 +- .../components/generation/WorldGenerator.tsx | 5 +- .../components/toolbox/GeneratorRunner.tsx | 15 ++-- apps/web/components/ui/Button.tsx | 8 ++ apps/web/components/ui/GenerationSkeleton.tsx | 49 ++++++++++++ apps/web/components/ui/Spinner.tsx | 18 +++++ apps/web/components/ui/StreamingBar.tsx | 18 +++++ .../workbench/ChapterRewritePanel.tsx | 6 ++ .../components/workbench/ContinuePanel.tsx | 13 ++-- .../workbench/ConversationThread.tsx | 5 +- apps/web/components/workbench/Editor.tsx | 10 ++- apps/web/components/workbench/RefinePanel.tsx | 3 +- .../workbench/ThinkingPlaceholder.tsx | 13 ++++ apps/web/components/workbench/Workbench.tsx | 8 ++ 16 files changed, 227 insertions(+), 28 deletions(-) create mode 100644 apps/web/components/ui/GenerationSkeleton.tsx create mode 100644 apps/web/components/ui/Spinner.tsx create mode 100644 apps/web/components/ui/StreamingBar.tsx create mode 100644 apps/web/components/workbench/ThinkingPlaceholder.tsx diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index 0743278..f577e57 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -164,7 +164,81 @@ body { } } +/* AI 工作中·三点波动(比 animate-pulse 更明显:竖向弹跳 + 亮度,供 ThinkingIndicator 用)。 */ +.ai-dot { + animation: ai-dot 1.2s ease-in-out infinite; +} +@keyframes ai-dot { + 0%, + 80%, + 100% { + transform: translateY(0); + opacity: 0.4; + } + 40% { + transform: translateY(-3px); + opacity: 1; + } +} + +/* AI 流式/处理中·不确定进度条(细条来回扫,明确传达"正在工作")。 */ +.ai-stream-track { + position: relative; + overflow: hidden; + background: var(--color-cinnabar-wash); +} +.ai-stream-track::after { + content: ""; + position: absolute; + inset-block: 0; + left: -40%; + width: 40%; + border-radius: 9999px; + background: var(--color-cinnabar); + animation: ai-stream 1.4s ease-in-out infinite; +} +@keyframes ai-stream { + 0% { + left: -40%; + width: 35%; + } + 50% { + width: 55%; + } + 100% { + left: 100%; + width: 35%; + } +} + +/* AI 构思中·占位微光(正文区首 token 前的呼吸感,比骨架更"活")。 */ +.ai-breathe { + animation: ai-breathe 1.8s ease-in-out infinite; +} +@keyframes ai-breathe { + 0%, + 100% { + opacity: 0.55; + } + 50% { + opacity: 1; + } +} + @media (prefers-reduced-motion: reduce) { + .ai-dot { + animation: none; + opacity: 0.85; + } + .ai-stream-track::after { + animation: none; + left: 0; + width: 100%; + opacity: 0.35; + } + .ai-breathe { + animation: none; + } .typewriter-cursor { animation: none; } diff --git a/apps/web/components/ThinkingIndicator.tsx b/apps/web/components/ThinkingIndicator.tsx index d778d11..0ac916b 100644 --- a/apps/web/components/ThinkingIndicator.tsx +++ b/apps/web/components/ThinkingIndicator.tsx @@ -17,12 +17,12 @@ export function ThinkingIndicator({ role="status" aria-live="polite" > -