Spaces:
Running
Running
Update static/application.js
Browse files- static/application.js +199 -7
static/application.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
document.addEventListener("DOMContentLoaded", () => {
|
2 |
const convo = document.querySelector(".convo");
|
3 |
const input = document.querySelector(".qt input");
|
4 |
const sendBtn = document.querySelector(".sendingQA");
|
@@ -66,12 +66,19 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
66 |
const audio = new Audio(audioSrc);
|
67 |
audio.play();
|
68 |
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
message.appendChild(icon);
|
77 |
}
|
@@ -153,4 +160,189 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
153 |
input.value = "";
|
154 |
selectedFile = null;
|
155 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
});
|
|
|
1 |
+
/*document.addEventListener("DOMContentLoaded", () => {
|
2 |
const convo = document.querySelector(".convo");
|
3 |
const input = document.querySelector(".qt input");
|
4 |
const sendBtn = document.querySelector(".sendingQA");
|
|
|
66 |
const audio = new Audio(audioSrc);
|
67 |
audio.play();
|
68 |
|
69 |
+
icon.addEventListener("click", () => {
|
70 |
+
if (audio.muted) {
|
71 |
+
audio.currentTime = 0; // โฎ๏ธ Rewind to beginning
|
72 |
+
audio.muted = false;
|
73 |
+
audio.play(); // ๐ Play from start
|
74 |
+
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
75 |
+
icon.title = "Click to mute";
|
76 |
+
} else {
|
77 |
+
audio.muted = true;
|
78 |
+
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
79 |
+
icon.title = "Click to unmute";
|
80 |
+
}
|
81 |
+
});
|
82 |
|
83 |
message.appendChild(icon);
|
84 |
}
|
|
|
160 |
input.value = "";
|
161 |
selectedFile = null;
|
162 |
});
|
163 |
+
}); */
|
164 |
+
document.addEventListener("DOMContentLoaded", () => {
|
165 |
+
const convo = document.querySelector(".convo");
|
166 |
+
const input = document.querySelector(".qt input");
|
167 |
+
const sendBtn = document.querySelector(".sendingQA");
|
168 |
+
const fileBtn = document.querySelector(".fa-file");
|
169 |
+
const imageBtn = document.querySelector(".fa-image");
|
170 |
+
|
171 |
+
let selectedFile = null;
|
172 |
+
let filePreviewBubble = null;
|
173 |
+
|
174 |
+
// Hidden file input
|
175 |
+
const fileInput = document.createElement("input");
|
176 |
+
fileInput.type = "file";
|
177 |
+
fileInput.style.display = "none";
|
178 |
+
document.body.appendChild(fileInput);
|
179 |
+
|
180 |
+
// Trigger file input (DOCS)
|
181 |
+
fileBtn.addEventListener("click", () => {
|
182 |
+
fileInput.value = ""; // โ
allow re-selecting same file
|
183 |
+
fileInput.accept = ".pdf,.docx,.pptx,.xlsx";
|
184 |
+
fileInput.click();
|
185 |
+
});
|
186 |
+
|
187 |
+
// Trigger file input (IMAGES)
|
188 |
+
imageBtn.addEventListener("click", () => {
|
189 |
+
fileInput.value = ""; // โ
allow re-selecting same image
|
190 |
+
fileInput.accept = "image/*";
|
191 |
+
fileInput.click();
|
192 |
+
});
|
193 |
+
|
194 |
+
// When file selected
|
195 |
+
fileInput.addEventListener("change", () => {
|
196 |
+
const file = fileInput.files[0];
|
197 |
+
if (file) {
|
198 |
+
selectedFile = file;
|
199 |
+
|
200 |
+
// Replace preview bubble
|
201 |
+
if (filePreviewBubble) filePreviewBubble.remove();
|
202 |
+
|
203 |
+
filePreviewBubble = document.createElement("div");
|
204 |
+
filePreviewBubble.className = "file-preview-bubble bubble right";
|
205 |
+
filePreviewBubble.textContent = `๐ Selected: ${file.name}`;
|
206 |
+
convo.appendChild(filePreviewBubble);
|
207 |
+
convo.scrollTop = convo.scrollHeight;
|
208 |
+
}
|
209 |
+
});
|
210 |
+
|
211 |
+
function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
|
212 |
+
const bubble = document.createElement("div");
|
213 |
+
bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
|
214 |
+
|
215 |
+
const label = document.createElement("div");
|
216 |
+
label.className = "label";
|
217 |
+
label.innerText = sender;
|
218 |
+
|
219 |
+
const message = document.createElement("div");
|
220 |
+
message.className = "text";
|
221 |
+
message.style.whiteSpace = "pre-wrap";
|
222 |
+
|
223 |
+
// User message with file
|
224 |
+
if (sender === "You") {
|
225 |
+
const fileLine = fileName ? `๐ Selected file: ${fileName}\n` : "";
|
226 |
+
message.innerText = `${fileLine}โ ${text}`;
|
227 |
+
} else {
|
228 |
+
message.style.display = "flex";
|
229 |
+
message.style.justifyContent = "space-between";
|
230 |
+
message.style.alignItems = "center";
|
231 |
+
|
232 |
+
const msgSpan = document.createElement("span");
|
233 |
+
msgSpan.innerText = text;
|
234 |
+
message.appendChild(msgSpan);
|
235 |
+
|
236 |
+
// Chris answer with speaker
|
237 |
+
if (audioSrc) {
|
238 |
+
const icon = document.createElement("i");
|
239 |
+
icon.className = "fa-solid fa-volume-high audio-toggle";
|
240 |
+
icon.title = "Click to mute";
|
241 |
+
icon.style.cursor = "pointer";
|
242 |
+
icon.style.fontSize = "18px";
|
243 |
+
|
244 |
+
const audio = new Audio(audioSrc);
|
245 |
+
audio.play();
|
246 |
+
|
247 |
+
icon.addEventListener("click", () => {
|
248 |
+
if (audio.muted) {
|
249 |
+
audio.currentTime = 0; // restart from beginning
|
250 |
+
audio.muted = false;
|
251 |
+
audio.play();
|
252 |
+
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
253 |
+
icon.title = "Click to mute";
|
254 |
+
} else {
|
255 |
+
audio.muted = true;
|
256 |
+
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
257 |
+
icon.title = "Click to unmute";
|
258 |
+
}
|
259 |
+
});
|
260 |
+
|
261 |
+
message.appendChild(icon);
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
bubble.appendChild(label);
|
266 |
+
bubble.appendChild(message);
|
267 |
+
convo.appendChild(bubble);
|
268 |
+
convo.scrollTop = convo.scrollHeight;
|
269 |
+
return bubble;
|
270 |
+
}
|
271 |
+
|
272 |
+
sendBtn.addEventListener("click", async () => {
|
273 |
+
const question = input.value.trim();
|
274 |
+
if (!question) return;
|
275 |
+
|
276 |
+
if (!selectedFile) {
|
277 |
+
alert("Please upload a document or image first.");
|
278 |
+
return;
|
279 |
+
}
|
280 |
+
|
281 |
+
if (filePreviewBubble) {
|
282 |
+
filePreviewBubble.remove();
|
283 |
+
filePreviewBubble = null;
|
284 |
+
}
|
285 |
+
|
286 |
+
// User message
|
287 |
+
createMessageBubble(question, "You", null, selectedFile.name);
|
288 |
+
|
289 |
+
// Thinking bubble
|
290 |
+
const thinkingBubble = createMessageBubble("๐ง Let me think...", "Chris");
|
291 |
+
|
292 |
+
const formData = new FormData();
|
293 |
+
formData.append("question", question);
|
294 |
+
formData.append("file", selectedFile);
|
295 |
+
|
296 |
+
try {
|
297 |
+
const response = await fetch("/predict", {
|
298 |
+
method: "POST",
|
299 |
+
body: formData
|
300 |
+
});
|
301 |
+
|
302 |
+
const result = await response.json();
|
303 |
+
const answerText = result.answer || "No response.";
|
304 |
+
const audioSrc = result.audio || null;
|
305 |
+
|
306 |
+
const message = thinkingBubble.querySelector(".text");
|
307 |
+
message.innerText = answerText;
|
308 |
+
|
309 |
+
// Re-add speaker icon if audio
|
310 |
+
if (audioSrc) {
|
311 |
+
const icon = document.createElement("i");
|
312 |
+
icon.className = "fa-solid fa-volume-high audio-toggle";
|
313 |
+
icon.title = "Click to mute";
|
314 |
+
icon.style.cursor = "pointer";
|
315 |
+
icon.style.fontSize = "18px";
|
316 |
+
icon.style.marginLeft = "10px";
|
317 |
+
|
318 |
+
const audio = new Audio(audioSrc);
|
319 |
+
audio.play();
|
320 |
+
|
321 |
+
icon.addEventListener("click", () => {
|
322 |
+
if (audio.muted) {
|
323 |
+
audio.currentTime = 0;
|
324 |
+
audio.muted = false;
|
325 |
+
audio.play();
|
326 |
+
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
327 |
+
icon.title = "Click to mute";
|
328 |
+
} else {
|
329 |
+
audio.muted = true;
|
330 |
+
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
331 |
+
icon.title = "Click to unmute";
|
332 |
+
}
|
333 |
+
});
|
334 |
+
|
335 |
+
message.style.display = "flex";
|
336 |
+
message.style.justifyContent = "space-between";
|
337 |
+
message.appendChild(icon);
|
338 |
+
}
|
339 |
+
|
340 |
+
} catch (err) {
|
341 |
+
const message = thinkingBubble.querySelector(".text");
|
342 |
+
message.innerText = "โ ๏ธ Chris had trouble responding.";
|
343 |
+
}
|
344 |
+
|
345 |
+
input.value = "";
|
346 |
+
// Do NOT clear selectedFile so user can ask follow-up questions
|
347 |
+
});
|
348 |
});
|