ikraamkb commited on
Commit
8a2b678
·
verified ·
1 Parent(s): fcf2242

Update static/appS.js

Browse files
Files changed (1) hide show
  1. static/appS.js +89 -491
static/appS.js CHANGED
@@ -1,489 +1,3 @@
1
- /*document.addEventListener('DOMContentLoaded', () => {
2
- const convo = document.querySelector(".convo");
3
- const fileUpload = document.getElementById('file-upload');
4
- const imageUpload = document.getElementById('image-upload');
5
- const fileBtn = document.getElementById('file-btn');
6
- const imageBtn = document.getElementById('image-btn');
7
- const sendButtons = document.querySelectorAll('.sendingQA');
8
- const SummarizeInput = document.querySelector(".SummarizeInput");
9
- const CaptionInput = document.querySelector(".CaptionInput");
10
- const gotItButton = document.querySelector('.explainChoix button');
11
- const explainChoixDiv = document.querySelector('.explainChoix');
12
-
13
- let selectedFile = null;
14
-
15
- const summarizeRadio = document.getElementById('summarize-radio');
16
- if (summarizeRadio) summarizeRadio.checked = true;
17
-
18
- document.querySelectorAll('.select-options input[name="mode"]').forEach(radio => {
19
- radio.addEventListener('change', (e) => {
20
- if (e.target.checked) {
21
- const selectedValue = e.target.value;
22
- if (selectedValue === "Summarize") {
23
- SummarizeInput.classList.add("active");
24
- SummarizeInput.classList.remove("innactive");
25
- CaptionInput.classList.remove("active");
26
- CaptionInput.classList.add("innactive");
27
- } else {
28
- SummarizeInput.classList.add("innactive");
29
- SummarizeInput.classList.remove("active");
30
- CaptionInput.classList.remove("innactive");
31
- CaptionInput.classList.add("active");
32
- }
33
- }
34
- });
35
- });
36
-
37
- fileBtn.addEventListener('click', () => fileUpload.click());
38
- imageBtn.addEventListener('click', () => imageUpload.click());
39
-
40
- fileUpload.addEventListener('change', (e) => {
41
- if (e.target.files.length) {
42
- selectedFile = e.target.files[0];
43
- displayFilePreview(selectedFile);
44
- }
45
- });
46
-
47
- imageUpload.addEventListener('change', (e) => {
48
- if (e.target.files.length) {
49
- selectedFile = e.target.files[0];
50
- displayFilePreview(selectedFile);
51
- }
52
- });
53
-
54
- gotItButton.addEventListener('click', () => {
55
- explainChoixDiv.style.display = "none";
56
- });
57
-
58
- sendButtons.forEach(button => {
59
- button.addEventListener('click', handleSubmit);
60
- });
61
-
62
- function displayFilePreview(file) {
63
- const previewBubble = document.createElement("div");
64
- previewBubble.className = "file-preview-bubble bubble right";
65
- previewBubble.style.display = "flex";
66
- previewBubble.style.flexDirection = "column";
67
- previewBubble.style.maxWidth = "50%";
68
-
69
- if (file.type.startsWith('image/')) {
70
- const reader = new FileReader();
71
- reader.onload = (e) => {
72
- const img = document.createElement("img");
73
- img.src = e.target.result;
74
- img.style.width = "100%";
75
- img.style.height = "200px";
76
- img.style.objectFit = "cover";
77
- img.style.borderRadius = "10px";
78
- img.style.marginBottom = "8px";
79
-
80
- const text = document.createElement("span");
81
- text.textContent = `📎 Selected image: ${file.name}`;
82
- text.style.fontSize = "13px";
83
-
84
- previewBubble.appendChild(img);
85
- previewBubble.appendChild(text);
86
- convo.appendChild(previewBubble);
87
- convo.scrollTop = convo.scrollHeight;
88
- };
89
- reader.readAsDataURL(file);
90
- } else {
91
- const text = document.createElement("span");
92
- text.textContent = `📎 Selected document: ${file.name}`;
93
- text.style.fontSize = "13px";
94
-
95
- previewBubble.appendChild(text);
96
- convo.appendChild(previewBubble);
97
- convo.scrollTop = convo.scrollHeight;
98
- }
99
- }
100
-
101
- function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
102
- const bubble = document.createElement('div');
103
- bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
104
- bubble.style.maxWidth = "50%";
105
- bubble.style.wordWrap = "break-word";
106
-
107
- const label = document.createElement('div');
108
- label.className = "label";
109
- label.textContent = sender;
110
-
111
- const message = document.createElement('div');
112
- message.className = "text";
113
- message.style.whiteSpace = "pre-wrap";
114
- message.style.display = "flex";
115
- message.style.flexDirection = "column";
116
-
117
- const textSpan = document.createElement("span");
118
- textSpan.innerHTML = text;
119
- message.appendChild(textSpan);
120
-
121
- if (sender !== "You" && (audioSrc || fileName)) {
122
- const iconContainer = document.createElement('div');
123
- iconContainer.style.marginTop = "10px";
124
- iconContainer.style.display = "flex";
125
- iconContainer.style.justifyContent = "flex-end";
126
- iconContainer.style.gap = "15px";
127
-
128
- if (audioSrc) {
129
- const audio = new Audio(audioSrc);
130
- // const audioIcon = document.createElement("i");
131
- audioIcon.className = "fa-solid fa-volume-high audio-toggle";
132
- audioIcon.title = "Play Audio";
133
- audioIcon.style.cursor = "pointer";
134
- audioIcon.style.fontSize = "18px";
135
-
136
- audioIcon.addEventListener("click", () => {
137
- if (audio.paused) {
138
- audio.play();
139
- audioIcon.classList.remove("fa-volume-xmark");
140
- audioIcon.classList.add("fa-volume-high");
141
- audioIcon.title = "Mute Audio";
142
- } else {
143
- audio.pause();
144
- audioIcon.classList.remove("fa-volume-high");
145
- audioIcon.classList.add("fa-volume-xmark");
146
- audioIcon.title = "Unmute Audio";
147
- }
148
- });
149
-
150
- iconContainer.appendChild(audioIcon);
151
- }
152
-
153
- if (fileName) {
154
- const downloadLink = document.createElement('a');
155
- downloadLink.href = fileName;
156
- downloadLink.target = "_blank";
157
- downloadLink.download = "summary.pdf";
158
- const downloadIcon = document.createElement("i");
159
- downloadIcon.className = "fa-solid fa-file-arrow-down";
160
- downloadIcon.style.fontSize = "18px";
161
- downloadIcon.style.cursor = "pointer";
162
- downloadLink.appendChild(downloadIcon);
163
- iconContainer.appendChild(downloadLink);
164
- }
165
-
166
- message.appendChild(iconContainer);
167
- }
168
-
169
- bubble.appendChild(label);
170
- bubble.appendChild(message);
171
- convo.appendChild(bubble);
172
- convo.scrollTop = convo.scrollHeight;
173
- return bubble;
174
- }
175
-
176
-
177
- async function handleSubmit() {
178
- if (!selectedFile) {
179
- alert("Please upload a file first");
180
- return;
181
- }
182
-
183
- const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
184
- const endpoint = isSummarizeMode ? '/Summarization/summarize/' : '/Summarization/imagecaption/';
185
- const thinkingText = isSummarizeMode ? 'Processing document 📄... <div class="loader"></div>' : "Generating caption 🖼️ ... <div class='loader'></div>";
186
- const senderName = "Aidan";
187
-
188
- const thinkingBubble = createMessageBubble(thinkingText, senderName);
189
-
190
- const formData = new FormData();
191
- formData.append('file', selectedFile);
192
- if (isSummarizeMode) formData.append('length', 'medium');
193
-
194
- try {
195
- const response = await fetch(endpoint, {
196
- method: 'POST',
197
- body: formData
198
- });
199
-
200
- if (!response.ok) {
201
- let errorMessage = 'Request failed';
202
- try {
203
- const error = await response.json();
204
- errorMessage = error.detail || error.error || errorMessage;
205
- } catch (e) {}
206
- throw new Error(errorMessage);
207
- }
208
-
209
- const result = await response.json();
210
- thinkingBubble.remove();
211
-
212
- if (isSummarizeMode) {
213
- createMessageBubble(
214
- result.summary || "No summary generated.",
215
- "Aidan",
216
- null, // Removed audioUrl
217
- result.pdfUrl
218
- );
219
- } else {
220
- createMessageBubble(
221
- result.caption || result.answer || "No caption generated.",
222
- "Aidan",
223
- null, // Removed audio
224
- null
225
- );
226
- }
227
- } catch (error) {
228
- thinkingBubble.remove();
229
- createMessageBubble(`⚠️ Error: ${error.message}`, "Aidan");
230
- } finally {
231
- selectedFile = null;
232
- }
233
- }
234
-
235
- const style = document.createElement('style');
236
- style.textContent = `
237
- .loader {
238
- display: inline-block;
239
- border: 2px solid #f3f3f3;
240
- border-top: 2px solid #3b82f6;
241
- border-radius: 50%;
242
- width: 16px;
243
- height: 16px;
244
- animation: spin 1s linear infinite;
245
- }
246
- @keyframes spin {
247
- 0% { transform: rotate(0deg); }
248
- 100% { transform: rotate(360deg); }
249
- }
250
- `;
251
- document.head.appendChild(style);
252
-
253
- var backarrow = document.querySelector(".fa-arrow-left");
254
- backarrow.addEventListener('click', function () {
255
- window.location.href = '/';
256
- });
257
- }); */
258
- /* document.addEventListener('DOMContentLoaded', () => {
259
- const convo = document.querySelector(".convo");
260
- const fileUpload = document.getElementById('file-upload');
261
- const imageUpload = document.getElementById('image-upload');
262
- const fileBtn = document.getElementById('file-btn');
263
- const imageBtn = document.getElementById('image-btn');
264
- const sendButtons = document.querySelectorAll('.sendingQA');
265
- const SummarizeInput = document.querySelector(".SummarizeInput");
266
- const CaptionInput = document.querySelector(".CaptionInput");
267
- const gotItButton = document.querySelector('.explainChoix button');
268
- const explainChoixDiv = document.querySelector('.explainChoix');
269
-
270
- let selectedFile = null;
271
-
272
- const summarizeRadio = document.getElementById('summarize-radio');
273
- if (summarizeRadio) summarizeRadio.checked = true;
274
-
275
- document.querySelectorAll('.select-options input[name="mode"]').forEach(radio => {
276
- radio.addEventListener('change', (e) => {
277
- if (e.target.checked) {
278
- const selectedValue = e.target.value;
279
- if (selectedValue === "Summarize") {
280
- SummarizeInput.classList.add("active");
281
- SummarizeInput.classList.remove("innactive");
282
- CaptionInput.classList.remove("active");
283
- CaptionInput.classList.add("innactive");
284
- } else {
285
- SummarizeInput.classList.add("innactive");
286
- SummarizeInput.classList.remove("active");
287
- CaptionInput.classList.remove("innactive");
288
- CaptionInput.classList.add("active");
289
- }
290
- }
291
- });
292
- });
293
-
294
- fileBtn.addEventListener('click', () => fileUpload.click());
295
- imageBtn.addEventListener('click', () => imageUpload.click());
296
-
297
- fileUpload.addEventListener('change', (e) => {
298
- if (e.target.files.length) {
299
- selectedFile = e.target.files[0];
300
- displayFilePreview(selectedFile);
301
- }
302
- });
303
-
304
- imageUpload.addEventListener('change', (e) => {
305
- if (e.target.files.length) {
306
- selectedFile = e.target.files[0];
307
- displayFilePreview(selectedFile);
308
- }
309
- });
310
-
311
- gotItButton.addEventListener('click', () => {
312
- explainChoixDiv.style.display = "none";
313
- });
314
-
315
- sendButtons.forEach(button => {
316
- button.addEventListener('click', handleSubmit);
317
- });
318
-
319
- function displayFilePreview(file) {
320
- const previewBubble = document.createElement("div");
321
- previewBubble.className = "file-preview-bubble bubble right";
322
- previewBubble.style.display = "flex";
323
- previewBubble.style.flexDirection = "column";
324
- previewBubble.style.maxWidth = "50%";
325
-
326
- if (file.type.startsWith('image/')) {
327
- const reader = new FileReader();
328
- reader.onload = (e) => {
329
- const img = document.createElement("img");
330
- img.src = e.target.result;
331
- img.style.width = "100%";
332
- img.style.height = "200px";
333
- img.style.objectFit = "cover";
334
- img.style.borderRadius = "10px";
335
- img.style.marginBottom = "8px";
336
-
337
- const text = document.createElement("span");
338
- text.textContent = `📎 Selected image: ${file.name}`;
339
- text.style.fontSize = "13px";
340
-
341
- previewBubble.appendChild(img);
342
- previewBubble.appendChild(text);
343
- convo.appendChild(previewBubble);
344
- convo.scrollTop = convo.scrollHeight;
345
- };
346
- reader.readAsDataURL(file);
347
- } else {
348
- const text = document.createElement("span");
349
- text.textContent = `📎 Selected document: ${file.name}`;
350
- text.style.fontSize = "13px";
351
-
352
- previewBubble.appendChild(text);
353
- convo.appendChild(previewBubble);
354
- convo.scrollTop = convo.scrollHeight;
355
- }
356
- }
357
-
358
- function createMessageBubble(text, sender = "You", fileName = null) {
359
- const bubble = document.createElement('div');
360
- bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
361
- bubble.style.maxWidth = "50%";
362
- bubble.style.wordWrap = "break-word";
363
-
364
- const label = document.createElement('div');
365
- label.className = "label";
366
- label.textContent = sender;
367
-
368
- const message = document.createElement('div');
369
- message.className = "text";
370
- message.style.whiteSpace = "pre-wrap";
371
- message.style.display = "flex";
372
- message.style.flexDirection = "column";
373
-
374
- const textSpan = document.createElement("span");
375
- textSpan.innerHTML = text;
376
- message.appendChild(textSpan);
377
-
378
- if (sender !== "You" && fileName) {
379
- const iconContainer = document.createElement('div');
380
- iconContainer.style.marginTop = "10px";
381
- iconContainer.style.display = "flex";
382
- iconContainer.style.justifyContent = "flex-end";
383
- iconContainer.style.gap = "15px";
384
-
385
- const downloadLink = document.createElement('a');
386
- downloadLink.href = fileName;
387
- downloadLink.target = "_blank";
388
- downloadLink.download = "summary.pdf";
389
- const downloadIcon = document.createElement("i");
390
- downloadIcon.className = "fa-solid fa-file-arrow-down";
391
- downloadIcon.style.fontSize = "18px";
392
- downloadIcon.style.cursor = "pointer";
393
- downloadLink.appendChild(downloadIcon);
394
- iconContainer.appendChild(downloadLink);
395
-
396
- message.appendChild(iconContainer);
397
- }
398
-
399
- bubble.appendChild(label);
400
- bubble.appendChild(message);
401
- convo.appendChild(bubble);
402
- convo.scrollTop = convo.scrollHeight;
403
- return bubble;
404
- }
405
-
406
- async function handleSubmit() {
407
- if (!selectedFile) {
408
- alert("Please upload a file first");
409
- return;
410
- }
411
-
412
- const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
413
- const endpoint = isSummarizeMode ? '/Summarization/summarize/' : '/Summarization/imagecaption/';
414
- const thinkingText = isSummarizeMode ? 'Processing document 📄... <div class="loader"></div>' : "Generating caption 🖼️ ... <div class='loader'></div>";
415
- const senderName = "Aidan";
416
-
417
- const thinkingBubble = createMessageBubble(thinkingText, senderName);
418
-
419
- const formData = new FormData();
420
- formData.append('file', selectedFile);
421
- if (isSummarizeMode) formData.append('length', summarizeRadio.selectedItem);
422
-
423
- try {
424
- const response = await fetch(endpoint, {
425
- method: 'POST',
426
- body: formData
427
- });
428
-
429
- if (!response.ok) {
430
- let errorMessage = 'Request failed';
431
- try {
432
- const error = await response.json();
433
- errorMessage = error.detail || error.error || errorMessage;
434
- } catch (e) {}
435
- throw new Error(errorMessage);
436
- }
437
-
438
- const result = await response.json();
439
- thinkingBubble.remove();
440
-
441
- if (isSummarizeMode) {
442
- createMessageBubble(
443
- result.summary || "No summary generated.",
444
- "Aidan",
445
- result.pdfUrl
446
- );
447
- } else {
448
- createMessageBubble(
449
- result.caption || result.answer || "No caption generated.",
450
- "Aidan",
451
- null
452
- );
453
- }
454
- } catch (error) {
455
- thinkingBubble.remove();
456
- createMessageBubble(`⚠️ Error: ${error.message}`, "Aidan");
457
- } finally {
458
- selectedFile = null;
459
- }
460
- }
461
-
462
- const style = document.createElement('style');
463
- style.textContent = `
464
- .loader {
465
- display: inline-block;
466
- border: 2px solid #f3f3f3;
467
- border-top: 2px solid #3b82f6;
468
- border-radius: 50%;
469
- width: 16px;
470
- height: 16px;
471
- animation: spin 1s linear infinite;
472
- }
473
- @keyframes spin {
474
- 0% { transform: rotate(0deg); }
475
- 100% { transform: rotate(360deg); }
476
- }
477
- `;
478
- document.head.appendChild(style);
479
-
480
- var backarrow = document.querySelector(".fa-arrow-left");
481
- backarrow.addEventListener('click', function () {
482
- window.location.href = '/';
483
- });
484
- }); */
485
-
486
-
487
  document.addEventListener('DOMContentLoaded', () => {
488
  const convo = document.querySelector(".convo");
489
  const fileUpload = document.getElementById('file-upload');
@@ -498,11 +12,11 @@ document.addEventListener('DOMContentLoaded', () => {
498
 
499
  let selectedFile = null;
500
 
501
- // Default mode
502
  const summarizeRadio = document.getElementById('summarize-radio');
503
  if (summarizeRadio) summarizeRadio.checked = true;
504
 
505
- //Mode switching
506
  document.querySelectorAll('.select-options input[name="mode"]').forEach(radio => {
507
  radio.addEventListener('change', (e) => {
508
  const selected = e.target.value;
@@ -583,7 +97,7 @@ document.addEventListener('DOMContentLoaded', () => {
583
  }
584
  }
585
 
586
- function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
587
  const bubble = document.createElement('div');
588
  bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
589
  bubble.style.maxWidth = "50%";
@@ -603,7 +117,7 @@ function createMessageBubble(text, sender = "You", audioSrc = null, fileName = n
603
  textSpan.innerHTML = text;
604
  message.appendChild(textSpan);
605
 
606
- // ✅ Only define and append icon container if needed
607
  if (sender !== "You" && (audioSrc || fileName)) {
608
  const iconContainer = document.createElement('div');
609
  iconContainer.style.marginTop = "10px";
@@ -660,8 +174,92 @@ function createMessageBubble(text, sender = "You", audioSrc = null, fileName = n
660
  convo.appendChild(bubble);
661
  convo.scrollTop = convo.scrollHeight;
662
  return bubble;
663
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
664
 
 
 
 
 
 
 
 
665
  async function handleSubmit() {
666
  if (!selectedFile) {
667
  alert("Please upload a file first");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  document.addEventListener('DOMContentLoaded', () => {
2
  const convo = document.querySelector(".convo");
3
  const fileUpload = document.getElementById('file-upload');
 
12
 
13
  let selectedFile = null;
14
 
15
+ // Default mode is summarize
16
  const summarizeRadio = document.getElementById('summarize-radio');
17
  if (summarizeRadio) summarizeRadio.checked = true;
18
 
19
+ // Mode switching
20
  document.querySelectorAll('.select-options input[name="mode"]').forEach(radio => {
21
  radio.addEventListener('change', (e) => {
22
  const selected = e.target.value;
 
97
  }
98
  }
99
 
100
+ /*function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
101
  const bubble = document.createElement('div');
102
  bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
103
  bubble.style.maxWidth = "50%";
 
117
  textSpan.innerHTML = text;
118
  message.appendChild(textSpan);
119
 
120
+
121
  if (sender !== "You" && (audioSrc || fileName)) {
122
  const iconContainer = document.createElement('div');
123
  iconContainer.style.marginTop = "10px";
 
174
  convo.appendChild(bubble);
175
  convo.scrollTop = convo.scrollHeight;
176
  return bubble;
177
+ }*/
178
+ function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
179
+ const bubble = document.createElement('div');
180
+ bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
181
+ bubble.style.maxWidth = "50%";
182
+ bubble.style.wordWrap = "break-word";
183
+
184
+ const label = document.createElement('div');
185
+ label.className = "label";
186
+ label.textContent = sender;
187
+
188
+ const message = document.createElement('div');
189
+ message.className = "text";
190
+ message.style.whiteSpace = "pre-wrap";
191
+ message.style.display = "flex";
192
+ message.style.flexDirection = "column";
193
+
194
+ const textSpan = document.createElement("span");
195
+ textSpan.innerHTML = text;
196
+ message.appendChild(textSpan);
197
+
198
+ if (sender !== "You" && (audioSrc || fileName)) {
199
+ const iconContainer = document.createElement('div');
200
+ iconContainer.style.marginTop = "10px";
201
+ iconContainer.style.display = "flex";
202
+ iconContainer.style.justifyContent = "flex-end";
203
+ iconContainer.style.gap = "15px";
204
+
205
+ // Audio Player
206
+ if (audioSrc) {
207
+ const audio = new Audio(audioSrc);
208
+ const audioIcon = document.createElement("i");
209
+ audioIcon.className = "fa-solid fa-volume-high audio-toggle";
210
+ audioIcon.title = "Play Audio";
211
+ audioIcon.style.cursor = "pointer";
212
+ audioIcon.style.fontSize = "18px";
213
+
214
+
215
+ const updateAudioIcon = () => {
216
+ if (audio.paused) {
217
+ audioIcon.classList.replace("fa-volume-xmark", "fa-volume-high");
218
+ audioIcon.title = "Play Audio";
219
+ } else {
220
+ audioIcon.classList.replace("fa-volume-high", "fa-volume-xmark");
221
+ audioIcon.title = "Pause Audio";
222
+ }
223
+ };
224
+
225
+ audio.addEventListener('play', updateAudioIcon);
226
+ audio.addEventListener('pause', updateAudioIcon);
227
+ audio.addEventListener('ended', updateAudioIcon);
228
+
229
+ audioIcon.addEventListener("click", () => {
230
+ audio.paused ? audio.play().catch(e => console.error("Audio error:", e)) : audio.pause();
231
+ });
232
+
233
+ iconContainer.appendChild(audioIcon);
234
+ }
235
+
236
+ // PDF Download
237
+ if (fileName) {
238
+ const downloadLink = document.createElement('a');
239
+ downloadLink.href = fileName;
240
+ downloadLink.target = "_blank";
241
+ downloadLink.download = fileName.split('/').pop() || "summary.pdf";
242
+
243
+ const downloadIcon = document.createElement("i");
244
+ downloadIcon.className = "fa-solid fa-file-arrow-down";
245
+ downloadIcon.style.fontSize = "18px";
246
+ downloadIcon.style.cursor = "pointer";
247
+ downloadIcon.title = "Download Summary PDF";
248
+
249
+ downloadLink.appendChild(downloadIcon);
250
+ iconContainer.appendChild(downloadLink);
251
+ }
252
+
253
+ message.appendChild(iconContainer);
254
+ }
255
 
256
+ bubble.appendChild(label);
257
+ bubble.appendChild(message);
258
+ convo.appendChild(bubble);
259
+ convo.scrollTop = convo.scrollHeight;
260
+
261
+ return bubble;
262
+ }
263
  async function handleSubmit() {
264
  if (!selectedFile) {
265
  alert("Please upload a file first");