Use vertical pipeline layout after polish to fix cramped UI.
Stack steps in full-width cards, compact voice grid, and guide user to Step 3 after polish. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -111,7 +111,10 @@ def ui_polish(raw_text: str) -> tuple[str, str]:
|
||||
|
||||
ok, result = polish_text(raw_text)
|
||||
if ok:
|
||||
return result, f"✅ Gemma4 润色完成,共 {len(result)} 字。"
|
||||
return (
|
||||
result,
|
||||
f"✅ Gemma4 润色完成,共 {len(result)} 字。请向下滚动到 Step 3 选择音色并合成。",
|
||||
)
|
||||
return "", f"❌ {result}"
|
||||
|
||||
|
||||
@@ -525,6 +528,63 @@ gradio-app,
|
||||
height: 18px !important;
|
||||
flex-shrink: 0 !important;
|
||||
}
|
||||
@media (min-width: 520px) {
|
||||
.gradio-container .voice-radio fieldset {
|
||||
display: grid !important;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
|
||||
gap: 8px !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.gradio-container .voice-radio label { margin: 0 !important; }
|
||||
}
|
||||
@media (max-width: 519px) {
|
||||
.gradio-container .voice-radio fieldset {
|
||||
max-height: 200px !important;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 分步流水线:纵向卡片,避免三栏挤扁 */
|
||||
.pipeline-flow {
|
||||
width: 100% !important;
|
||||
gap: 4px !important;
|
||||
}
|
||||
.pipeline-step-card {
|
||||
border: 1px solid #374151 !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 16px 18px !important;
|
||||
background: #111827 !important;
|
||||
margin-bottom: 18px !important;
|
||||
width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
}
|
||||
.pipeline-step-card h3 {
|
||||
margin-top: 0 !important;
|
||||
padding-bottom: 8px !important;
|
||||
border-bottom: 1px solid #374151 !important;
|
||||
}
|
||||
.gradio-container .pipeline-step-card button {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
white-space: normal !important;
|
||||
line-height: 1.35 !important;
|
||||
min-height: 44px !important;
|
||||
}
|
||||
.gradio-container .accordion,
|
||||
.gradio-container .gr-accordion {
|
||||
border: 1px solid #374151 !important;
|
||||
border-radius: 10px !important;
|
||||
background: #1a2332 !important;
|
||||
}
|
||||
.gradio-container .accordion > .label-wrap,
|
||||
.gradio-container .gr-accordion .label-wrap {
|
||||
background: #1e293b !important;
|
||||
color: #e5e7eb !important;
|
||||
}
|
||||
.gradio-container .accordion .content,
|
||||
.gradio-container .gr-accordion .content {
|
||||
background: #111827 !important;
|
||||
}
|
||||
|
||||
/* Dropdown 兜底(其他下拉组件深色化) */
|
||||
.gradio-container .gradio-dropdown input,
|
||||
@@ -988,11 +1048,11 @@ def build_app() -> gr.Blocks:
|
||||
[lock_log, speaker_status],
|
||||
)
|
||||
|
||||
# ---- Tab 2: 分步操作 ----
|
||||
# ---- Tab 2: 分步操作(纵向三步,避免三栏挤在一起)----
|
||||
with gr.Tab("🔧 分步流水线"):
|
||||
gr.HTML(MIC_HINT_HTML)
|
||||
with gr.Row(elem_classes=["pipeline-steps"]):
|
||||
with gr.Column(scale=1):
|
||||
with gr.Column(elem_classes=["pipeline-flow"]):
|
||||
with gr.Group(elem_classes=["pipeline-step-card"]):
|
||||
gr.Markdown("### Step 1 · 音频极速识别")
|
||||
rec_audio = gr.Audio(
|
||||
label="交易复盘碎碎念录音",
|
||||
@@ -1002,36 +1062,37 @@ def build_app() -> gr.Blocks:
|
||||
transcribe_btn = gr.Button("⚡ Faster-Whisper 识别", variant="primary")
|
||||
transcribe_log = gr.Textbox(label="识别日志", lines=2, interactive=False)
|
||||
|
||||
with gr.Column(scale=1):
|
||||
with gr.Group(elem_classes=["pipeline-step-card"]):
|
||||
gr.Markdown("### Step 2 · Gemma4 纪律审判")
|
||||
raw_text = gr.Textbox(
|
||||
label="转写原文(可编辑)",
|
||||
lines=10,
|
||||
lines=8,
|
||||
placeholder="识别结果将显示在此,也可手动粘贴...",
|
||||
)
|
||||
polish_btn = gr.Button("⚖️ 远程 Gemma4 严厉润色", variant="primary")
|
||||
polish_log = gr.Textbox(label="润色日志", lines=2, interactive=False)
|
||||
|
||||
with gr.Column(scale=1):
|
||||
with gr.Group(elem_classes=["pipeline-step-card"]):
|
||||
gr.Markdown("### Step 3 · 本地 GPU 配音合成")
|
||||
gr.Markdown(
|
||||
"> 全部在 **本机显卡** 运行,无需微软/讯飞 API。"
|
||||
"可选「我的锁定音色」或预设男/女声;合成前会自动清洗 Markdown。"
|
||||
"<span style='color:#94a3b8;font-size:0.9rem'>"
|
||||
"本机显卡合成,无需 API。润色完成后在此选音色并点合成。</span>"
|
||||
)
|
||||
with gr.Accordion("🎚️ 选择配音音色", open=True):
|
||||
tts_voice = gr.Radio(
|
||||
label="配音音色(本地 ChatTTS)",
|
||||
choices=voice_choice_labels(),
|
||||
value=_default_voice_label(),
|
||||
info="预设音色需先在服务器执行 bash scripts/generate_voice_presets.sh",
|
||||
info="预设音色:bash scripts/generate_voice_presets.sh",
|
||||
elem_classes=["voice-radio"],
|
||||
)
|
||||
polished_text = gr.Textbox(
|
||||
label="润色配音稿(可编辑,支持含 Markdown,合成时自动清洗)",
|
||||
lines=10,
|
||||
label="润色配音稿(可编辑,合成时自动清洗 Markdown)",
|
||||
lines=12,
|
||||
placeholder="润色结果将显示在此...",
|
||||
)
|
||||
synth_btn = gr.Button("🔊 合成配音 WAV", variant="primary")
|
||||
synth_log = gr.Textbox(label="合成日志", lines=2, interactive=False)
|
||||
synth_log = gr.Textbox(label="合成日志", lines=3, interactive=False)
|
||||
output_audio = gr.Audio(label="成品配音", type="filepath")
|
||||
|
||||
transcribe_btn.click(ui_transcribe, rec_audio, [raw_text, transcribe_log])
|
||||
|
||||
Reference in New Issue
Block a user