XiaoBai1221's picture
Done
6c78660
function typewriterEffect(text, speed = 50, enableTTS = true) {
agentOutput.textContent = '';
agentOutput.classList.add('active');
agentOutput.classList.remove('typing-done');
let index = 0;
if (typingInterval) {
clearInterval(typingInterval);
}
if (enableTTS && typeof speakText === 'function') {
speakText(text); // 語音與打字效果並行
}
typingInterval = setInterval(() => {
if (index < text.length) {
agentOutput.textContent += text[index];
index++;
} else {
clearInterval(typingInterval);
agentOutput.classList.add('typing-done'); // 打字完成,隱藏游標
}
}, speed);
}
function hideAgentOutput() {
if (typingInterval) {
clearInterval(typingInterval);
}
agentOutput.classList.remove('active');
agentOutput.textContent = '';
}
function initEmotionSelector() {
document.getElementById('emotion-select').addEventListener('change', (e) => {
const emotion = e.target.value;
background.className = `voice-immersive-background emotion-${emotion} active`;
emotionIndicator.textContent = `當前情緒: ${emotionEmojis[emotion]}`;
});
}
function initTranscriptControls() {
document.getElementById('transcript-provisional').addEventListener('click', () => {
transcript.textContent = '今天天氣怎麼樣';
transcript.className = 'voice-transcript provisional';
});
document.getElementById('transcript-final').addEventListener('click', () => {
transcript.textContent = '今天天氣怎麼樣?';
transcript.className = 'voice-transcript final';
});
}
function initLoginButton() {
const googleLoginBtn = document.getElementById('googleLoginBtn');
if (googleLoginBtn) {
googleLoginBtn.addEventListener('click', handleGoogleLogin);
}
}
function initLogoutButton() {
const logoutBtn = document.getElementById('logoutBtn');
if (logoutBtn) {
logoutBtn.addEventListener('click', handleLogout);
}
}
function handleLogout() {
localStorage.removeItem('jwt_token');
if (typeof ws !== 'undefined' && ws) {
ws.close();
}
if (typeof stopSpeaking === 'function') {
stopSpeaking();
}
window.location.href = '/login/';
}
let isTextInputMode = false; // 當前是否為文字輸入模式
let textInputElement = null; // 文字輸入框元素
function initChatIcon() {
const chatIcon = document.getElementById('chatIcon');
if (chatIcon) {
chatIcon.addEventListener('click', toggleInputMode);
}
}
function toggleInputMode() {
isTextInputMode = !isTextInputMode;
const transcript = document.getElementById('transcript');
if (!transcript) {
console.error('❌ 找不到 transcript 元素');
return;
}
if (isTextInputMode) {
const originalContent = transcript.textContent;
transcript.className = 'voice-transcript text-input-mode';
transcript.innerHTML = '';
textInputElement = document.createElement('textarea');
textInputElement.placeholder = '請輸入訊息...';
textInputElement.id = 'text-input-box';
textInputElement.addEventListener('keydown', handleTextInput);
transcript.appendChild(textInputElement);
setTimeout(() => textInputElement.focus(), 100);
} else {
if (textInputElement) {
textInputElement.removeEventListener('keydown', handleTextInput);
textInputElement = null;
}
transcript.className = 'voice-transcript provisional';
transcript.textContent = '請說話...';
}
}
function handleTextInput(event) {
if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
const text = textInputElement.value.trim();
if (!text) {
console.warn('⚠️ 訊息為空,不送出');
return;
}
if (typeof wsManager !== 'undefined' && wsManager) {
const chatId = window.currentChatId || null;
wsManager.sendUserMessage(text, chatId);
textInputElement.value = '';
if (typeof setState === 'function') {
setState('thinking');
}
toggleInputMode();
} else {
console.error('❌ WebSocket 未初始化');
}
}
}