Spaces:
Sleeping
Sleeping
| let mapEnabled = false; // Flag to track if mapping is enabled | |
| let spotifyEnabled = false; // Flag to track if spotify is enabled | |
| startNewChat(); | |
| function sendMessage() { | |
| // Hide sample questions buttons | |
| hideAdditionalButtons(); | |
| // Determine route based on Map and Spotify flags | |
| if (mapEnabled) { | |
| // If mapping is enabled, handle mapping functionality | |
| handleMapping() | |
| } else if (spotifyEnabled) { | |
| // If spotify is enabled, handle spotify functionality | |
| var userInput = document.getElementById("user-input").value.trim(); | |
| if (userInput !== "") { | |
| // Pass user input to Python Flask for processing | |
| sendSpotifyRequest(userInput); | |
| } else { | |
| updateAndDisplayMessage("Please enter a song title or artist.", false); | |
| } | |
| } else { | |
| var userInput = document.getElementById("user-input").value.trim(); | |
| sendRegularMessage(userInput) | |
| } | |
| // Clear input field | |
| document.getElementById("user-input").value = ""; | |
| } | |
| // ============================== Spotify ============================== | |
| function toggleSpotify(){ | |
| hideAdditionalButtons(); | |
| spotifyEnabled = !spotifyEnabled | |
| mapEnabled = false; | |
| // Update the appearance of the buttons | |
| updateButtons(spotifyEnabled,mapEnabled) | |
| if (spotifyEnabled) { | |
| updateAndDisplayMessage("Please enter a song title or artist.", false); | |
| } else { | |
| updateAndDisplayMessage("Spotify turned off.", false); | |
| } | |
| } | |
| function sendSpotifyRequest(musicRequest) { | |
| // Display user's message immediately | |
| displayMessage(musicRequest, true); | |
| // Send user's message and selected language to server | |
| fetch('/handle_spotify', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json;charset=UTF-8' | |
| }, | |
| body: JSON.stringify({ song: musicRequest }) | |
| }) | |
| .then(response => { | |
| if (response.ok) { | |
| return response.json(); | |
| } else { | |
| throw new Error('Network response was not ok.'); | |
| } | |
| }) | |
| .then(responseData => { | |
| // Display Spotify results | |
| displaySpotifyResults(responseData) | |
| console.log("Attempting to display Spotify results"); | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| }); | |
| } | |
| function displaySpotifyResults(results) { | |
| updateAndDisplayMessage("Here are the top 5 results for this query:"); | |
| var chatList = document.querySelector(".chat"); | |
| results.forEach(track => { | |
| var messageElement = document.createElement("li"); | |
| messageElement.className = "message-music"; | |
| // Create and append image element | |
| var imageElement = document.createElement("img"); | |
| imageElement.src = track.image; | |
| imageElement.className = "play-btn"; | |
| imageElement.dataset.id = track.preview_url; // Use preview URL as track ID | |
| imageElement.addEventListener("click", play); | |
| messageElement.appendChild(imageElement); | |
| // Create and append text content (track name and artist) | |
| var textElement = document.createElement("span"); | |
| textElement.textContent = track.name + ' - ' + track.artist; | |
| messageElement.appendChild(textElement); | |
| chatList.appendChild(messageElement); | |
| }); | |
| } | |
| function play() { | |
| const previewUrl = this.getAttribute('data-id'); | |
| const player = document.getElementById('player'); | |
| player.innerHTML = ''; | |
| if (previewUrl && previewUrl !== '') { | |
| const audio = document.createElement('audio'); | |
| audio.controls = true; | |
| audio.src = previewUrl; | |
| player.appendChild(audio); | |
| audio.play(); | |
| audio.addEventListener('ended', function() { | |
| audio.currentTime = 0; // Reset audio to the beginning | |
| audio.play(); // Restart playback | |
| }); | |
| } else { | |
| player.innerHTML = 'No preview available'; | |
| } | |
| } | |
| // ============================== Mapping ============================== | |
| function toggleMap() { | |
| hideAdditionalButtons(); | |
| mapEnabled = !mapEnabled; // Toggle the flag | |
| spotifyEnabled = false; | |
| updateButtons(spotifyEnabled,mapEnabled) | |
| // Display message in the chat area based on the state | |
| if (mapEnabled) { | |
| addLocationDropDown("start_location", false, "Select Starting Location: "); | |
| addLocationDropDown("end_location", false, "Select Ending Location: "); | |
| } else { | |
| updateAndDisplayMessage("Mapping turned off.", false); | |
| } | |
| } | |
| function addLocationDropDown(idAndName, isUserMessage, location_string) { | |
| var chatList = document.querySelector(".chat"); | |
| // Create message element | |
| var messageElement = document.createElement("li"); | |
| messageElement.className = "message"; | |
| // Create label for the drop down menu | |
| var dropdownLabel = document.createElement("label"); | |
| dropdownLabel.setAttribute("for", idAndName); | |
| dropdownLabel.textContent = location_string; | |
| // Add elements to the html | |
| messageElement.appendChild(dropdownLabel); | |
| chatList.appendChild(messageElement); | |
| var dropdown = document.createElement("select"); | |
| dropdown.setAttribute("id", idAndName); | |
| dropdown.setAttribute("name", idAndName); | |
| dropdown.className = "location-dropdown"; | |
| var locations = { | |
| "42 Langguth Road":"42 Langguth Road, West Langguth Road, 06824 Fairfield, Connecticut, United States", | |
| "Kelley Center":"Aloysius P. Kelley Center, Loyola Drive, 06824 Fairfield, United States", | |
| "Alumni Hall Sports Arena":"Alumni Hall Sports Arena, Leeber Road, 06824 Fairfield, Connecticut, United States", | |
| "Alumni House":"Alumni House, Stonkas Road, 06824 Fairfield, United States", | |
| "Alumni Softball Field":"Alumni Softball Field, McCormick Road, 06824 Fairfield, United States", | |
| "Barlow Field":"Barlow Field, Barlow Road, 06824 Fairfield, United States", | |
| "Barone Campus Center":"Barone Campus Center, Loyola Drive, 06824 Fairfield, United States", | |
| "Bellarmine Hall":"Bellarmine Hall, Fitzgerald Way, 06824 Fairfield, United States", | |
| "Campion Hall":"Campion Hall, McCormick Road, 06824 Fairfield, United States", | |
| "Canisius Hall":"Canisius Hall, East Langguth Road, 06824 Fairfield, Connecticut, United States", | |
| "Center for Nursing and Health Studies":"Center for Nursing and Health Studies, McInnes Road, 06824 Fairfield, United States", | |
| "Charles F Dolan School of Business":"Charles F Dolan School of Business, Bellarmine Road, 06824 Fairfield, CT, United States", | |
| "Claver Hall":"Claver Hall, Mahan Road, 06824 Fairfield, United States", | |
| "Conference Center at Fairfield U":"Conference Center at Fairfield University, Walters Way, 06824 Fairfield, United States", | |
| "David J Dolan House":"David J Dolan House, Mooney Road, 06824 Fairfield, CT, United States", | |
| "DiMenna-Nyselius Library":"DiMenna-Nyselius Library, McInnes Road, 06824 Fairfield, United States", | |
| "Donnarumma Hall":"Donnarumma Hall, East Langguth Road, 06824 Fairfield, Connecticut, United States", | |
| "Egan Chapel of Saint Ignatius Lo":"Egan Chapel of Saint Ignatius Loyola, Bellarmine Road, 06824 Fairfield, United States", | |
| "Faber Hall":"Faber Hall, Bellarmine Road, 06824 Fairfield, United States", | |
| "Gonzaga Hall":"Gonzaga Hall, East Langguth Road, 06824 Fairfield, Connecticut, United States", | |
| "Jesuit Community Center":"Jesuit Community Center, Bellarmine Road, 06824 Fairfield, United States", | |
| "Jogues Hall":"Jogues Hall, McCormick Road, 06824 Fairfield, United States", | |
| "John C. Dolan Hall":"John C. Dolan Hall, Mooney Road, 06824 Fairfield, CT, United States", | |
| "Kelley Center Parking Garage":"Kelley Center Parking Garage, Leeber Road, 06824 Fairfield, Connecticut, United States", | |
| "Kostka Hall":"Kostka Hall, Mahan Road, 06824 Fairfield, United States", | |
| "Lessing Field":"Lessing Field, Leeber Road, 06824 Fairfield, Connecticut, United States", | |
| "Loyola Hall":"Loyola Hall, McCormick Road, 06824 Fairfield, United States", | |
| "Mahan Road":"Mahan Road, 06824 Fairfield, United States", | |
| "McAuliffe Hall":"McAuliffe Hall, Ross Road, 06824 Fairfield, United States", | |
| "McCormick Road":"McCormick Road, 06824 Fairfield, United States", | |
| "Meditz Hall":"Meditz Hall, McInnes Road, 06824 Fairfield, United States", | |
| "Rafferty Stadium":"Rafferty Stadium, Lynch Road, 06824 Fairfield, United States", | |
| "Regina A Quick Center for the Arts":"Regina A Quick Center for the Arts, McInnes Road, 06824 Fairfield, CT, United States", | |
| "Regis Hall":"Regis Hall, East Langguth Road, 06824 Fairfield, Connecticut, United States", | |
| "Rudolph F. Bannow Science Center":"Rudolph F. Bannow Science Center, McInnes Road, 06824 Fairfield, United States", | |
| "Student Townhouse Complex":"Student Townhouse Complex, Lynch Road, 06824 Fairfield, CT, United States", | |
| "The Levee":"The Levee, Lynch Road, 06824 Fairfield, CT, United States", | |
| "University Field":"University Field, Leeber Road, 06824 Fairfield, Connecticut, United States", | |
| "Walsh Athletic Center":"Walsh Athletic Center, Lynch Road, 06824 Fairfield, United States" | |
| }; | |
| Object.keys(locations).forEach(function(key) { | |
| var option = document.createElement("option"); | |
| option.setAttribute("value", locations[key]); | |
| option.textContent = key; | |
| dropdown.appendChild(option); | |
| }); | |
| messageElement.appendChild(dropdown); | |
| } | |
| function handleMapping() { | |
| var start_location = document.getElementById("start_location").value | |
| var end_location = document.getElementById("end_location").value | |
| // Create an object with the data | |
| var data = { | |
| start_location: start_location, | |
| end_location: end_location | |
| }; | |
| fetch('/handle_mapping', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json;charset=UTF-8' | |
| }, | |
| body: JSON.stringify(data) // Pass the data object | |
| }) | |
| .then(response => { | |
| if (response.ok) { | |
| return response.json(); | |
| } else { | |
| throw new Error('Network response was not ok.'); | |
| } | |
| }) | |
| .then(responseData => { | |
| // Clear display, and display map rsults | |
| console.log("Attempting to display mapping results"); | |
| toggleMap(); | |
| clearChat(); | |
| displayMessage(responseData.message, false); | |
| displayMap(responseData); | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| }); | |
| } | |
| function displayMap(responseData){ | |
| // Select the chat area | |
| var chatList = document.querySelector(".chat"); | |
| // Create new message element in the chat | |
| var messageElement = document.createElement("li"); | |
| messageElement.className = "message"; | |
| chatList.appendChild(messageElement); | |
| // Create new map element in the message element | |
| var mapContainer = document.createElement("iframe"); | |
| mapContainer.srcdoc = responseData.map_html | |
| messageElement.appendChild(mapContainer); | |
| } | |
| // ============================== Chatbot ============================== | |
| function sendRegularMessage(userInput) { | |
| var languageSelect = document.getElementById("language-select"); | |
| var selectedLanguage = languageSelect.value; | |
| if (userInput.trim() !== "") { | |
| // Display user's message immediately | |
| displayMessage(userInput, true); | |
| // Display loading message for bot response | |
| displayMessage("...", false); | |
| // Send user's message and selected language to server using fetch | |
| fetch('/process_message', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json;charset=UTF-8' | |
| }, | |
| body: JSON.stringify({ message: userInput, language: selectedLanguage }) | |
| }) | |
| .then(response => { | |
| if (response.ok) { | |
| return response.json(); | |
| } else { | |
| throw new Error('Network response was not ok.'); | |
| } | |
| }) | |
| .then(responseData => { | |
| // Update bot's response | |
| updateBotResponse(responseData.response); | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| }); | |
| // Clear user input field | |
| document.getElementById("user-input").value = ""; | |
| } | |
| } | |
| // Function to check if a message contains 'code block' | |
| function hasCodeSnippet(message) { | |
| return /\```(?:[^```]+)\```/g.test(message); | |
| } | |
| // Function to convert message to HTML with code blocks | |
| function convertMessageToHTML(message) { | |
| // Handle code blocks first (before other replacements) | |
| const codeBlocks = []; | |
| message = message.replace(/```(.*?)```/gs, (match) => { | |
| codeBlocks.push(match); | |
| return `__CODE_BLOCK_${codeBlocks.length - 1}__`; | |
| }); | |
| // Convert markdown to HTML | |
| // Headers | |
| message = message.replace(/^### (.+)$/gm, '<h3>$1</h3>'); | |
| message = message.replace(/^## (.+)$/gm, '<h2>$1</h2>'); | |
| message = message.replace(/^# (.+)$/gm, '<h1>$1</h1>'); | |
| // Bold and italic | |
| message = message.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>'); | |
| message = message.replace(/\*(.+?)\*/g, '<em>$1</em>'); | |
| // Lists | |
| message = message.replace(/^- (.+)$/gm, '<li>$1</li>'); | |
| message = message.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>'); | |
| // Line breaks | |
| message = message.replace(/\n/g, '<br>'); | |
| // Restore code blocks | |
| codeBlocks.forEach((block, i) => { | |
| const code = block.replace(/```(.*?)```/s, '<div class="code-wrapper"><pre><code>$1</code></pre></div>'); | |
| message = message.replace(`__CODE_BLOCK_${i}__`, code); | |
| }); | |
| return message; | |
| } | |
| function updateBotResponse(botMessage) { | |
| // Find the loading message and replace it with the bot's response | |
| var loadingMessage = document.querySelector(".loading-message"); | |
| if (loadingMessage) { | |
| loadingMessage.innerHTML = convertMessageToHTML(botMessage.trim()); | |
| loadingMessage.classList.remove("loading-message"); | |
| } else { | |
| // If loading message is not found, add the bot's response | |
| displayMessage(botMessage, false); | |
| } | |
| } | |
| function displayMessage(message, isUserMessage) { | |
| var chatList = document.querySelector(".chat"); | |
| // Display user's message or bot's response | |
| var messageElement = document.createElement("li"); | |
| if (hasCodeSnippet(message)){ | |
| messageElement.innerHTML = convertMessageToHTML(message); | |
| messageElement.className = "message" + (isUserMessage ? " user-message" : " loading-message"); | |
| chatList.appendChild(messageElement); | |
| } else { | |
| messageElement.innerHTML = message; | |
| messageElement.className = "message" + (isUserMessage ? " user-message" : " loading-message"); | |
| chatList.appendChild(messageElement); | |
| } | |
| } | |
| // Helper function to display and update message | |
| function updateAndDisplayMessage(message, isUserMessage){ | |
| displayMessage(message, isUserMessage); | |
| updateBotResponse(message); | |
| } | |
| // ============================== New Chat ============================== | |
| // Function to start new chat | |
| function startNewChat() { | |
| mapEnabled = false; // Reset map flag to false | |
| spotifyEnabled = false; // Reset spotify flag to false | |
| updateButtons(spotifyEnabled,mapEnabled); // Update button highlighting | |
| showAdditionalButtons(); // Show the sample prompts | |
| clearChat(); | |
| updateAndDisplayMessage("Hello, how can I assist you?", false); | |
| // Send a POST request to clear the conversation history on the server side | |
| fetch('/clear_history', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json;charset=UTF-8' | |
| } | |
| }) | |
| .then(response => { | |
| if (response.ok) { | |
| console.log('Conversation history cleared.'); | |
| } else { | |
| throw new Error('Failed to clear conversation history.'); | |
| } | |
| }) | |
| .catch(error => { | |
| console.error('Error:', error); | |
| }); | |
| // Clear the audio player | |
| const player = document.getElementById('player'); | |
| player.innerHTML = ''; | |
| } | |
| // Helper function to clear chat container messages | |
| function clearChat(){ | |
| var chatList = document.querySelector(".chat"); | |
| chatList.innerHTML = ''; | |
| } | |
| // ============================== Speech Recognition ============================== | |
| function startSpeechRecognition() { | |
| var recognition = new window.webkitSpeechRecognition(); // Create a new SpeechRecognition object | |
| recognition.lang = "en-US"; // Set language to English (United States) | |
| recognition.onresult = function(event) { // When speech recognition is successful | |
| var transcript = event.results[0][0].transcript; // Get the recognized transcript | |
| document.getElementById("user-input").value = transcript; // Set the transcript as user input | |
| sendMessage(); // Call sendMessage function to process the input | |
| }; | |
| recognition.onerror = function(event) { // If there's an error in speech recognition | |
| console.error("Speech recognition error:", event.error); | |
| alert("Error occurred in speech recognition. Please try again."); // Show an error message | |
| }; | |
| recognition.onstart = function() { // When speech recognition starts | |
| document.getElementById("record-button").classList.add("active"); // Add "active" class to record button | |
| }; | |
| recognition.onend = function() { // When speech recognition ends | |
| document.getElementById("record-button").classList.remove("active"); // Remove "active" class from record button | |
| }; | |
| recognition.start(); // Start speech recognition | |
| } | |
| // ============================== Instructions ============================== | |
| const instructions = `Start Conversation: Type your message in the text box and press 'Send' to start a conversation with the chatbot.\n | |
| Voice Input: Click 'Record Speech' to speak instead of typing. The chatbot will transcribe and respond to your voice message. \n | |
| Language Selection: Use the dropdown menu to select your preferred language for communication with the chatbot. \n | |
| New Chat: Click 'New Chat' to start a new conversation and clear the chat history. \n | |
| Spotify: Click the spotify button to toggle functionality \n | |
| Map: Click the map button to toggle mapping functionality\n` | |
| // Function to display the instructions | |
| function addInstructions() { | |
| startNewChat(); | |
| updateAndDisplayMessage(instructions,false); | |
| hideAdditionalButtons(); | |
| } | |
| // ============================== Buttons ============================== | |
| // Function to update the spotify and map buttons | |
| function updateButtons(spotifyEnabled,mapEnabled) { | |
| // Update spotify button | |
| const spotifyButton = document.getElementById("spotify-button"); | |
| spotifyButton.classList.toggle("active", spotifyEnabled); // Add or remove "active" class | |
| // Update map button | |
| const mapButton = document.getElementById("map-button"); | |
| mapButton.classList.toggle("active", mapEnabled); // Add or remove "active" class | |
| } | |
| // Function to hide additional buttons | |
| function hideAdditionalButtons() { | |
| var additionalButtons = document.getElementById("additional-buttons"); | |
| additionalButtons.style.display = "none"; | |
| } | |
| // Function to show additional buttons | |
| function showAdditionalButtons() { | |
| var additionalButtons = document.getElementById("additional-buttons"); | |
| additionalButtons.style.display = "block"; | |
| } | |
| // Function to handle sample buttons | |
| function handleSample(button){ | |
| const question = button.innerText.trim(); // Get the inner text of the button | |
| hideAdditionalButtons(); | |
| sendRegularMessage(question); | |
| } | |
| // Function to allow user to press enter to submit | |
| function handleKeyDown(event) { | |
| if (event.key === "Enter") { | |
| event.preventDefault(); // Prevents the default Enter key behavior (like adding a new line) | |
| sendMessage(); // Calls the sendMessage function when Enter is pressed | |
| } | |
| } | |