/*document.addEventListener("DOMContentLoaded", () => { const convo = document.querySelector(".convo"); const input = document.querySelector(".qt input"); const sendBtn = document.querySelector(".sendingQA"); const fileBtn = document.querySelector(".fa-file"); const imageBtn = document.querySelector(".fa-image"); let selectedFile = null; let filePreviewBubble = null; // Create hidden file inputs for documents and images const fileUpload = document.createElement("input"); fileUpload.type = "file"; fileUpload.accept = ".pdf,.docx,.pptx,.xlsx"; fileUpload.style.display = "none"; document.body.appendChild(fileUpload); const imageUpload = document.createElement("input"); imageUpload.type = "file"; imageUpload.accept = "image/*"; imageUpload.style.display = "none"; document.body.appendChild(imageUpload); // Click on hidden inputs when buttons are clicked fileBtn.addEventListener("click", () => fileUpload.click()); imageBtn.addEventListener("click", () => imageUpload.click()); // Handle document file selection fileUpload.addEventListener("change", (e) => { handleFileSelection(e.target.files[0], "document"); }); // Handle image file selection imageUpload.addEventListener("change", (e) => { handleFileSelection(e.target.files[0], "image"); }); function handleFileSelection(file, type) { if (!file) return; const validDocTypes = [ 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ]; const validImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; const isValid = type === "document" ? validDocTypes.includes(file.type) : validImageTypes.includes(file.type); if (!isValid) { alert(`Please select a valid ${type === "document" ? "document (PDF, DOCX, PPTX, XLSX)" : "image (JPEG, PNG, GIF, WEBP)"}`); if (type === "document") fileUpload.value = ''; else imageUpload.value = ''; return; } selectedFile = file; if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = document.createElement("div"); filePreviewBubble.className = "file-preview-bubble bubble right"; filePreviewBubble.textContent = `${type === "document" ? "šŸ“Ž" : "šŸ–¼ļø"} Selected: ${file.name}`; convo.appendChild(filePreviewBubble); convo.scrollTop = convo.scrollHeight; } function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) { const bubble = document.createElement("div"); bubble.className = `bubble ${sender === "You" ? "right" : "left"}`; const label = document.createElement("div"); label.className = "label"; label.innerText = sender; const message = document.createElement("div"); message.className = "text"; message.style.whiteSpace = "pre-wrap"; if (sender === "You") { let fileLine = fileName ? `šŸ“Ž Selected file: ${fileName}\n` : ""; message.innerText = `${fileLine}ā“ ${text}`; } else { message.style.display = "flex"; message.style.justifyContent = "space-between"; message.style.alignItems = "center"; const msgSpan = document.createElement("span"); msgSpan.innerHTML = text; message.appendChild(msgSpan); if (audioSrc) { const icon = document.createElement("i"); icon.className = "fa-solid fa-volume-high audio-toggle"; icon.title = "Click to mute"; icon.style.cursor = "pointer"; icon.style.fontSize = "18px"; const audio = new Audio(audioSrc); audio.play(); icon.addEventListener("click", () => { if (audio.muted) { audio.currentTime = 0; audio.muted = false; icon.classList.remove("fa-volume-xmark"); icon.classList.add("fa-volume-high"); icon.title = "Click to mute"; audio.play(); } else { audio.muted = true; icon.classList.remove("fa-volume-high"); icon.classList.add("fa-volume-xmark"); icon.title = "Click to unmute"; } }); message.appendChild(icon); } } bubble.appendChild(label); bubble.appendChild(message); convo.appendChild(bubble); convo.scrollTop = convo.scrollHeight; return bubble; } async function sendMessage() { const question = input.value.trim(); if (!question) return; if (!selectedFile) { alert("Please upload a document or image first."); return; } // Remove file preview bubble if (filePreviewBubble) { filePreviewBubble.remove(); filePreviewBubble = null; } // Create user's message bubble createMessageBubble(question, "You", null, selectedFile.name); // Thinking bubble with loader const thinkingBubble = createMessageBubble("Wait, let me think šŸ¤”...
", "Aidan"); const formData = new FormData(); formData.append("question", question); formData.append("file", selectedFile); try { const response = await fetch("/predict", { method: "POST", body: formData }); const result = await response.json(); const answerText = result.answer || "No response."; const audioSrc = result.audio || null; // Update the thinking bubble to show the answer text and remove the loader const message = thinkingBubble.querySelector(".text"); message.innerHTML = answerText; // Replacing with answer // If audio exists, add audio toggle icon if (audioSrc) { const icon = document.createElement("i"); icon.className = "fa-solid fa-volume-high audio-toggle"; icon.title = "Click to mute"; icon.style.cursor = "pointer"; icon.style.fontSize = "18px"; icon.style.marginLeft = "10px"; const audio = new Audio(audioSrc); audio.play(); icon.addEventListener("click", () => { if (audio.muted) { audio.currentTime = 0; audio.muted = false; icon.classList.remove("fa-volume-xmark"); icon.classList.add("fa-volume-high"); icon.title = "Click to mute"; audio.play(); } else { audio.muted = true; icon.classList.remove("fa-volume-high"); icon.classList.add("fa-volume-xmark"); icon.title = "Click to unmute"; } }); message.style.display = "flex"; message.style.justifyContent = "space-between"; message.appendChild(icon); } } catch (err) { const message = thinkingBubble.querySelector(".text"); message.innerText = "āš ļø Aidan had trouble responding."; } input.value = ""; selectedFile = null; } sendBtn.addEventListener("click", sendMessage); input.addEventListener("keydown", (event) => { if (event.key === "Enter") { event.preventDefault(); sendMessage(); } }); const style = document.createElement('style'); style.textContent = ` .loader { display: inline-block; border: 2px solid #f3f3f3; border-top: 2px solid #3b82f6; border-radius: 50%; width: 16px; height: 16px; animation: spin 1s linear infinite; margin-left: 8px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; document.head.appendChild(style); }); */ document.addEventListener("DOMContentLoaded", () => { const convo = document.querySelector(".convo"); const input = document.querySelector(".qt input"); const sendBtn = document.querySelector(".sendingQA"); const fileBtn = document.querySelector(".fa-file"); const imageBtn = document.querySelector(".fa-image"); let selectedFile = null; let filePreviewBubble = null; // Create hidden file inputs for documents and images const fileUpload = document.createElement("input"); fileUpload.type = "file"; fileUpload.accept = ".pdf,.docx,.pptx,.xlsx"; fileUpload.style.display = "none"; document.body.appendChild(fileUpload); const imageUpload = document.createElement("input"); imageUpload.type = "file"; imageUpload.accept = "image/*"; imageUpload.style.display = "none"; document.body.appendChild(imageUpload); // Click on hidden inputs when buttons are clicked fileBtn.addEventListener("click", () => fileUpload.click()); imageBtn.addEventListener("click", () => imageUpload.click()); // Handle document file selection fileUpload.addEventListener("change", (e) => { handleFileSelection(e.target.files[0], "document"); }); // Handle image file selection imageUpload.addEventListener("change", (e) => { handleFileSelection(e.target.files[0], "image"); }); function handleFileSelection(file, type) { if (!file) return; const validDocTypes = [ 'application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ]; const validImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; const isValid = type === "document" ? validDocTypes.includes(file.type) : validImageTypes.includes(file.type); if (!isValid) { alert(`Please select a valid ${type === "document" ? "document (PDF, DOCX, PPTX, XLSX)" : "image (JPEG, PNG, GIF, WEBP)"}`); if (type === "document") fileUpload.value = ''; else imageUpload.value = ''; return; } selectedFile = file; if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = document.createElement("div"); filePreviewBubble.className = "file-preview-bubble bubble right"; filePreviewBubble.style.display = "flex"; filePreviewBubble.style.flexDirection = "column"; filePreviewBubble.style.maxWidth = "50%"; const userQuestion = input.value.trim(); // Only include the question if it was entered if (file.type.startsWith('image/')) { const reader = new FileReader(); reader.onload = (e) => { const img = document.createElement("img"); img.src = e.target.result; img.style.width = "100%"; img.style.height = "200px"; img.style.objectFit = "cover"; img.style.borderRadius = "10px"; img.style.marginBottom = "8px"; const text = document.createElement("span"); text.textContent = `šŸ“Ž Selected image: ${file.name}`; text.style.fontSize = "13px"; // If there's a user question, add the ā“ if (userQuestion) { const question = document.createElement("span"); question.textContent = `\nā“ ${userQuestion}`; question.style.fontSize = "13px"; filePreviewBubble.appendChild(question); } filePreviewBubble.appendChild(img); filePreviewBubble.appendChild(text); convo.appendChild(filePreviewBubble); convo.scrollTop = convo.scrollHeight; }; reader.readAsDataURL(file); } else { const text = document.createElement("span"); text.textContent = `šŸ“Ž Selected file: ${file.name}`; text.style.fontSize = "13px"; // If there's a user question, add the ā“ if (userQuestion) { const question = document.createElement("span"); question.textContent = `\nā“ ${userQuestion}`; question.style.fontSize = "13px"; filePreviewBubble.appendChild(question); } filePreviewBubble.appendChild(text); convo.appendChild(filePreviewBubble); convo.scrollTop = convo.scrollHeight; } } function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null, imageSrc = null) { const bubble = document.createElement("div"); bubble.className = `bubble ${sender === "You" ? "right" : "left"}`; bubble.style.maxWidth = "50%"; const label = document.createElement("div"); label.className = "label"; label.innerText = sender; const message = document.createElement("div"); message.className = "text"; message.style.whiteSpace = "pre-wrap"; const textSpan = document.createElement("span"); textSpan.innerHTML = text; message.appendChild(textSpan); // Display image if available if (imageSrc) { const img = document.createElement("img"); img.src = imageSrc; img.style.width = "100%"; img.style.height = "200px"; img.style.objectFit = "cover"; img.style.borderRadius = "10px"; img.style.marginTop = "8px"; message.appendChild(img); } bubble.appendChild(label); bubble.appendChild(message); convo.appendChild(bubble); convo.scrollTop = convo.scrollHeight; return bubble; } async function sendMessage() { const question = input.value.trim(); if (!question) return; if (!selectedFile) { alert("Please upload a document or image first."); return; } // Remove file preview bubble if (filePreviewBubble) { filePreviewBubble.remove(); filePreviewBubble = null; } // Create user's message bubble createMessageBubble(question, "You", null, selectedFile.name, selectedFile.type.startsWith('image/') ? URL.createObjectURL(selectedFile) : null); // Thinking bubble with loader const thinkingBubble = createMessageBubble("Wait, let me think šŸ¤”...
", "Aidan"); const formData = new FormData(); formData.append("question", question); formData.append("file", selectedFile); try { const response = await fetch("/predict", { method: "POST", body: formData }); const result = await response.json(); const answerText = result.answer || "No response."; const audioSrc = result.audio || null; // Update the thinking bubble to show the answer text and remove the loader const message = thinkingBubble.querySelector(".text"); message.innerHTML = answerText; // If audio exists, add audio toggle icon if (audioSrc) { const icon = document.createElement("i"); icon.className = "fa-solid fa-volume-high audio-toggle"; icon.title = "Click to mute"; icon.style.cursor = "pointer"; icon.style.fontSize = "18px"; icon.style.marginLeft = "10px"; const audio = new Audio(audioSrc); audio.play(); icon.addEventListener("click", () => { if (audio.muted) { audio.currentTime = 0; audio.muted = false; icon.classList.remove("fa-volume-xmark"); icon.classList.add("fa-volume-high"); icon.title = "Click to mute"; audio.play(); } else { audio.muted = true; icon.classList.remove("fa-volume-high"); icon.classList.add("fa-volume-xmark"); icon.title = "Click to unmute"; } }); message.style.display = "flex"; message.style.justifyContent = "space-between"; message.appendChild(icon); } } catch (err) { const message = thinkingBubble.querySelector(".text"); message.innerText = "āš ļø Aidan had trouble responding."; } input.value = ""; selectedFile = null; } sendBtn.addEventListener("click", sendMessage); input.addEventListener("keydown", (event) => { if (event.key === "Enter") { event.preventDefault(); sendMessage(); } }); const style = document.createElement('style'); style.textContent = ` .loader { display: inline-block; border: 2px solid #f3f3f3; border-top: 2px solid #3b82f6; border-radius: 50%; width: 16px; height: 16px; animation: spin 1s linear infinite; margin-left: 8px; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } `; document.head.appendChild(style); });