Improve one-click tab layout: even nav, equal cards, collapsible voice

Evenly distribute main tabs, make upload and transcript inputs equal height, and fold voice selection into a collapsed accordion.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-12 18:59:27 +08:00
parent 54523e39af
commit ca49b2feed
+66 -15
View File
@@ -643,17 +643,19 @@ gradio-app,
gap: 6px !important; gap: 6px !important;
} }
.gradio-container .tab-nav button { .gradio-container .tab-nav button {
flex: 1 1 28% !important; flex: 1 1 25% !important;
min-width: 88px !important; min-width: 0 !important;
padding: 8px 8px !important; padding: 8px 6px !important;
font-size: 0.8rem !important; font-size: 0.82rem !important;
} }
.status-row, .status-row,
.status-row > div, .status-row > div,
.pipeline-steps, .pipeline-steps,
.pipeline-steps > div, .pipeline-steps > div,
.pipeline-output-row, .pipeline-output-row,
.pipeline-output-row > div { .pipeline-output-row > div,
.pipeline-input-row,
.pipeline-input-row > div {
flex-direction: column !important; flex-direction: column !important;
width: 100% !important; width: 100% !important;
} }
@@ -1023,6 +1025,51 @@ gradio-app,
font-size: 0.95rem !important; font-size: 0.95rem !important;
padding: 10px 18px !important; padding: 10px 18px !important;
} }
/* 主导航 Tab 均匀分布 */
.gradio-container .main-nav-tabs > .tab-nav,
.gradio-container .tabs.main-nav-tabs > .tab-nav {
display: flex !important;
width: 100% !important;
gap: 0 !important;
}
.gradio-container .main-nav-tabs > .tab-nav button,
.gradio-container .tabs.main-nav-tabs > .tab-nav button {
flex: 1 1 25% !important;
min-width: 0 !important;
text-align: center !important;
justify-content: center !important;
border-radius: 0 !important;
}
/* 一键生成:上传区与转写区等大 */
.pipeline-input-row {
align-items: stretch !important;
gap: 12px !important;
}
.pipeline-input-row > .gr-column,
.pipeline-input-row > div {
flex: 1 1 50% !important;
min-width: 0 !important;
width: 50% !important;
display: flex !important;
flex-direction: column !important;
}
.pipeline-input-row .block,
.pipeline-input-row .form {
flex: 1 1 auto !important;
height: 100% !important;
}
.pipeline-input-row .audio-container,
.pipeline-input-row .upload-container {
flex: 1 1 auto !important;
min-height: 220px !important;
display: flex !important;
flex-direction: column !important;
justify-content: center !important;
}
.pipeline-input-row textarea {
min-height: 220px !important;
height: 100% !important;
}
.gradio-container .tab-nav button.selected { .gradio-container .tab-nav button.selected {
color: #ffffff !important; color: #ffffff !important;
background: #1e3a5f !important; background: #1e3a5f !important;
@@ -1305,34 +1352,38 @@ def build_app() -> gr.Blocks:
with gr.Blocks( with gr.Blocks(
title="Trading Studio | 交易复盘配音中控", title="Trading Studio | 交易复盘配音中控",
) as demo: ) as demo:
with gr.Tabs(): with gr.Tabs(elem_classes=["main-nav-tabs"]):
# ---- Tab 1: 一键生成(默认首页)---- # ---- Tab 1: 一键生成(默认首页)----
with gr.Tab("一键生成"): with gr.Tab("一键生成"):
gr.HTML(MIC_HINT_HTML) gr.HTML(MIC_HINT_HTML)
gr.Markdown( gr.Markdown(
"上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。" "上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。"
) )
with gr.Row(): with gr.Row(equal_height=True, elem_classes=["pipeline-input-row"]):
pipe_audio = gr.Audio( pipe_audio = gr.Audio(
label="复盘录音", label="复盘录音",
type="filepath", type="filepath",
sources=["upload", "microphone"], sources=["upload", "microphone"],
scale=1,
) )
pipe_manual = gr.Textbox( pipe_manual = gr.Textbox(
label="或手动输入转写(跳过识别)", label="或手动输入转写(跳过识别)",
lines=4, lines=8,
placeholder="若已有转写文本,可直接粘贴,留空则走 Whisper 识别", placeholder="若已有转写文本,可直接粘贴,留空则走 Whisper 识别",
scale=1,
elem_classes=["bright-input"],
) )
skip_polish_cb = gr.Checkbox( skip_polish_cb = gr.Checkbox(
label="跳过 Gemma4 润色(仅测试 TTS)", label="跳过 Gemma4 润色(仅测试 TTS)",
value=False, value=False,
) )
pipe_voice = gr.Radio( with gr.Accordion("🎚️ 配音音色", open=False):
label="配音音色(本地 ChatTTS", pipe_voice = gr.Radio(
choices=voice_choice_labels(), label="配音音色(本地 ChatTTS",
value=default_voice_label(), choices=voice_choice_labels(),
elem_classes=["voice-radio"], value=default_voice_label(),
) elem_classes=["voice-radio"],
)
pipeline_btn = gr.Button("▶ 启动全流程", variant="primary", size="lg") pipeline_btn = gr.Button("▶ 启动全流程", variant="primary", size="lg")
pipeline_log = gr.Textbox(label="流水线日志", lines=6, interactive=False) pipeline_log = gr.Textbox(label="流水线日志", lines=6, interactive=False)
with gr.Row(elem_classes=["pipeline-output-row"]): with gr.Row(elem_classes=["pipeline-output-row"]):
@@ -1370,7 +1421,7 @@ def build_app() -> gr.Blocks:
"<span style='color:#94a3b8;font-size:0.9rem'>" "<span style='color:#94a3b8;font-size:0.9rem'>"
"本机显卡合成,无需 API。润色完成后在此选音色并点合成。</span>" "本机显卡合成,无需 API。润色完成后在此选音色并点合成。</span>"
) )
with gr.Accordion("🎚️ 选择配音音色", open=True): with gr.Accordion("🎚️ 配音音色", open=False):
tts_voice = gr.Radio( tts_voice = gr.Radio(
label="配音音色(本地 ChatTTS", label="配音音色(本地 ChatTTS",
choices=voice_choice_labels(), choices=voice_choice_labels(),