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:
@@ -1091,50 +1091,9 @@ def build_app() -> gr.Blocks:
|
|||||||
with gr.Blocks(
|
with gr.Blocks(
|
||||||
title="Trading Studio | 交易复盘配音中控",
|
title="Trading Studio | 交易复盘配音中控",
|
||||||
) as demo:
|
) 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():
|
with gr.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(
|
||||||
"上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。"
|
"上传碎碎念录音,系统自动完成 **识别 → 润色 → 合成** 全流程。"
|
||||||
@@ -1168,7 +1127,7 @@ def build_app() -> gr.Blocks:
|
|||||||
pipe_output = _tts_output_audio("成品配音")
|
pipe_output = _tts_output_audio("成品配音")
|
||||||
|
|
||||||
# ---- Tab 2: 分步流水线 ----
|
# ---- Tab 2: 分步流水线 ----
|
||||||
with gr.Tab("🔧 分步流水线"):
|
with gr.Tab("分步流水线"):
|
||||||
gr.HTML(MIC_HINT_HTML)
|
gr.HTML(MIC_HINT_HTML)
|
||||||
with gr.Column(elem_classes=["pipeline-flow"]):
|
with gr.Column(elem_classes=["pipeline-flow"]):
|
||||||
with gr.Group(elem_classes=["pipeline-step-card"]):
|
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])
|
polish_btn.click(ui_polish, raw_text, [polished_text, polish_log])
|
||||||
|
|
||||||
# ---- Tab 3: 音色锁定 ----
|
# ---- Tab 3: 音色锁定 ----
|
||||||
with gr.Tab("🎙️ 音色锁定"):
|
with gr.Tab("音色锁定"):
|
||||||
gr.HTML(MIC_HINT_HTML)
|
gr.HTML(MIC_HINT_HTML)
|
||||||
gr.HTML(
|
gr.HTML(
|
||||||
f'<div class="hint-box">'
|
f'<div class="hint-box">'
|
||||||
@@ -1242,11 +1201,56 @@ def build_app() -> gr.Blocks:
|
|||||||
)
|
)
|
||||||
lock_btn = gr.Button("🔒 锁定音色", variant="primary")
|
lock_btn = gr.Button("🔒 锁定音色", variant="primary")
|
||||||
lock_log = gr.Textbox(label="锁定结果", lines=4, interactive=False)
|
lock_log = gr.Textbox(label="锁定结果", lines=4, interactive=False)
|
||||||
lock_btn.click(
|
|
||||||
ui_lock_speaker,
|
# ---- Tab 4: 配置说明 ----
|
||||||
[spk_audio, spk_transcript],
|
with gr.Tab("配置说明"):
|
||||||
[lock_log, speaker_status],
|
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.Accordion("📂 配音历史(本地保留,可随时试听下载)", open=True):
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
|
|||||||
Reference in New Issue
Block a user