diff --git a/frontend/app.js b/frontend/app.js index f7a415c..e6a7c1a 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -3,10 +3,23 @@ */ const CONFIG = { - API_BASE_URL: '', // 空字符串表示使用相对路径,通过Nginx代理 + API_BASE_URL: '', MAX_CHARS: 2000, }; +const ENGINE_CONFIG = { + minimax: { + name: 'MiniMax', + emotionMode: 'global', + color: '#00d4aa' + }, + cosyvoice: { + name: 'CosyVoice', + emotionMode: 'global', + color: '#ff6b6b' + } +}; + // 情绪按钮与 API emotion 值的映射 const EMOTION_MAP = { 'happy': { emoji: '😊', label: '开心', apiValue: 'happy' }, @@ -30,8 +43,10 @@ const elements = { editor: document.getElementById('editor'), editorPlaceholder: document.getElementById('editorPlaceholder'), charCount: document.getElementById('charCount'), - switchBtns: document.querySelectorAll('.switch-btn'), + engineSelect: document.getElementById('engine-select'), emotionBtns: document.querySelectorAll('.emotion-btn'), + emotionGlobal: document.getElementById('emotion-global'), + emotionPerSentence: document.getElementById('emotion-per-sentence'), speedSlider: document.getElementById('speedSlider'), speedValue: document.getElementById('speedValue'), pitchSlider: document.getElementById('pitchSlider'), @@ -143,12 +158,34 @@ function updateSliderDisplay() { function switchEngine(engine) { state.currentEngine = engine; - elements.switchBtns.forEach(btn => { - btn.classList.toggle('active', btn.dataset.engine === engine); - }); - const engineName = engine === 'minimax' ? 'MiniMax' : 'CosyVoice'; - document.getElementById('engineBadge').textContent = `蓝皓 · ${engineName}`; - showToast(`已切换到${engineName}引擎`); + const config = ENGINE_CONFIG[engine]; + if (!config) return; + + // Update engine badge + const badge = document.getElementById('engineBadge'); + badge.textContent = `蓝皓 · ${config.name}`; + badge.style.background = config.color; + + // Update engine select value + elements.engineSelect.value = engine; + + // Switch emotion UI mode + updateEmotionMode(config.emotionMode); + + // Reset emotion state + clearEmotionSelection(); + + showToast(`已切换到${config.name}引擎`); +} + +function updateEmotionMode(mode) { + if (mode === 'global') { + elements.emotionGlobal.style.display = 'flex'; + elements.emotionPerSentence.style.display = 'none'; + } else if (mode === 'perSentence') { + elements.emotionGlobal.style.display = 'none'; + elements.emotionPerSentence.style.display = 'block'; + } } async function generateAudio() { @@ -290,8 +327,8 @@ function downloadAudio() { elements.editor.addEventListener('input', updateCharCount); elements.editor.addEventListener('paste', () => { setTimeout(updateCharCount, 0); }); -elements.switchBtns.forEach(btn => { - btn.addEventListener('click', () => switchEngine(btn.dataset.engine)); +elements.engineSelect.addEventListener('change', (e) => { + switchEngine(e.target.value); }); elements.emotionBtns.forEach(btn => { btn.addEventListener('click', () => { diff --git a/frontend/index.html b/frontend/index.html index 0e7a0e5..6c17859 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -37,24 +37,25 @@
diff --git a/frontend/styles.css b/frontend/styles.css index fb656f7..2ef08b6 100644 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -121,30 +121,38 @@ body { .toolbar-label { font-size: 0.85rem; color: var(--text-secondary); } .toolbar-hint { font-size: 0.7rem; color: var(--text-muted); margin-left: 8px; } -.switch-btn { - display: flex; - align-items: center; - gap: 4px; - padding: 4px 12px; - background: transparent; - border: 1px solid var(--border-color); +#engine-select { + padding: 6px 12px; + background: #1a1a25; + border: 1px solid #2a2a3a; border-radius: var(--radius-sm); - color: var(--text-secondary); + color: #ffffff; font-size: 0.85rem; cursor: pointer; transition: var(--transition-fast); + outline: none; + -webkit-appearance: none; + appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2371717a' d='M2 4l4 4 4-4'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 8px center; + padding-right: 28px; } -.switch-btn:hover { border-color: var(--border-hover); color: var(--text-primary); } -.switch-btn.active { background: var(--bg-card); border-color: var(--accent-primary); color: var(--text-primary); } +#engine-select:hover { border-color: var(--border-hover); } +#engine-select:focus { border-color: var(--accent-primary); } +#engine-select option { background: #1a1a25; color: #ffffff; } -.engine-icon { - width: 18px; height: 18px; - border-radius: var(--radius-sm); - display: flex; align-items: center; justify-content: center; - font-size: 0.65rem; font-weight: 700; +#emotion-global { + display: flex; + align-items: center; + gap: 4px; +} + +#emotion-per-sentence { + color: #71717a; + padding: 8px; + font-size: 0.85rem; } -.minimax-icon { background: var(--minimax-color); color: #0a0a0f; } -.cosyvoice-icon { background: var(--cosyvoice-color); color: white; } .emotion-btn { width: 32px; height: 32px;