Spaces:
Running
Running
/*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 = ""; | |
}); | |
}); | |