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:
+47
-10
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user