Spaces:
Running
Running
Update static/application.js
Browse files- static/application.js +44 -57
static/application.js
CHANGED
@@ -1,30 +1,34 @@
|
|
1 |
document.addEventListener("DOMContentLoaded", () => {
|
2 |
const convo = document.querySelector(".convo");
|
3 |
-
const input = document.querySelector("
|
4 |
const sendBtn = document.querySelector(".sendingQA");
|
5 |
const fileBtn = document.querySelector(".fa-file");
|
6 |
const imageBtn = document.querySelector(".fa-image");
|
|
|
7 |
let selectedFile = null;
|
8 |
let filePreviewBubble = null;
|
9 |
|
10 |
-
// Hidden input
|
11 |
const fileInput = document.createElement("input");
|
12 |
fileInput.type = "file";
|
13 |
fileInput.style.display = "none";
|
14 |
document.body.appendChild(fileInput);
|
15 |
|
|
|
16 |
fileBtn.addEventListener("click", () => {
|
17 |
fileInput.value = "";
|
18 |
fileInput.accept = ".pdf,.docx,.pptx,.xlsx";
|
19 |
fileInput.click();
|
20 |
});
|
21 |
|
|
|
22 |
imageBtn.addEventListener("click", () => {
|
23 |
fileInput.value = "";
|
24 |
fileInput.accept = "image/*";
|
25 |
fileInput.click();
|
26 |
});
|
27 |
|
|
|
28 |
fileInput.addEventListener("change", () => {
|
29 |
const file = fileInput.files[0];
|
30 |
if (file) {
|
@@ -33,13 +37,13 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
33 |
|
34 |
filePreviewBubble = document.createElement("div");
|
35 |
filePreviewBubble.className = "file-preview-bubble bubble right";
|
36 |
-
filePreviewBubble.textContent =
|
37 |
convo.appendChild(filePreviewBubble);
|
38 |
convo.scrollTop = convo.scrollHeight;
|
39 |
}
|
40 |
});
|
41 |
|
42 |
-
// Drag & drop
|
43 |
convo.addEventListener("dragover", (e) => {
|
44 |
e.preventDefault();
|
45 |
convo.classList.add("drag-over");
|
@@ -61,23 +65,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
61 |
|
62 |
filePreviewBubble = document.createElement("div");
|
63 |
filePreviewBubble.className = "file-preview-bubble bubble right";
|
64 |
-
filePreviewBubble.textContent =
|
65 |
convo.appendChild(filePreviewBubble);
|
66 |
convo.scrollTop = convo.scrollHeight;
|
67 |
}
|
68 |
});
|
69 |
|
70 |
-
// Reset chat
|
71 |
-
resetBtn.addEventListener("click", () => {
|
72 |
-
convo.innerHTML = "";
|
73 |
-
selectedFile = null;
|
74 |
-
filePreviewBubble = null;
|
75 |
-
input.value = "";
|
76 |
-
});
|
77 |
-
|
78 |
function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
|
79 |
const bubble = document.createElement("div");
|
80 |
-
bubble.className =
|
81 |
|
82 |
const label = document.createElement("div");
|
83 |
label.className = "label";
|
@@ -88,8 +84,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
88 |
message.style.whiteSpace = "pre-wrap";
|
89 |
|
90 |
if (sender === "You") {
|
91 |
-
const fileLine = fileName ?
|
92 |
-
message.innerText =
|
93 |
} else {
|
94 |
message.style.display = "flex";
|
95 |
message.style.justifyContent = "space-between";
|
@@ -104,31 +100,27 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
104 |
icon.className = "fa-solid fa-volume-high audio-toggle";
|
105 |
icon.title = "Click to mute";
|
106 |
icon.style.cursor = "pointer";
|
107 |
-
icon.style.fontSize = "
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
let isMuted = false;
|
113 |
-
let audio = new Audio(audioSrc);
|
114 |
-
audio.play();
|
115 |
-
|
116 |
-
icon.addEventListener("click", () => {
|
117 |
-
if (isMuted) {
|
118 |
-
// Recreate audio to force replay
|
119 |
-
audio = new Audio(audioSrc);
|
120 |
-
audio.play();
|
121 |
-
isMuted = false;
|
122 |
-
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
123 |
-
icon.title = "Click to mute";
|
124 |
-
} else {
|
125 |
-
audio.pause();
|
126 |
-
isMuted = true;
|
127 |
-
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
128 |
-
icon.title = "Click to unmute";
|
129 |
-
}
|
130 |
-
});
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
133 |
message.appendChild(icon);
|
134 |
}
|
@@ -141,8 +133,8 @@ icon.addEventListener("click", () => {
|
|
141 |
return bubble;
|
142 |
}
|
143 |
|
|
|
144 |
sendBtn.addEventListener("click", async () => {
|
145 |
-
input.value = "";
|
146 |
const question = input.value.trim();
|
147 |
if (!question) return;
|
148 |
|
@@ -157,16 +149,11 @@ icon.addEventListener("click", () => {
|
|
157 |
}
|
158 |
|
159 |
createMessageBubble(question, "You", null, selectedFile.name);
|
160 |
-
const thinkingBubble = createMessageBubble("
|
161 |
-
|
162 |
-
// Rewrap file if needed (for reuse in FormData)
|
163 |
-
const wrappedFile = new File([selectedFile], selectedFile.name, {
|
164 |
-
type: selectedFile.type,
|
165 |
-
});
|
166 |
|
167 |
const formData = new FormData();
|
168 |
formData.append("question", question);
|
169 |
-
formData.append("file",
|
170 |
|
171 |
try {
|
172 |
const response = await fetch("/predict", {
|
@@ -189,18 +176,20 @@ icon.addEventListener("click", () => {
|
|
189 |
icon.style.fontSize = "18px";
|
190 |
icon.style.marginLeft = "10px";
|
191 |
|
192 |
-
|
193 |
-
|
194 |
|
|
|
195 |
icon.addEventListener("click", () => {
|
196 |
-
if (
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
201 |
icon.title = "Click to mute";
|
202 |
} else {
|
203 |
-
|
|
|
204 |
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
205 |
icon.title = "Click to unmute";
|
206 |
}
|
@@ -210,18 +199,16 @@ icon.addEventListener("click", () => {
|
|
210 |
message.style.justifyContent = "space-between";
|
211 |
message.appendChild(icon);
|
212 |
}
|
213 |
-
|
214 |
} catch (err) {
|
215 |
const message = thinkingBubble.querySelector(".text");
|
216 |
message.innerText = "β οΈ Chris had trouble responding.";
|
217 |
}
|
218 |
|
219 |
-
|
220 |
});
|
221 |
});
|
222 |
|
223 |
|
224 |
-
|
225 |
/*
|
226 |
document.addEventListener("DOMContentLoaded", () => {
|
227 |
const convo = document.querySelector(".convo");
|
|
|
1 |
document.addEventListener("DOMContentLoaded", () => {
|
2 |
const convo = document.querySelector(".convo");
|
3 |
+
const input = document.querySelector("#questionInput");
|
4 |
const sendBtn = document.querySelector(".sendingQA");
|
5 |
const fileBtn = document.querySelector(".fa-file");
|
6 |
const imageBtn = document.querySelector(".fa-image");
|
7 |
+
|
8 |
let selectedFile = null;
|
9 |
let filePreviewBubble = null;
|
10 |
|
11 |
+
// Hidden file input
|
12 |
const fileInput = document.createElement("input");
|
13 |
fileInput.type = "file";
|
14 |
fileInput.style.display = "none";
|
15 |
document.body.appendChild(fileInput);
|
16 |
|
17 |
+
// π Handle document icon click
|
18 |
fileBtn.addEventListener("click", () => {
|
19 |
fileInput.value = "";
|
20 |
fileInput.accept = ".pdf,.docx,.pptx,.xlsx";
|
21 |
fileInput.click();
|
22 |
});
|
23 |
|
24 |
+
// πΌοΈ Handle image icon click
|
25 |
imageBtn.addEventListener("click", () => {
|
26 |
fileInput.value = "";
|
27 |
fileInput.accept = "image/*";
|
28 |
fileInput.click();
|
29 |
});
|
30 |
|
31 |
+
// When file is selected
|
32 |
fileInput.addEventListener("change", () => {
|
33 |
const file = fileInput.files[0];
|
34 |
if (file) {
|
|
|
37 |
|
38 |
filePreviewBubble = document.createElement("div");
|
39 |
filePreviewBubble.className = "file-preview-bubble bubble right";
|
40 |
+
filePreviewBubble.textContent = π Selected: ${file.name};
|
41 |
convo.appendChild(filePreviewBubble);
|
42 |
convo.scrollTop = convo.scrollHeight;
|
43 |
}
|
44 |
});
|
45 |
|
46 |
+
// π±οΈ Drag & drop file support
|
47 |
convo.addEventListener("dragover", (e) => {
|
48 |
e.preventDefault();
|
49 |
convo.classList.add("drag-over");
|
|
|
65 |
|
66 |
filePreviewBubble = document.createElement("div");
|
67 |
filePreviewBubble.className = "file-preview-bubble bubble right";
|
68 |
+
filePreviewBubble.textContent = π Selected: ${file.name};
|
69 |
convo.appendChild(filePreviewBubble);
|
70 |
convo.scrollTop = convo.scrollHeight;
|
71 |
}
|
72 |
});
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
|
75 |
const bubble = document.createElement("div");
|
76 |
+
bubble.className = bubble ${sender === "You" ? "right" : "left"};
|
77 |
|
78 |
const label = document.createElement("div");
|
79 |
label.className = "label";
|
|
|
84 |
message.style.whiteSpace = "pre-wrap";
|
85 |
|
86 |
if (sender === "You") {
|
87 |
+
const fileLine = fileName ? π Selected file: ${fileName}\n : "";
|
88 |
+
message.innerText = ${fileLine}β ${text};
|
89 |
} else {
|
90 |
message.style.display = "flex";
|
91 |
message.style.justifyContent = "space-between";
|
|
|
100 |
icon.className = "fa-solid fa-volume-high audio-toggle";
|
101 |
icon.title = "Click to mute";
|
102 |
icon.style.cursor = "pointer";
|
103 |
+
icon.style.fontSize = "20px";
|
104 |
+
icon.style.marginLeft = "40px";
|
105 |
|
106 |
+
let currentAudio = new Audio(audioSrc);
|
107 |
+
currentAudio.play();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
+
let isMuted = false;
|
110 |
+
icon.addEventListener("click", () => {
|
111 |
+
if (isMuted) {
|
112 |
+
currentAudio = new Audio(audioSrc);
|
113 |
+
currentAudio.play();
|
114 |
+
isMuted = false;
|
115 |
+
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
116 |
+
icon.title = "Click to mute";
|
117 |
+
} else {
|
118 |
+
currentAudio.pause();
|
119 |
+
isMuted = true;
|
120 |
+
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
121 |
+
icon.title = "Click to unmute";
|
122 |
+
}
|
123 |
+
});
|
124 |
|
125 |
message.appendChild(icon);
|
126 |
}
|
|
|
133 |
return bubble;
|
134 |
}
|
135 |
|
136 |
+
// π§ Send question
|
137 |
sendBtn.addEventListener("click", async () => {
|
|
|
138 |
const question = input.value.trim();
|
139 |
if (!question) return;
|
140 |
|
|
|
149 |
}
|
150 |
|
151 |
createMessageBubble(question, "You", null, selectedFile.name);
|
152 |
+
const thinkingBubble = createMessageBubble("Wait, let me think π€...", "Chris");
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
const formData = new FormData();
|
155 |
formData.append("question", question);
|
156 |
+
formData.append("file", selectedFile);
|
157 |
|
158 |
try {
|
159 |
const response = await fetch("/predict", {
|
|
|
176 |
icon.style.fontSize = "18px";
|
177 |
icon.style.marginLeft = "10px";
|
178 |
|
179 |
+
let currentAudio = new Audio(audioSrc);
|
180 |
+
currentAudio.play();
|
181 |
|
182 |
+
let isMuted = false;
|
183 |
icon.addEventListener("click", () => {
|
184 |
+
if (isMuted) {
|
185 |
+
currentAudio = new Audio(audioSrc); // restart
|
186 |
+
currentAudio.play();
|
187 |
+
isMuted = false;
|
188 |
icon.classList.replace("fa-volume-xmark", "fa-volume-high");
|
189 |
icon.title = "Click to mute";
|
190 |
} else {
|
191 |
+
currentAudio.pause();
|
192 |
+
isMuted = true;
|
193 |
icon.classList.replace("fa-volume-high", "fa-volume-xmark");
|
194 |
icon.title = "Click to unmute";
|
195 |
}
|
|
|
199 |
message.style.justifyContent = "space-between";
|
200 |
message.appendChild(icon);
|
201 |
}
|
|
|
202 |
} catch (err) {
|
203 |
const message = thinkingBubble.querySelector(".text");
|
204 |
message.innerText = "β οΈ Chris had trouble responding.";
|
205 |
}
|
206 |
|
207 |
+
input.value = "";
|
208 |
});
|
209 |
});
|
210 |
|
211 |
|
|
|
212 |
/*
|
213 |
document.addEventListener("DOMContentLoaded", () => {
|
214 |
const convo = document.querySelector(".convo");
|