Spaces:
Running
Running
Update static/application.js
Browse files- static/application.js +59 -17
static/application.js
CHANGED
@@ -6,9 +6,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
6 |
const fileIcon = document.querySelector(".fa-file");
|
7 |
|
8 |
let selectedFile = null;
|
|
|
9 |
let autoScroll = true;
|
10 |
|
11 |
-
// Enable auto-scroll unless user scrolls up
|
12 |
convo.addEventListener("scroll", () => {
|
13 |
const threshold = 150;
|
14 |
autoScroll = convo.scrollHeight - convo.scrollTop - convo.clientHeight < threshold;
|
@@ -20,7 +20,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
20 |
}
|
21 |
}
|
22 |
|
23 |
-
function createMessageBubble(text, sender, audioUrl = null) {
|
24 |
const bubble = document.createElement("div");
|
25 |
bubble.classList.add("bubble", sender === "You" ? "right" : "left");
|
26 |
|
@@ -28,12 +28,20 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
28 |
label.className = "label";
|
29 |
label.innerText = sender;
|
30 |
|
31 |
-
const
|
32 |
-
|
33 |
-
|
34 |
|
35 |
bubble.appendChild(label);
|
36 |
-
bubble.appendChild(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
|
38 |
if (audioUrl) {
|
39 |
const audio = document.createElement("audio");
|
@@ -46,6 +54,20 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
46 |
|
47 |
convo.appendChild(bubble);
|
48 |
scrollToBottom();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
sendBtn.addEventListener("click", async () => {
|
@@ -53,11 +75,18 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
53 |
if (!question) return;
|
54 |
|
55 |
if (!selectedFile) {
|
56 |
-
alert("Please upload a file
|
57 |
return;
|
58 |
}
|
59 |
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
|
62 |
const formData = new FormData();
|
63 |
formData.append("question", question);
|
@@ -66,29 +95,39 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
66 |
try {
|
67 |
const response = await fetch("/predict", {
|
68 |
method: "POST",
|
69 |
-
body: formData
|
70 |
});
|
|
|
71 |
const result = await response.json();
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
|
|
78 |
} catch (err) {
|
79 |
-
|
80 |
}
|
81 |
|
82 |
userInput.value = "";
|
83 |
selectedFile = null;
|
84 |
});
|
85 |
|
86 |
-
// File
|
87 |
imageIcon.addEventListener("click", () => {
|
88 |
const input = document.createElement("input");
|
89 |
input.type = "file";
|
90 |
input.accept = "image/*";
|
91 |
-
input.onchange = () =>
|
|
|
|
|
|
|
92 |
input.click();
|
93 |
});
|
94 |
|
@@ -96,7 +135,10 @@ document.addEventListener("DOMContentLoaded", function () {
|
|
96 |
const input = document.createElement("input");
|
97 |
input.type = "file";
|
98 |
input.accept = ".pdf,.docx,.pptx,.xlsx";
|
99 |
-
input.onchange = () =>
|
|
|
|
|
|
|
100 |
input.click();
|
101 |
});
|
102 |
});
|
|
|
6 |
const fileIcon = document.querySelector(".fa-file");
|
7 |
|
8 |
let selectedFile = null;
|
9 |
+
let filePreviewDiv = null;
|
10 |
let autoScroll = true;
|
11 |
|
|
|
12 |
convo.addEventListener("scroll", () => {
|
13 |
const threshold = 150;
|
14 |
autoScroll = convo.scrollHeight - convo.scrollTop - convo.clientHeight < threshold;
|
|
|
20 |
}
|
21 |
}
|
22 |
|
23 |
+
function createMessageBubble(text, sender, audioUrl = null, fileName = null) {
|
24 |
const bubble = document.createElement("div");
|
25 |
bubble.classList.add("bubble", sender === "You" ? "right" : "left");
|
26 |
|
|
|
28 |
label.className = "label";
|
29 |
label.innerText = sender;
|
30 |
|
31 |
+
const textDiv = document.createElement("div");
|
32 |
+
textDiv.className = "text";
|
33 |
+
textDiv.innerText = text;
|
34 |
|
35 |
bubble.appendChild(label);
|
36 |
+
bubble.appendChild(textDiv);
|
37 |
+
|
38 |
+
if (fileName) {
|
39 |
+
const fileLine = document.createElement("div");
|
40 |
+
fileLine.style.fontSize = "0.85rem";
|
41 |
+
fileLine.style.color = "#555";
|
42 |
+
fileLine.innerHTML = `π <strong>File:</strong> ${fileName}`;
|
43 |
+
bubble.appendChild(fileLine);
|
44 |
+
}
|
45 |
|
46 |
if (audioUrl) {
|
47 |
const audio = document.createElement("audio");
|
|
|
54 |
|
55 |
convo.appendChild(bubble);
|
56 |
scrollToBottom();
|
57 |
+
return bubble;
|
58 |
+
}
|
59 |
+
|
60 |
+
function showFilePreview(filename, icon = "π") {
|
61 |
+
if (filePreviewDiv) filePreviewDiv.remove();
|
62 |
+
|
63 |
+
filePreviewDiv = document.createElement("div");
|
64 |
+
filePreviewDiv.classList.add("bubble", "right");
|
65 |
+
filePreviewDiv.innerHTML = `
|
66 |
+
<div class="label">You</div>
|
67 |
+
<div class="text">${icon} <strong>Selected:</strong> ${filename}</div>
|
68 |
+
`;
|
69 |
+
convo.appendChild(filePreviewDiv);
|
70 |
+
scrollToBottom();
|
71 |
}
|
72 |
|
73 |
sendBtn.addEventListener("click", async () => {
|
|
|
75 |
if (!question) return;
|
76 |
|
77 |
if (!selectedFile) {
|
78 |
+
alert("Please upload a file before asking a question.");
|
79 |
return;
|
80 |
}
|
81 |
|
82 |
+
// Remove preview
|
83 |
+
if (filePreviewDiv) filePreviewDiv.remove();
|
84 |
+
|
85 |
+
// Show user message + file
|
86 |
+
createMessageBubble(question, "You", null, selectedFile.name);
|
87 |
+
|
88 |
+
// Show thinking placeholder
|
89 |
+
const thinkingBubble = createMessageBubble("Chris is thinking...", "Chris");
|
90 |
|
91 |
const formData = new FormData();
|
92 |
formData.append("question", question);
|
|
|
95 |
try {
|
96 |
const response = await fetch("/predict", {
|
97 |
method: "POST",
|
98 |
+
body: formData
|
99 |
});
|
100 |
+
|
101 |
const result = await response.json();
|
102 |
|
103 |
+
// Replace thinking bubble with actual answer
|
104 |
+
thinkingBubble.querySelector(".text").innerText = result.answer || "No response received.";
|
105 |
+
if (result.audio) {
|
106 |
+
const audio = document.createElement("audio");
|
107 |
+
audio.controls = true;
|
108 |
+
audio.autoplay = true;
|
109 |
+
audio.src = result.audio;
|
110 |
+
audio.style.marginTop = "10px";
|
111 |
+
thinkingBubble.appendChild(audio);
|
112 |
}
|
113 |
+
|
114 |
} catch (err) {
|
115 |
+
thinkingBubble.querySelector(".text").innerText = "β οΈ Chris had trouble connecting.";
|
116 |
}
|
117 |
|
118 |
userInput.value = "";
|
119 |
selectedFile = null;
|
120 |
});
|
121 |
|
122 |
+
// File icon handlers
|
123 |
imageIcon.addEventListener("click", () => {
|
124 |
const input = document.createElement("input");
|
125 |
input.type = "file";
|
126 |
input.accept = "image/*";
|
127 |
+
input.onchange = () => {
|
128 |
+
selectedFile = input.files[0];
|
129 |
+
if (selectedFile) showFilePreview(selectedFile.name, "πΌοΈ");
|
130 |
+
};
|
131 |
input.click();
|
132 |
});
|
133 |
|
|
|
135 |
const input = document.createElement("input");
|
136 |
input.type = "file";
|
137 |
input.accept = ".pdf,.docx,.pptx,.xlsx";
|
138 |
+
input.onchange = () => {
|
139 |
+
selectedFile = input.files[0];
|
140 |
+
if (selectedFile) showFilePreview(selectedFile.name, "π");
|
141 |
+
};
|
142 |
input.click();
|
143 |
});
|
144 |
});
|