Move header and status into config tab for compact nav

Use four tabs (one-click, pipeline, voice lock, config) as the main navigation and relocate project intro, install button, and Ollama or speaker status into the config tab to save vertical space.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-12 18:50:35 +08:00
parent 541df29722
commit 2dd642598f
+53 -49
View File
@@ -1091,50 +1091,9 @@ def build_app() -> gr.Blocks:
with gr.Blocks(
title="Trading Studio | 交易复盘配音中控",
) as demo:
with gr.Row(elem_classes=["header-row"]):
gr.Markdown(
f"""
# ⚡ Trading Studio
**本地量化交易复盘 → B 站配音生产流水线**
| 模块 | 说明 |
|------|------|
| Whisper | 本地 GPU 语音识别 |
| Gemma4 | `{MODEL_NAME}` @ `{OLLAMA_URL.replace('/api/chat', '')}` |
| ChatTTS | 本地 GPU 固定音色合成 |
> 仓库: [{GIT_REPO_URL}]({GIT_REPO_URL})
""",
elem_classes=["dark-panel"],
)
gr.HTML(INSTALL_APP_BUTTON_HTML)
with gr.Row(elem_classes=["status-row"]):
ollama_status = gr.HTML(value=_status_html("Ollama 节点", "正在检测...", "warn"))
speaker_status = gr.HTML(value=_status_html("音色状态", "正在检测...", "warn"))
refresh_btn = gr.Button("🔄 刷新状态", variant="secondary", scale=0, min_width=120)
refresh_btn.click(
fn=lambda: ui_refresh_status_html(force=True),
outputs=[ollama_status, speaker_status],
)
demo.load(
fn=ui_initial_load,
outputs=[ollama_status, speaker_status],
)
# 仅低频刷新状态(去掉 1s Timer,避免合成后整页闪屏)
status_timer_slow = gr.Timer(value=60, active=True)
status_timer_slow.tick(
fn=lambda: ui_refresh_status_html(force=True),
outputs=[ollama_status, speaker_status],
)
with gr.Tabs():
# ---- Tab 1: 一键生(默认首页)----
with gr.Tab("🚀 一键生"):
# ---- Tab 1: 一键生(默认首页)----
with gr.Tab("一键生"):
gr.HTML(MIC_HINT_HTML)
gr.Markdown(
"上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。"
@@ -1168,7 +1127,7 @@ def build_app() -> gr.Blocks:
pipe_output = _tts_output_audio("成品配音")
# ---- Tab 2: 分步流水线 ----
with gr.Tab("🔧 分步流水线"):
with gr.Tab("分步流水线"):
gr.HTML(MIC_HINT_HTML)
with gr.Column(elem_classes=["pipeline-flow"]):
with gr.Group(elem_classes=["pipeline-step-card"]):
@@ -1218,7 +1177,7 @@ def build_app() -> gr.Blocks:
polish_btn.click(ui_polish, raw_text, [polished_text, polish_log])
# ---- Tab 3: 音色锁定 ----
with gr.Tab("🎙️ 音色锁定"):
with gr.Tab("音色锁定"):
gr.HTML(MIC_HINT_HTML)
gr.HTML(
f'<div class="hint-box">'
@@ -1242,11 +1201,56 @@ def build_app() -> gr.Blocks:
)
lock_btn = gr.Button("🔒 锁定音色", variant="primary")
lock_log = gr.Textbox(label="锁定结果", lines=4, interactive=False)
lock_btn.click(
ui_lock_speaker,
[spk_audio, spk_transcript],
[lock_log, speaker_status],
# ---- Tab 4: 配置说明 ----
with gr.Tab("配置说明"):
gr.Markdown(
f"""
# ⚡ Trading Studio
**本地量化交易复盘 → B 站配音生产流水线**
| 模块 | 说明 |
|------|------|
| Whisper | 本地 GPU 语音识别 |
| Gemma4 | `{MODEL_NAME}` @ `{OLLAMA_URL.replace('/api/chat', '')}` |
| ChatTTS | 本地 GPU 固定音色合成 |
> 仓库: [{GIT_REPO_URL}]({GIT_REPO_URL})
> 中控端口: `{PORT}` · 部署路径: `/opt/Trading_Studio`
""",
elem_classes=["dark-panel"],
)
gr.HTML(INSTALL_APP_BUTTON_HTML)
with gr.Row(elem_classes=["status-row"]):
ollama_status = gr.HTML(
value=_status_html("Ollama 节点", "正在检测...", "warn")
)
speaker_status = gr.HTML(
value=_status_html("音色状态", "正在检测...", "warn")
)
refresh_btn = gr.Button(
"🔄 刷新状态", variant="secondary", scale=0, min_width=120
)
refresh_btn.click(
fn=lambda: ui_refresh_status_html(force=True),
outputs=[ollama_status, speaker_status],
)
demo.load(
fn=ui_initial_load,
outputs=[ollama_status, speaker_status],
)
status_timer_slow = gr.Timer(value=60, active=True)
status_timer_slow.tick(
fn=lambda: ui_refresh_status_html(force=True),
outputs=[ollama_status, speaker_status],
)
lock_btn.click(
ui_lock_speaker,
[spk_audio, spk_transcript],
[lock_log, speaker_status],
)
with gr.Accordion("📂 配音历史(本地保留,可随时试听下载)", open=True):
with gr.Row():