Spaces:
Running
Running
let isRecording = false; | |
let recognition; | |
let responsesHistory = {}; // Holds all responses per prompt | |
let currentIndex = {}; // Track current response index | |
function initSpeechRecognition() { | |
// Check for SpeechRecognition compatibility | |
if (!('SpeechRecognition' in window || 'webkitSpeechRecognition' in window)) { | |
alert("Speech recognition is not supported in your browser."); | |
return; | |
} | |
window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; | |
recognition = new SpeechRecognition(); | |
recognition.lang = 'en-US'; | |
recognition.interimResults = false; | |
recognition.maxAlternatives = 1; | |
recognition.onresult = function (event) { | |
const transcript = event.results[0][0].transcript; | |
sendMessageFromVoice(transcript); | |
}; | |
recognition.onerror = function (event) { | |
console.log("Speech recognition error:", event.error); | |
alert("Error in speech recognition: " + event.error); | |
}; | |
recognition.onend = function () { | |
isRecording = false; | |
micIcon.textContent = 'mic'; | |
}; | |
} | |
const micIcon = document.getElementById('mic-icon'); | |
micIcon.addEventListener('click', function () { | |
if (isRecording) { | |
recognition.stop(); | |
isRecording = false; | |
micIcon.textContent = 'mic'; | |
} else { | |
recognition.start(); | |
isRecording = true; | |
micIcon.textContent = 'mic_off'; | |
} | |
}); | |
function appendMessage(text, className) { | |
const chatbox = document.getElementById('chatbox'); | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = 'message ' + className; | |
messageDiv.innerHTML = text; | |
chatbox.appendChild(messageDiv); | |
chatbox.scrollTop = chatbox.scrollHeight; | |
} | |
function sendMessageFromVoice(message) { | |
appendMessage(message, 'user'); | |
fetchMessageFromAI(message); | |
} | |
function sendMessage() { | |
const userInput = document.getElementById('user-input'); | |
const message = userInput.value.trim(); | |
if (message === '') return; | |
appendMessage(message, 'user'); | |
userInput.value = ''; | |
fetchMessageFromAI(message); | |
} | |
function fetchMessageFromAI(message) { | |
const typingIndicator = document.getElementById('typing-indicator'); | |
typingIndicator.style.display = 'flex'; | |
fetch('/message', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify({ text: message }) // Sending message text as JSON | |
}) | |
.then(response => { | |
if (!response.ok) { | |
throw new Error(`Server error: ${response.statusText}`); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
typingIndicator.style.display = 'none'; | |
if (data.response) { | |
// Add the AI's response to the chatbox | |
addAIResponse(data.response, message); | |
} else { | |
console.error("No response from the server."); | |
appendMessage("No response from the AI.", 'ai'); | |
} | |
}) | |
.catch(error => { | |
typingIndicator.style.display = 'none'; | |
console.error('Error:', error); | |
appendMessage("An error occurred. Please try again later.", 'ai'); | |
}); | |
} | |
function addAIResponse(responseText, userPrompt) { | |
const responseId = Date.now(); | |
responsesHistory[responseId] = [responseText]; | |
currentIndex[responseId] = 0; | |
renderAIResponse(responseText, responseId, userPrompt); | |
} | |
function renderAIResponse(responseText, responseId, userPrompt) { | |
const chatbox = document.getElementById('chatbox'); | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = 'message ai'; | |
messageDiv.dataset.responseId = responseId; | |
messageDiv.dataset.userPrompt = userPrompt; // Store the prompt | |
const responseTextDiv = document.createElement('div'); | |
responseTextDiv.className = 'response-text'; | |
responseTextDiv.innerHTML = responseText; | |
messageDiv.appendChild(responseTextDiv); | |
const iconsDiv = document.createElement('div'); | |
iconsDiv.className = 'icons'; | |
const speakerIcon = document.createElement('span'); | |
speakerIcon.className = 'material-icons'; | |
speakerIcon.innerText = 'volume_up'; | |
speakerIcon.onclick = () => speakText(responseId); | |
const copyIcon = document.createElement('span'); | |
copyIcon.className = 'material-icons'; | |
copyIcon.innerText = 'content_copy'; | |
copyIcon.onclick = () => copyResponse(responseId); | |
const regenerateIcon = document.createElement('span'); | |
regenerateIcon.className = 'material-icons'; | |
regenerateIcon.innerText = 'replay'; | |
regenerateIcon.onclick = () => regenerateResponse(responseId, responseTextDiv, iconsDiv); | |
iconsDiv.appendChild(speakerIcon); | |
iconsDiv.appendChild(copyIcon); | |
iconsDiv.appendChild(regenerateIcon); | |
messageDiv.appendChild(iconsDiv); | |
chatbox.appendChild(messageDiv); | |
chatbox.scrollTop = chatbox.scrollHeight; | |
} | |
document.addEventListener('DOMContentLoaded', initSpeechRecognition); | |