File size: 20,057 Bytes
a41ca00 0f1b9e9 a41ca00 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | 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
}
}
|