feat(frontend): polish login and design tokens

This commit is contained in:
iye
2026-06-16 12:30:45 +08:00
parent 77c037495e
commit b2288a2652
23 changed files with 828 additions and 926 deletions
+22 -22
View File
@@ -1381,7 +1381,7 @@ export function PipelinePage(props: {
<div className="pane-h">
<div className="shot-headline">
<strong>镜头脚本</strong>
<span className="muted-2 mono" id="shots-meta" style={{ fontSize: "11px" }}>
<span className="muted-2 mono" id="shots-meta" style={{ fontSize: "12px" }}>
{shots.length ? `· ${shots.length} 镜 · ${scriptAdopted ? "已采用" : "待采用"}` : "· 空 · 待生成"}
</span>
</div>
@@ -1499,7 +1499,7 @@ export function PipelinePage(props: {
<div className="pane-h">
<div className="ai-avatar">AI</div>
<strong>脚本助手</strong>
<span className="muted-2 mono" style={{ fontSize: "11px" }}>· {scriptModelName}</span>
<span className="muted-2 mono" style={{ fontSize: "12px" }}>· {scriptModelName}</span>
<span className="spacer"></span>
<button className="btn btn-ghost btn-sm" type="button" id="chat-clear-btn" disabled={!chatText && chatAttachments.length === 0 && chatMsgs.length === 0} onClick={clearChat}>清空对话</button>
</div>
@@ -1658,7 +1658,7 @@ export function PipelinePage(props: {
</div>
<div className="body-2">
<div className="hstack">
<strong style={{ fontSize: "13.5px" }}>{assetName(group.adopted_asset) || `${KIND_LABEL[kind]} ${gi + 1}`}</strong>
<strong style={{ fontSize: "14px" }}>{assetName(group.adopted_asset) || `${KIND_LABEL[kind]} ${gi + 1}`}</strong>
<span className="spacer"></span>
{group.adopted_asset
? <span className="pill ok"><span className="dot"></span>已采用</span>
@@ -1744,7 +1744,7 @@ export function PipelinePage(props: {
</span>
<div className="note-copy"><strong>仅支持整张重跑</strong> · 不能局部改某一镜。如需调单镜,先在 <a href="#stage-1" onClick={(event) => { event.preventDefault(); goStage(1); }}>Stage 1 脚本</a> 改镜头描述,再回此处整张重跑。</div>
</div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "6px", letterSpacing: ".04em" }}>// 整张提示词(重跑时生效,可编辑)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "6px", letterSpacing: ".04em" }}>// 整张提示词(重跑时生效,可编辑)</div>
{/* key 跟版本走:切版本重新种子;onInput 实时回写 state → 整张重跑用的就是你编辑后的文本 */}
<div
className="prompt-edit"
@@ -1761,7 +1761,7 @@ export function PipelinePage(props: {
{adoptedStoryboard ? "整张重跑" : "生成故事板"}
</button>
<span className="spacer"></span>
<span className="muted-2 mono" style={{ fontSize: "11px", alignSelf: "center" }}>~¥0.45/场</span>
<span className="muted-2 mono" style={{ fontSize: "12px", alignSelf: "center" }}>~¥0.45/场</span>
</div>
<div className="sb-history">
<div className="sb-history-h">// 历史版本(<span id="sb-history-ct">{storyboards.length}</span>)</div>
@@ -1774,15 +1774,15 @@ export function PipelinePage(props: {
<div className="ts">{(ver.created_at || "").slice(11, 16) || "--:--"}</div>
</div>
);
}) : <span className="muted-2 mono" style={{ fontSize: "11px" }}>// 暂无历史</span>}
}) : <span className="muted-2 mono" style={{ fontSize: "12px" }}>// 暂无历史</span>}
</div>
</div>
<div className="divider" style={{ marginTop: "16px" }}></div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 绑定的资产</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 绑定的资产</div>
<div style={{ display: "flex", gap: "6px", flexWrap: "wrap" }} id="sb-bound-assets">
{groups.filter((g) => g.adopted_asset).length ? groups.filter((g) => g.adopted_asset).map((g) => (
<span className="asset-tag" key={g.id}><span className="dotc"></span>{assetName(g.adopted_asset) || KIND_LABEL[g.kind] || g.kind}({KIND_LABEL[g.kind] || g.kind})</span>
)) : <span className="muted-2 mono" style={{ fontSize: "11px" }}>// 暂无绑定资产</span>}
)) : <span className="muted-2 mono" style={{ fontSize: "12px" }}>// 暂无绑定资产</span>}
</div>
</div>
</div>
@@ -1818,7 +1818,7 @@ export function PipelinePage(props: {
<div className="queue-bar">
<div>
<div style={{ fontSize: "14px", fontWeight: 600 }}>视频生成 · {segDone} / {segments.length} 完成</div>
<div className="muted-2 mono" style={{ fontSize: "11px", marginTop: "3px", letterSpacing: ".02em" }}>// 每场 Seedance 生成 · {statusText}</div>
<div className="muted-2 mono" style={{ fontSize: "12px", marginTop: "3px", letterSpacing: ".02em" }}>// 每场 Seedance 生成 · {statusText}</div>
</div>
<div className="bar-wrap"><span style={{ width: `${pct}%` }}></span></div>
<span className="muted mono" style={{ fontSize: "12px" }}>{pct}%</span>
@@ -2038,7 +2038,7 @@ export function PipelinePage(props: {
<span className="k">烧入字幕</span>
<button className={`btn btn-sm ${edState.subtitleEnabled ? "btn-primary" : "btn-ghost"}`} type="button" onClick={() => commitEdit({ ...edState, subtitleEnabled: !edState.subtitleEnabled })}>{edState.subtitleEnabled ? "已开启" : "已关闭"}</button>
</div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 字幕样式(导出烧入)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 字幕样式(导出烧入)</div>
<div className="style-swatch">
{STYLE_SWATCHES.map((sw) => (
<div className={`swatch-card${edState.subtitleStyle === sw.key ? " selected" : ""}`} key={sw.key} role="button" tabIndex={0} style={{ cursor: "pointer", opacity: edState.subtitleEnabled ? 1 : 0.5 }} onClick={() => commitEdit({ ...edState, subtitleStyle: sw.key, subtitleEnabled: true })}>
@@ -2046,17 +2046,17 @@ export function PipelinePage(props: {
</div>
))}
</div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, margin: "12px 0 6px", letterSpacing: ".04em" }}>// 字幕文本(默认取脚本旁白,可逐段改)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, margin: "12px 0 6px", letterSpacing: ".04em" }}>// 字幕文本(默认取脚本旁白,可逐段改)</div>
<div style={{ display: "flex", flexDirection: "column", gap: "6px", maxHeight: "186px", overflowY: "auto" }}>
{edState.clips.map((c, idx) => (
<div key={c.key} style={{ display: "flex", gap: "6px", alignItems: "flex-start" }}>
<span className="mono" style={{ fontSize: "10px", color: "var(--black-alpha-48)", marginTop: "7px", flex: "0 0 auto" }}>{idx + 1}</span>
<span className="mono" style={{ fontSize: "12px", color: "var(--black-alpha-48)", marginTop: "7px", flex: "0 0 auto" }}>{idx + 1}</span>
<textarea value={c.subtitle} onChange={(e) => setClipSubtitle(idx, e.target.value)} rows={1} disabled={!edState.subtitleEnabled} placeholder={`第 ${idx + 1} 段字幕`} style={{ flex: 1, minWidth: 0, resize: "vertical", fontSize: "12px", lineHeight: 1.4, padding: "4px 6px", border: "1px solid var(--border-faint)", borderRadius: "6px", background: "var(--surface)", color: "var(--accent-black)", fontFamily: "inherit" }} />
</div>
))}
</div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, margin: "14px 0 6px", letterSpacing: ".04em" }}>// 旁白配音(TTS · 导出混在 BGM 之上)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, margin: "14px 0 6px", letterSpacing: ".04em" }}>// 旁白配音(TTS · 导出混在 BGM 之上)</div>
{voInfo ? (
<div className="props-row" style={{ marginBottom: 6 }}>
<span style={{ fontSize: "12px", flex: 1 }}>已生成 {voInfo.items.length} 段 · {VO_VOICES.find((v) => v.key === voInfo.voice_type)?.label || voInfo.voice_type}</span>
@@ -2065,7 +2065,7 @@ export function PipelinePage(props: {
) : (
<div className="muted" style={{ fontSize: "12px", marginBottom: 6 }}>未生成配音 · 将按上方字幕文本逐段合成人声</div>
)}
{voStale && <div style={{ fontSize: "11.5px", color: "#B45309", marginBottom: 6 }}>字幕文本已修改,与现有配音不一致,建议重新生成</div>}
{voStale && <div style={{ fontSize: "12px", color: "#B45309", marginBottom: 6 }}>字幕文本已修改,与现有配音不一致,建议重新生成</div>}
<div className="props-row" style={{ marginBottom: 6 }}>
<span className="k">音色</span>
<select value={voVoicePick || voInfo?.voice_type || VO_VOICES[0].key} onChange={(e) => setVoVoicePick(e.target.value)} style={{ flex: 1, fontSize: "12px", padding: "4px 6px", border: "1px solid var(--border-faint)", borderRadius: "6px", background: "var(--surface)", color: "var(--accent-black)" }}>
@@ -2081,7 +2081,7 @@ export function PipelinePage(props: {
{propsTab === "transition" && (
<>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 片段间转场(导出 xfade 烧入)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 片段间转场(导出 xfade 烧入)</div>
<div style={{ display: "flex", flexDirection: "column", gap: "6px" }}>
{TRANSITIONS.map((tr) => (
<button className={`btn btn-sm ${edState.transition === tr.key ? "btn-primary" : "btn-ghost"}`} key={tr.key} type="button" style={{ justifyContent: "flex-start" }} onClick={() => commitEdit({ ...edState, transition: tr.key })}>{tr.nm}</button>
@@ -2092,7 +2092,7 @@ export function PipelinePage(props: {
{propsTab === "bgm" && (
<>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 背景音乐(导出混音)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 背景音乐(导出混音)</div>
<div className="props-row"><span style={{ fontSize: "12px", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{serverBgm ? serverBgmName : "未设置 BGM"}</span></div>
{serverBgmUrl && <audio src={serverBgmUrl} controls style={{ width: "100%", height: 30, marginBottom: 8 }} />}
<div className="props-row"><span className="k">音量 {edState.bgmVolume}</span>
@@ -2107,12 +2107,12 @@ export function PipelinePage(props: {
)}
<div className="divider"></div>
<div className="muted mono" style={{ fontSize: "11px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 时间轴(<span id="ed-inspect-name">{timeline?.name || "未命名"}</span>)</div>
<div className="muted mono" style={{ fontSize: "12px", fontWeight: 500, marginBottom: "8px", letterSpacing: ".04em" }}>// 时间轴(<span id="ed-inspect-name">{timeline?.name || "未命名"}</span>)</div>
<div className="props-row"><span className="k">总时长</span><input className="input-mini" value={fmtMs(edRulerMs)} readOnly /></div>
<div className="props-row"><span className="k">片段</span><input className="input-mini" value={`${edClips.length} 段`} readOnly /></div>
<div className="props-row"><span className="k">字幕</span><input className="input-mini" value={subVisible ? `${edClips.length} 条` : "关"} readOnly /></div>
<div className="props-row"><span className="k">转场</span><input className="input-mini" value={(TRANSITIONS.find((t) => t.key === edState.transition) || TRANSITIONS[0]).nm} readOnly /></div>
<div className="props-row"><span className="k">分辨率</span><span className="mono" style={{ fontSize: "11.5px" }}>{resolution}</span></div>
<div className="props-row"><span className="k">分辨率</span><span className="mono" style={{ fontSize: "12px" }}>{resolution}</span></div>
</div>
<div className="timeline" id="ed-timeline" style={{ overflowX: edZoom > 100 ? "auto" : "hidden" }}>
@@ -2174,7 +2174,7 @@ export function PipelinePage(props: {
<span className="num">{idx + 1}</span><span className="lbl">{lbl}</span>
</div>
);
}) : <span className="muted-2 mono" style={{ position: "absolute", left: "8px", top: "50%", transform: "translateY(-50%)", fontSize: "11px" }}>// 暂无片段</span>}
}) : <span className="muted-2 mono" style={{ position: "absolute", left: "8px", top: "50%", transform: "translateY(-50%)", fontSize: "12px" }}>// 暂无片段</span>}
</div>
</div>
@@ -2260,7 +2260,7 @@ export function PipelinePage(props: {
<div className="asset-modal">
<div className="asset-modal-h">
<h2>视频详情</h2>
<span className="mono" style={{ fontSize: "11px", color: "var(--black-alpha-48)" }}>// 场 {vdSeg.sort_order + 1} · {vdSeg.target_duration_seconds}s</span>
<span className="mono" style={{ fontSize: "12px", color: "var(--black-alpha-48)" }}>// 场 {vdSeg.sort_order + 1} · {vdSeg.target_duration_seconds}s</span>
<button className="x" type="button" aria-label="关闭" onClick={() => setVdSegId(null)}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M6 6l12 12M6 18L18 6" /></svg>
</button>
@@ -2291,13 +2291,13 @@ export function PipelinePage(props: {
</div>
<div className="ts">{(v.created_at || "").slice(11, 16) || "--:--"}</div>
</div>
)) : <span className="muted-2 mono" style={{ fontSize: "11px" }}>// 暂无版本</span>}
)) : <span className="muted-2 mono" style={{ fontSize: "12px" }}>// 暂无版本</span>}
</div>
</div>
<div className="vd-prompt-field">
<div className="vd-prompt-head">
<span className="label">// 本场提示词(重跑生效,可编辑)</span>
<span className="mono" style={{ fontSize: "10.5px", color: "var(--black-alpha-48)" }}>系统会自动织入本镜旁白与参考图</span>
<span className="mono" style={{ fontSize: "12px", color: "var(--black-alpha-48)" }}>系统会自动织入本镜旁白与参考图</span>
</div>
<div
className="vd-prompt-edit"