feat(frontend): engine dropdown + emotion dual mode

- Replace engine buttons with <select> dropdown
- Add ENGINE_CONFIG for centralized engine management
- Add global/per-sentence emotion UI mode switching
- Add #engine-select dark theme styles
- Remove old .switch-btn and .engine-icon styles
- Reset emotion state on engine switch
This commit is contained in:
lanhao
2026-07-01 00:48:05 +08:00
parent 81460f06d7
commit a0346d05ba
3 changed files with 88 additions and 42 deletions
+47 -10
View File
@@ -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', () => {