/*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; // Hidden file input const fileInput = document.createElement("input"); fileInput.type = "file"; fileInput.accept = ".pdf,.docx,.pptx,.xlsx,image/*"; fileInput.style.display = "none"; document.body.appendChild(fileInput); fileBtn.addEventListener("click", () => fileInput.click()); imageBtn.addEventListener("click", () => fileInput.click()); fileInput.addEventListener("change", () => { const file = fileInput.files[0]; if (file) { selectedFile = file; if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = document.createElement("div"); filePreviewBubble.className = "file-preview-bubble bubble right"; filePreviewBubble.textContent = `📎 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"; // preserve line breaks 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.innerText = 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; // ⏮️ Rewind to beginning audio.muted = false; audio.play(); // 🔊 Play from start icon.classList.replace("fa-volume-xmark", "fa-volume-high"); icon.title = "Click to mute"; } else { audio.muted = true; icon.classList.replace("fa-volume-high", "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; } sendBtn.addEventListener("click", async () => { 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; } // User message with file info createMessageBubble(question, "You", null, selectedFile.name); // Chris is thinking... const thinkingBubble = createMessageBubble("Wait , Let me think 🤔...", "Chris"); 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; // Replace "Let me think..." with actual answer const message = thinkingBubble.querySelector(".text"); message.innerText = answerText; 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", () => { audio.muted = !audio.muted; icon.classList.toggle("fa-volume-high", !audio.muted); icon.classList.toggle("fa-volume-xmark", audio.muted); icon.title = audio.muted ? "Click to unmute" : "Click to mute"; }); message.style.display = "flex"; message.style.justifyContent = "space-between"; message.appendChild(icon); } } catch (err) { const message = thinkingBubble.querySelector(".text"); message.innerText = "⚠️ Chris had trouble responding."; } input.value = ""; selectedFile = null; }); }); */ 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 a hidden input const fileInput = document.createElement("input"); fileInput.type = "file"; fileInput.style.display = "none"; document.body.appendChild(fileInput); // Choose document fileBtn.addEventListener("click", () => { fileInput.value = ""; // ✅ allow selecting same file again fileInput.accept = ".pdf,.docx,.pptx,.xlsx"; fileInput.click(); }); // Choose image imageBtn.addEventListener("click", () => { fileInput.value = ""; fileInput.accept = "image/*"; fileInput.click(); }); // Handle file selection fileInput.addEventListener("change", () => { const file = fileInput.files[0]; if (file) { selectedFile = file; if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = document.createElement("div"); filePreviewBubble.className = "file-preview-bubble bubble right"; filePreviewBubble.textContent = `📎 Selected: ${file.name}`; convo.appendChild(filePreviewBubble); convo.scrollTop = convo.scrollHeight; } }); // Drag & drop support convo.addEventListener("dragover", (e) => { e.preventDefault(); convo.classList.add("drag-over"); }); convo.addEventListener("dragleave", () => { convo.classList.remove("drag-over"); }); convo.addEventListener("drop", (e) => { e.preventDefault(); convo.classList.remove("drag-over"); const file = e.dataTransfer.files[0]; if (file) { selectedFile = file; if (filePreviewBubble) filePreviewBubble.remove(); filePreviewBubble = document.createElement("div"); filePreviewBubble.className = "file-preview-bubble bubble right"; filePreviewBubble.textContent = `📎 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") { const 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.innerText = 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"; let currentAudio = new Audio(audioSrc); currentAudio.play(); let isMuted = false; icon.addEventListener("click", () => { if (isMuted) { currentAudio = new Audio(audioSrc); // restart currentAudio.play(); isMuted = false; icon.classList.replace("fa-volume-xmark", "fa-volume-high"); icon.title = "Click to mute"; } else { currentAudio.pause(); isMuted = true; icon.classList.replace("fa-volume-high", "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; } sendBtn.addEventListener("click", async () => { const question = input.value.trim(); if (!question) return; if (!selectedFile) { alert("Please upload a document or image first."); return; } if (filePreviewBubble) { filePreviewBubble.remove(); filePreviewBubble = null; } createMessageBubble(question, "You", null, selectedFile.name); const thinkingBubble = createMessageBubble("🧠 Let me think...", "Chris"); const wrappedFile = new File([selectedFile], selectedFile.name, { type: selectedFile.type, }); const formData = new FormData(); formData.append("question", question); formData.append("file", wrappedFile); 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; const message = thinkingBubble.querySelector(".text"); message.innerText = answerText; 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"; let currentAudio = new Audio(audioSrc); currentAudio.play(); let isMuted = false; icon.addEventListener("click", () => { if (isMuted) { currentAudio = new Audio(audioSrc); // restart currentAudio.play(); isMuted = false; icon.classList.replace("fa-volume-xmark", "fa-volume-high"); icon.title = "Click to mute"; } else { currentAudio.pause(); isMuted = true; icon.classList.replace("fa-volume-high", "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 = "⚠️ Chris had trouble responding."; } input.value = ""; }); });