Spaces:
Running
Running
Update static/appS.js
Browse files- static/appS.js +76 -76
static/appS.js
CHANGED
@@ -11,6 +11,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
11 |
var explainChoixDiv = document.querySelector('.explainChoix');
|
12 |
|
13 |
let selectedFile = null;
|
|
|
14 |
|
15 |
// β
Default mode: Summarize selected
|
16 |
const summarizeRadio = document.getElementById('summarize-radio');
|
@@ -43,12 +44,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
43 |
fileUpload.addEventListener('change', (e) => {
|
44 |
if (e.target.files.length) {
|
45 |
selectedFile = e.target.files[0];
|
|
|
46 |
}
|
47 |
});
|
48 |
|
49 |
imageUpload.addEventListener('change', (e) => {
|
50 |
if (e.target.files.length) {
|
51 |
selectedFile = e.target.files[0];
|
|
|
52 |
}
|
53 |
});
|
54 |
|
@@ -63,16 +66,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
63 |
});
|
64 |
|
65 |
function displayFilePreview(file) {
|
66 |
-
|
67 |
-
newBubble.className = "file-preview-bubble bubble right";
|
68 |
-
newBubble.style.display = "flex";
|
69 |
-
newBubble.style.flexDirection = "column";
|
70 |
-
newBubble.style.maxWidth = "50%";
|
71 |
|
72 |
// If it's an image
|
73 |
if (file.type.startsWith('image/')) {
|
74 |
const reader = new FileReader();
|
75 |
reader.onload = (e) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
const img = document.createElement("img");
|
77 |
img.src = e.target.result;
|
78 |
img.style.width = "100%";
|
@@ -85,81 +90,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
85 |
text.textContent = `π Selected image: ${file.name}`;
|
86 |
text.style.fontSize = "13px";
|
87 |
|
88 |
-
|
89 |
-
|
90 |
-
convo.appendChild(
|
91 |
convo.scrollTop = convo.scrollHeight;
|
92 |
};
|
93 |
reader.readAsDataURL(file);
|
94 |
} else {
|
95 |
// Document preview stays as text
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
convo.appendChild(newBubble);
|
101 |
-
convo.scrollTop = convo.scrollHeight;
|
102 |
-
}
|
103 |
-
}
|
104 |
-
|
105 |
-
async function handleSubmit() {
|
106 |
-
if (!selectedFile) {
|
107 |
-
alert("Please upload a file first");
|
108 |
-
return;
|
109 |
-
}
|
110 |
-
|
111 |
-
const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
|
112 |
-
const endpoint = isSummarizeMode ? '/summarize/' : '/imagecaption/';
|
113 |
-
const thinkingText = isSummarizeMode ? 'Processing document... <div class="loader"></div>' : "Generating caption... <div class='loader'></div>";
|
114 |
-
const senderName = "Aidan";
|
115 |
-
|
116 |
-
const thinkingBubble = createMessageBubble(thinkingText, senderName);
|
117 |
-
|
118 |
-
const formData = new FormData();
|
119 |
-
formData.append('file', selectedFile);
|
120 |
-
if (isSummarizeMode) formData.append('length', 'medium');
|
121 |
-
|
122 |
-
// Display file preview in new bubble
|
123 |
-
displayFilePreview(selectedFile);
|
124 |
-
|
125 |
-
try {
|
126 |
-
const response = await fetch(endpoint, {
|
127 |
-
method: 'POST',
|
128 |
-
body: formData
|
129 |
-
});
|
130 |
-
|
131 |
-
if (!response.ok) {
|
132 |
-
let errorMessage = 'Request failed';
|
133 |
-
try {
|
134 |
-
const error = await response.json();
|
135 |
-
errorMessage = error.detail || error.error || errorMessage;
|
136 |
-
} catch (e) {
|
137 |
-
// response not JSON
|
138 |
-
}
|
139 |
-
throw new Error(errorMessage);
|
140 |
-
}
|
141 |
-
|
142 |
-
const result = await response.json();
|
143 |
-
thinkingBubble.remove();
|
144 |
-
|
145 |
-
if (isSummarizeMode) {
|
146 |
-
createMessageBubble(
|
147 |
-
result.summary || "No summary generated.",
|
148 |
-
"Aidan",
|
149 |
-
result.audioUrl,
|
150 |
-
result.pdfUrl
|
151 |
-
);
|
152 |
-
} else {
|
153 |
-
createMessageBubble(
|
154 |
-
result.caption || result.answer || "No caption generated.",
|
155 |
-
"Aidan",
|
156 |
-
result.audio,
|
157 |
-
null
|
158 |
-
);
|
159 |
-
}
|
160 |
-
} catch (error) {
|
161 |
-
thinkingBubble.remove();
|
162 |
-
createMessageBubble(`β οΈ Error: ${error.message}`, "Aidan");
|
163 |
}
|
164 |
}
|
165 |
|
@@ -219,7 +161,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
219 |
const downloadLink = document.createElement('a');
|
220 |
downloadLink.href = fileName;
|
221 |
downloadLink.target = "_blank";
|
222 |
-
|
223 |
|
224 |
const downloadIcon = document.createElement("i");
|
225 |
downloadIcon.className = "fa-solid fa-file-arrow-down";
|
@@ -240,6 +182,64 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
240 |
return bubble;
|
241 |
}
|
242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
// Loader CSS
|
244 |
const style = document.createElement('style');
|
245 |
style.textContent = `
|
|
|
11 |
var explainChoixDiv = document.querySelector('.explainChoix');
|
12 |
|
13 |
let selectedFile = null;
|
14 |
+
let filePreviewBubble = null;
|
15 |
|
16 |
// β
Default mode: Summarize selected
|
17 |
const summarizeRadio = document.getElementById('summarize-radio');
|
|
|
44 |
fileUpload.addEventListener('change', (e) => {
|
45 |
if (e.target.files.length) {
|
46 |
selectedFile = e.target.files[0];
|
47 |
+
displayFilePreview(selectedFile);
|
48 |
}
|
49 |
});
|
50 |
|
51 |
imageUpload.addEventListener('change', (e) => {
|
52 |
if (e.target.files.length) {
|
53 |
selectedFile = e.target.files[0];
|
54 |
+
displayFilePreview(selectedFile);
|
55 |
}
|
56 |
});
|
57 |
|
|
|
66 |
});
|
67 |
|
68 |
function displayFilePreview(file) {
|
69 |
+
if (filePreviewBubble) filePreviewBubble.remove();
|
|
|
|
|
|
|
|
|
70 |
|
71 |
// If it's an image
|
72 |
if (file.type.startsWith('image/')) {
|
73 |
const reader = new FileReader();
|
74 |
reader.onload = (e) => {
|
75 |
+
filePreviewBubble = document.createElement("div");
|
76 |
+
filePreviewBubble.className = "file-preview-bubble bubble right";
|
77 |
+
filePreviewBubble.style.display = "flex";
|
78 |
+
filePreviewBubble.style.flexDirection = "column";
|
79 |
+
filePreviewBubble.style.maxWidth = "50%";
|
80 |
+
|
81 |
const img = document.createElement("img");
|
82 |
img.src = e.target.result;
|
83 |
img.style.width = "100%";
|
|
|
90 |
text.textContent = `π Selected image: ${file.name}`;
|
91 |
text.style.fontSize = "13px";
|
92 |
|
93 |
+
filePreviewBubble.appendChild(img);
|
94 |
+
filePreviewBubble.appendChild(text);
|
95 |
+
convo.appendChild(filePreviewBubble);
|
96 |
convo.scrollTop = convo.scrollHeight;
|
97 |
};
|
98 |
reader.readAsDataURL(file);
|
99 |
} else {
|
100 |
// Document preview stays as text
|
101 |
+
filePreviewBubble = createMessageBubble(
|
102 |
+
`π Selected document: ${file.name}`,
|
103 |
+
"You"
|
104 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
}
|
106 |
}
|
107 |
|
|
|
161 |
const downloadLink = document.createElement('a');
|
162 |
downloadLink.href = fileName;
|
163 |
downloadLink.target = "_blank";
|
164 |
+
downloadLink.download = "summary.pdf"; // β
Suggest filename to browser
|
165 |
|
166 |
const downloadIcon = document.createElement("i");
|
167 |
downloadIcon.className = "fa-solid fa-file-arrow-down";
|
|
|
182 |
return bubble;
|
183 |
}
|
184 |
|
185 |
+
async function handleSubmit() {
|
186 |
+
if (!selectedFile) {
|
187 |
+
alert("Please upload a file first");
|
188 |
+
return;
|
189 |
+
}
|
190 |
+
|
191 |
+
const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
|
192 |
+
const endpoint = isSummarizeMode ? '/summarize/' : '/imagecaption/';
|
193 |
+
const thinkingText = isSummarizeMode ? 'Processing document... <div class="loader"></div>' : "Generating caption... <div class='loader'></div>";
|
194 |
+
const senderName = "Aidan";
|
195 |
+
|
196 |
+
const thinkingBubble = createMessageBubble(thinkingText, senderName);
|
197 |
+
|
198 |
+
const formData = new FormData();
|
199 |
+
formData.append('file', selectedFile);
|
200 |
+
if (isSummarizeMode) formData.append('length', 'medium');
|
201 |
+
|
202 |
+
try {
|
203 |
+
const response = await fetch(endpoint, {
|
204 |
+
method: 'POST',
|
205 |
+
body: formData
|
206 |
+
});
|
207 |
+
|
208 |
+
if (!response.ok) {
|
209 |
+
let errorMessage = 'Request failed';
|
210 |
+
try {
|
211 |
+
const error = await response.json();
|
212 |
+
errorMessage = error.detail || error.error || errorMessage;
|
213 |
+
} catch (e) {
|
214 |
+
// response not JSON
|
215 |
+
}
|
216 |
+
throw new Error(errorMessage);
|
217 |
+
}
|
218 |
+
|
219 |
+
const result = await response.json();
|
220 |
+
thinkingBubble.remove();
|
221 |
+
|
222 |
+
if (isSummarizeMode) {
|
223 |
+
createMessageBubble(
|
224 |
+
result.summary || "No summary generated.",
|
225 |
+
"Aidan",
|
226 |
+
result.audioUrl,
|
227 |
+
result.pdfUrl
|
228 |
+
);
|
229 |
+
} else {
|
230 |
+
createMessageBubble(
|
231 |
+
result.caption || result.answer || "No caption generated.",
|
232 |
+
"Aidan",
|
233 |
+
result.audio,
|
234 |
+
null
|
235 |
+
);
|
236 |
+
}
|
237 |
+
} catch (error) {
|
238 |
+
thinkingBubble.remove();
|
239 |
+
createMessageBubble(`β οΈ Error: ${error.message}`, "Aidan");
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
// Loader CSS
|
244 |
const style = document.createElement('style');
|
245 |
style.textContent = `
|