Spaces:
Runtime error
Runtime error
| 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); | |