- New light UI: fixed 220px sidebar, single scrolling page, 8 named sections - Static files split by concern: style.css, app.js, loader.js, nav.js - Each page section is its own partial in static/sections/s-*.html - loader.js fetches all section partials in parallel, then loads app.js and nav.js - All original functionality, element IDs, and API endpoints preserved Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
95 lines
4.4 KiB
HTML
95 lines
4.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>TTS Voice Creator</title>
|
|
<!-- WaveSurfer must load synchronously before app.js initialises audio -->
|
|
<script src="https://unpkg.com/wavesurfer.js@7/dist/wavesurfer.min.js"></script>
|
|
<script src="https://unpkg.com/wavesurfer.js@7/dist/plugins/regions.min.js"></script>
|
|
<link rel="stylesheet" href="/static/style.css">
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Hidden tabs nav — required for JS backend availability detection -->
|
|
<nav class="tabs" style="display:none" aria-hidden="true">
|
|
<div class="tab active" data-tab="library" data-backend-required="voice_clone" tabindex="-1"><span class="tab-title">Voice Clone</span></div>
|
|
<div class="tab" data-tab="design" data-backend-required="voice_design" tabindex="-1"><span class="tab-title">Voice Design</span></div>
|
|
<div class="tab" data-tab="custom" data-backend-required="customvoice" tabindex="-1"><span class="tab-title">Voice Custom</span></div>
|
|
<div class="tab" data-tab="generation" data-backend-required="any_tts" tabindex="-1"><span class="tab-title">TTS Generation</span></div>
|
|
<div class="tab" data-tab="stt-tts" data-backend-required="any_tts" tabindex="-1"><span class="tab-title">STT-TTS</span></div>
|
|
<div class="tab" data-tab="routing" tabindex="-1"><span class="tab-title">Routing</span></div>
|
|
<div class="tab" data-tab="integrations" tabindex="-1"><span class="tab-title">How to</span></div>
|
|
<div class="tab" data-tab="getvoices" tabindex="-1"><span class="tab-title">Get Voices</span></div>
|
|
<div class="tab" data-tab="settings" tabindex="-1"><span class="tab-title">Settings</span></div>
|
|
</nav>
|
|
|
|
<!-- App shell -->
|
|
<div id="app-shell">
|
|
|
|
<!-- Sidebar -->
|
|
<aside id="sidebar">
|
|
<div class="sidebar-brand">
|
|
<h1>🎤 Voice Creator</h1>
|
|
<p>Clone · Design · Deploy</p>
|
|
</div>
|
|
|
|
<nav class="sidebar-nav">
|
|
<div class="nav-group-label">Voices</div>
|
|
<div class="nav-item active" data-nav-section="s-voices" onclick="navTo('s-voices')">
|
|
<span class="nav-icon">🔊</span> My Voices
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-clone" onclick="navTo('s-clone')">
|
|
<span class="nav-icon">🎤</span> Clone a Voice
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-design" onclick="navTo('s-design')">
|
|
<span class="nav-icon">✨</span> Design a Voice
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-studio" onclick="navTo('s-studio')">
|
|
<span class="nav-icon">🌐</span> Get Voices Online
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-tryout" onclick="navTo('s-tryout')">
|
|
<span class="nav-icon">▶</span> Try It Out
|
|
</div>
|
|
|
|
<div class="nav-group-label" style="margin-top:6px">Setup</div>
|
|
<div class="nav-item" data-nav-section="s-routing" onclick="navTo('s-routing')">
|
|
<span class="nav-icon">⇌</span> App Routing
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-connect" onclick="navTo('s-connect')">
|
|
<span class="nav-icon">🔗</span> Connect Apps
|
|
</div>
|
|
<div class="nav-item" data-nav-section="s-settings" onclick="navTo('s-settings')">
|
|
<span class="nav-icon">⚙</span> Settings
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="sidebar-footer">
|
|
<button id="theme-btn" title="Switch theme" style="display:none">☀</button>
|
|
<button id="settings-btn" onclick="navTo('s-settings')" title="Open settings">⚙ Settings</button>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main scrollable content — sections filled by loader.js -->
|
|
<main id="main-content">
|
|
<section class="page-section" id="s-voices"></section>
|
|
<section class="page-section" id="s-clone"></section>
|
|
<section class="page-section" id="s-design"></section>
|
|
<section class="page-section" id="s-studio"></section>
|
|
<section class="page-section" id="s-tryout"></section>
|
|
<section class="page-section" id="s-routing"></section>
|
|
<section class="page-section" id="s-connect"></section>
|
|
<section class="page-section" id="s-settings"></section>
|
|
</main>
|
|
|
|
</div><!-- /app-shell -->
|
|
|
|
<div id="toast"></div>
|
|
<div id="status-bar">Loading…</div>
|
|
|
|
<!-- loader.js: fetches sections → loads app.js → loads nav.js -->
|
|
<script src="/static/loader.js"></script>
|
|
|
|
</body>
|
|
</html>
|