Spaces:
Running
Running
document.addEventListener("DOMContentLoaded", function () { | |
const convo = document.querySelector(".convo"); | |
const sendBtn = document.querySelector(".sendingQA"); | |
const userInput = document.querySelector(".qt input"); | |
const imageIcon = document.querySelector(".fa-image"); | |
const fileIcon = document.querySelector(".fa-file"); | |
let selectedFile = null; | |
let filePreviewDiv = null; | |
let autoScroll = true; | |
convo.addEventListener("scroll", () => { | |
const threshold = 150; | |
autoScroll = convo.scrollHeight - convo.scrollTop - convo.clientHeight < threshold; | |
}); | |
function scrollToBottom() { | |
if (autoScroll) { | |
convo.scrollTo({ top: convo.scrollHeight, behavior: "smooth" }); | |
} | |
} | |
function createMessageBubble(text, sender, audioUrl = null, fileName = null) { | |
const bubble = document.createElement("div"); | |
bubble.classList.add("bubble", sender === "You" ? "right" : "left"); | |
const label = document.createElement("div"); | |
label.className = "label"; | |
label.innerText = sender; | |
const textDiv = document.createElement("div"); | |
textDiv.className = "text"; | |
textDiv.innerText = text; | |
bubble.appendChild(label); | |
bubble.appendChild(textDiv); | |
if (fileName) { | |
const fileLine = document.createElement("div"); | |
fileLine.style.fontSize = "0.85rem"; | |
fileLine.style.color = "#555"; | |
fileLine.innerHTML = `π <strong>File:</strong> ${fileName}`; | |
bubble.appendChild(fileLine); | |
} | |
if (audioUrl) { | |
const audio = document.createElement("audio"); | |
audio.controls = true; | |
audio.autoplay = true; | |
audio.src = audioUrl; | |
audio.style.marginTop = "10px"; | |
bubble.appendChild(audio); | |
} | |
convo.appendChild(bubble); | |
scrollToBottom(); | |
return bubble; | |
} | |
function showFilePreview(filename, icon = "π") { | |
if (filePreviewDiv) filePreviewDiv.remove(); | |
filePreviewDiv = document.createElement("div"); | |
filePreviewDiv.className = "file-preview"; | |
filePreviewDiv.innerHTML = `${icon} <strong>Selected:</strong> ${filename}`; | |
const qtContainer = document.querySelector(".qt"); | |
qtContainer.parentElement.insertBefore(filePreviewDiv, qtContainer); | |
} | |
sendBtn.addEventListener("click", async () => { | |
const question = userInput.value.trim(); | |
if (!question) return; | |
if (!selectedFile) { | |
alert("Please upload a file before asking a question."); | |
return; | |
} | |
// Remove preview | |
if (filePreviewDiv) filePreviewDiv.remove(); | |
// Show user message + file | |
createMessageBubble(question, "You", null, selectedFile.name); | |
// Show thinking placeholder | |
const thinkingBubble = createMessageBubble("Chris is thinking...", "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(); | |
// Replace thinking bubble with actual answer | |
thinkingBubble.querySelector(".text").innerText = result.answer || "No response received."; | |
if (result.audio) { | |
const audio = document.createElement("audio"); | |
audio.controls = true; | |
audio.autoplay = true; | |
audio.src = result.audio; | |
audio.style.marginTop = "10px"; | |
thinkingBubble.appendChild(audio); | |
} | |
} catch (err) { | |
thinkingBubble.querySelector(".text").innerText = "β οΈ Chris had trouble connecting."; | |
} | |
scrollToBottom(); | |
userInput.value = ""; | |
selectedFile = null; | |
}); | |
// File icon handlers | |
imageIcon.addEventListener("click", () => { | |
const input = document.createElement("input"); | |
input.type = "file"; | |
input.accept = "image/*"; | |
input.onchange = () => { | |
selectedFile = input.files[0]; | |
if (selectedFile) showFilePreview(selectedFile.name, "πΌοΈ"); | |
}; | |
input.click(); | |
}); | |
fileIcon.addEventListener("click", () => { | |
const input = document.createElement("input"); | |
input.type = "file"; | |
input.accept = ".pdf,.docx,.pptx,.xlsx"; | |
input.onchange = () => { | |
selectedFile = input.files[0]; | |
if (selectedFile) showFilePreview(selectedFile.name, "π"); | |
}; | |
input.click(); | |
}); | |
}); | |