From 8dd0db58b8b090dd06377fdae62d06fa5236eb79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=B5=E5=BA=94?= Date: Thu, 2 Jul 2026 18:22:19 +0800 Subject: [PATCH] fix: progress bar indeterminate animation (P2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GeneratePage.tsx: processing 状态进度条改为 indeterminate 条纹流动动画 - MyVoices.tsx: 同上,移除硬编码 progress: 0 百分比显示 - generate.css: 添加 @keyframes xx-clone-progress-flow 条纹流动 + pulse 脉冲 - my-voices.css: 添加 @keyframes xx-mv-progress-flow 条纹流动 + pulse 脉冲 - 文本从 '0%' 改为 '处理中…',给用户处理中的视觉反馈 Fixes: P2 — progress 硬编码为 0,进度条永远显示 0% --- apps/web/src/pages/generate/GeneratePage.tsx | 8 ++--- apps/web/src/pages/generate/generate.css | 29 +++++++++++++++ apps/web/src/pages/my-voices/MyVoices.tsx | 8 ++--- apps/web/src/pages/my-voices/my-voices.css | 38 +++++++++++++++++--- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/apps/web/src/pages/generate/GeneratePage.tsx b/apps/web/src/pages/generate/GeneratePage.tsx index 05acce935..261ede93d 100644 --- a/apps/web/src/pages/generate/GeneratePage.tsx +++ b/apps/web/src/pages/generate/GeneratePage.tsx @@ -846,11 +846,11 @@ const GeneratePage: React.FC = () => { )} - {/* 进度条 */} + {/* 进度条(克隆中 — indeterminate 条纹流动动画) */} {cv.status === "processing" && ( -
-
- {cv.progress}% +
+
+ 处理中…
)}
diff --git a/apps/web/src/pages/generate/generate.css b/apps/web/src/pages/generate/generate.css index 96da0afb1..fe8403567 100644 --- a/apps/web/src/pages/generate/generate.css +++ b/apps/web/src/pages/generate/generate.css @@ -728,6 +728,35 @@ transition: width 0.5s ease; } +/* Indeterminate 态:条纹流动动画(progress=0 时后端无进度数据) */ +.xx-clone-progress--indeterminate .xx-clone-progress-bar { + width: 100%; + background: repeating-linear-gradient( + 90deg, + var(--accent-color, #f59e0b) 0%, + var(--accent-color, #f59e0b) 25%, + var(--secondary-color, #10b981) 25%, + var(--secondary-color, #10b981) 50%, + var(--accent-color, #f59e0b) 50% + ); + background-size: 60px 100%; + animation: xx-clone-progress-flow 1.2s linear infinite; +} + +@keyframes xx-clone-progress-flow { + from { background-position: 0 0; } + to { background-position: 60px 0; } +} + +.xx-clone-progress--indeterminate .xx-clone-progress-text { + animation: xx-clone-progress-pulse 1.5s ease-in-out infinite; +} + +@keyframes xx-clone-progress-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + .xx-clone-progress-text { position: absolute; right: 0; diff --git a/apps/web/src/pages/my-voices/MyVoices.tsx b/apps/web/src/pages/my-voices/MyVoices.tsx index aa544f18c..c74316ec7 100644 --- a/apps/web/src/pages/my-voices/MyVoices.tsx +++ b/apps/web/src/pages/my-voices/MyVoices.tsx @@ -102,11 +102,11 @@ const VoiceCard: React.FC = ({ )}
- {/* 进度条(克隆中) */} + {/* 进度条(克隆中 — indeterminate 条纹流动动画) */} {voice.status === "processing" && ( -
-
- {voice.progress}% +
+
+ 处理中…
)} diff --git a/apps/web/src/pages/my-voices/my-voices.css b/apps/web/src/pages/my-voices/my-voices.css index 1aa43f384..2ea8ffdb2 100644 --- a/apps/web/src/pages/my-voices/my-voices.css +++ b/apps/web/src/pages/my-voices/my-voices.css @@ -238,15 +238,43 @@ .xx-mv-progress-bar { height: 100%; - background: linear-gradient( - 90deg, - var(--accent-color, #f59e0b), - var(--secondary-color, #10b981) - ); border-radius: 3px; transition: width 0.5s ease; } +/* Indeterminate 态:条纹流动动画(后端无 progress 字段) */ +.xx-mv-progress--indeterminate { + background: var(--bg-tertiary, #f1f5f9); +} + +.xx-mv-progress--indeterminate .xx-mv-progress-bar { + width: 100%; + background: repeating-linear-gradient( + 90deg, + var(--accent-color, #f59e0b) 0%, + var(--accent-color, #f59e0b) 25%, + var(--secondary-color, #10b981) 25%, + var(--secondary-color, #10b981) 50%, + var(--accent-color, #f59e0b) 50% + ); + background-size: 60px 100%; + animation: xx-mv-progress-flow 1.2s linear infinite; +} + +@keyframes xx-mv-progress-flow { + from { background-position: 0 0; } + to { background-position: 60px 0; } +} + +.xx-mv-progress--indeterminate .xx-mv-progress-text { + animation: xx-mv-progress-pulse 1.5s ease-in-out infinite; +} + +@keyframes xx-mv-progress-pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + .xx-mv-progress-text { position: absolute; right: 0;