ikraamkb commited on
Commit
4b810e0
Β·
verified Β·
1 Parent(s): 3ba8f3d

Update static/appS.js

Browse files
Files changed (1) hide show
  1. static/appS.js +105 -79
static/appS.js CHANGED
@@ -11,6 +11,7 @@ document.addEventListener('DOMContentLoaded', () => {
11
  const explainChoixDiv = document.getElementById('explainChoix');
12
 
13
  let selectedFile = null;
 
14
 
15
  // βœ… Default mode: Summarize selected
16
  const summarizeRadio = document.getElementById('summarize-radio');
@@ -43,89 +44,41 @@ document.addEventListener('DOMContentLoaded', () => {
43
  fileUpload.addEventListener('change', (e) => {
44
  if (e.target.files.length) {
45
  selectedFile = e.target.files[0];
46
- handleFileUpload(selectedFile);
47
  }
48
  });
49
 
50
  imageUpload.addEventListener('change', (e) => {
51
  if (e.target.files.length) {
52
  selectedFile = e.target.files[0];
53
- handleFileUpload(selectedFile);
54
  }
55
  });
56
 
57
- // "Got it" button
58
- gotItButton.addEventListener('click', () => {
59
- explainChoixDiv.style.display = "none";
60
- });
61
-
62
- async function handleFileUpload(file) {
63
- if (!file) return;
64
-
65
- const isImage = file.type.startsWith('image/');
66
- const icon = isImage ? 'πŸ–ΌοΈ' : 'πŸ“Ž';
67
-
68
- // User bubble: Uploaded file
69
- createMessageBubble(`${icon} Uploaded: ${file.name}`, "You");
70
-
71
- const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
72
- const endpoint = isSummarizeMode ? '/summarize/' : '/imagecaption/';
73
- const thinkingText = isSummarizeMode ? 'Analyzing document... <div class="loader"></div>' : 'Analyzing image... <div class="loader"></div>';
74
-
75
- // AI thinking bubble
76
- const thinkingBubble = createMessageBubble(thinkingText, "Aidan");
77
-
78
- const formData = new FormData();
79
- formData.append('file', file);
80
-
81
- if (isSummarizeMode) {
82
- const selectedLength = document.querySelector('input[name="length"]:checked')?.value || 'medium';
83
- formData.append('length', selectedLength);
84
- }
85
-
86
- try {
87
- const response = await fetch(endpoint, {
88
- method: 'POST',
89
- body: formData
90
- });
91
-
92
- if (!response.ok) {
93
- let errorMessage = 'Request failed';
94
- try {
95
- const error = await response.json();
96
- errorMessage = error.detail || error.error || errorMessage;
97
- } catch (e) {}
98
- throw new Error(errorMessage);
99
  }
 
 
100
 
101
- const result = await response.json();
102
- thinkingBubble.remove();
 
 
103
 
104
- // Aidan's response bubble
105
- if (isSummarizeMode) {
106
- createMessageBubble(
107
- result.summary || "No summary generated.",
108
- "Aidan",
109
- result.audioUrl,
110
- result.pdfUrl
111
- );
112
- } else {
113
- createMessageBubble(
114
- result.caption || result.answer || "No caption generated.",
115
- "Aidan",
116
- result.audio,
117
- null
118
- );
119
- }
120
- } catch (error) {
121
- thinkingBubble.remove();
122
- createMessageBubble(`⚠️ Error: ${error.message}`, "Aidan");
123
- } finally {
124
- resetFileInputs();
125
- }
126
  }
127
 
128
- function createMessageBubble(text, sender = "You", audioSrc = null, fileUrl = null) {
129
  const bubble = document.createElement('div');
130
  bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
131
  bubble.style.maxWidth = "50%";
@@ -138,15 +91,19 @@ document.addEventListener('DOMContentLoaded', () => {
138
  const message = document.createElement('div');
139
  message.className = "text";
140
  message.style.whiteSpace = "pre-wrap";
141
- message.innerHTML = text;
 
 
 
 
 
142
 
143
- // Extra controls (audio/PDF download)
144
- if (sender !== "You" && (audioSrc || fileUrl)) {
145
  const iconContainer = document.createElement('div');
146
  iconContainer.style.marginTop = "10px";
147
  iconContainer.style.display = "flex";
148
- iconContainer.style.gap = "15px";
149
  iconContainer.style.justifyContent = "flex-end";
 
150
 
151
  if (audioSrc) {
152
  const audio = new Audio(audioSrc);
@@ -159,21 +116,25 @@ document.addEventListener('DOMContentLoaded', () => {
159
  audioIcon.addEventListener("click", () => {
160
  if (audio.paused) {
161
  audio.play();
162
- audioIcon.title = "Pause Audio";
 
 
163
  } else {
164
  audio.pause();
165
- audioIcon.title = "Play Audio";
 
 
166
  }
167
  });
168
 
169
  iconContainer.appendChild(audioIcon);
170
  }
171
 
172
- if (fileUrl) {
173
  const downloadLink = document.createElement('a');
174
- downloadLink.href = fileUrl;
175
- downloadLink.setAttribute('download', 'summary.pdf');
176
  downloadLink.target = "_blank";
 
177
 
178
  const downloadIcon = document.createElement("i");
179
  downloadIcon.className = "fa-solid fa-file-arrow-down";
@@ -194,10 +155,71 @@ document.addEventListener('DOMContentLoaded', () => {
194
  return bubble;
195
  }
196
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  function resetFileInputs() {
198
  selectedFile = null;
199
  fileUpload.value = '';
200
  imageUpload.value = '';
 
201
  }
202
 
203
  // Loader CSS
@@ -216,6 +238,10 @@ document.addEventListener('DOMContentLoaded', () => {
216
  0% { transform: rotate(0deg); }
217
  100% { transform: rotate(360deg); }
218
  }
 
 
 
 
219
  `;
220
  document.head.appendChild(style);
221
- });
 
11
  const explainChoixDiv = document.getElementById('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
 
58
+ // "Got it" button to hide explanation div
59
+ if (gotItButton) {
60
+ gotItButton.addEventListener('click', () => {
61
+ if (explainChoixDiv) {
62
+ explainChoixDiv.style.display = "none";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
+ });
65
+ }
66
 
67
+ // Send button handlers
68
+ sendButtons.forEach(button => {
69
+ button.addEventListener('click', handleSubmit);
70
+ });
71
 
72
+ function displayFilePreview(file) {
73
+ if (filePreviewBubble) filePreviewBubble.remove();
74
+
75
+ filePreviewBubble = createMessageBubble(
76
+ `πŸ“Ž Selected ${file.type.startsWith('image/') ? 'image' : 'document'}: ${file.name}`,
77
+ "You"
78
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
 
81
+ function createMessageBubble(text, sender = "You", audioSrc = null, fileName = null) {
82
  const bubble = document.createElement('div');
83
  bubble.className = `bubble ${sender === "You" ? "right" : "left"}`;
84
  bubble.style.maxWidth = "50%";
 
91
  const message = document.createElement('div');
92
  message.className = "text";
93
  message.style.whiteSpace = "pre-wrap";
94
+ message.style.display = "flex";
95
+ message.style.flexDirection = "column";
96
+
97
+ const textSpan = document.createElement("span");
98
+ textSpan.innerHTML = text;
99
+ message.appendChild(textSpan);
100
 
101
+ if (sender !== "You" && (audioSrc || fileName)) {
 
102
  const iconContainer = document.createElement('div');
103
  iconContainer.style.marginTop = "10px";
104
  iconContainer.style.display = "flex";
 
105
  iconContainer.style.justifyContent = "flex-end";
106
+ iconContainer.style.gap = "15px";
107
 
108
  if (audioSrc) {
109
  const audio = new Audio(audioSrc);
 
116
  audioIcon.addEventListener("click", () => {
117
  if (audio.paused) {
118
  audio.play();
119
+ audioIcon.classList.remove("fa-volume-xmark");
120
+ audioIcon.classList.add("fa-volume-high");
121
+ audioIcon.title = "Mute Audio";
122
  } else {
123
  audio.pause();
124
+ audioIcon.classList.remove("fa-volume-high");
125
+ audioIcon.classList.add("fa-volume-xmark");
126
+ audioIcon.title = "Unmute Audio";
127
  }
128
  });
129
 
130
  iconContainer.appendChild(audioIcon);
131
  }
132
 
133
+ if (fileName) {
134
  const downloadLink = document.createElement('a');
135
+ downloadLink.href = fileName;
 
136
  downloadLink.target = "_blank";
137
+ downloadLink.download = "summary.pdf"; // βœ… Suggest filename to browser
138
 
139
  const downloadIcon = document.createElement("i");
140
  downloadIcon.className = "fa-solid fa-file-arrow-down";
 
155
  return bubble;
156
  }
157
 
158
+ async function handleSubmit() {
159
+ if (!selectedFile) {
160
+ alert("Please upload a file first");
161
+ return;
162
+ }
163
+
164
+ const isSummarizeMode = document.querySelector('input[name="mode"]:checked').value === 'Summarize';
165
+ const endpoint = isSummarizeMode ? '/summarize/' : '/imagecaption/';
166
+ const thinkingText = isSummarizeMode ? 'Processing document...' : "Generating caption... <div class='loader'></div>";
167
+ const senderName = "Aidan";
168
+
169
+ const thinkingBubble = createMessageBubble(thinkingText, senderName);
170
+
171
+ const formData = new FormData();
172
+ formData.append('file', selectedFile);
173
+ if (isSummarizeMode) formData.append('length', 'medium');
174
+
175
+ try {
176
+ const response = await fetch(endpoint, {
177
+ method: 'POST',
178
+ body: formData
179
+ });
180
+
181
+ if (!response.ok) {
182
+ let errorMessage = 'Request failed';
183
+ try {
184
+ const error = await response.json();
185
+ errorMessage = error.detail || error.error || errorMessage;
186
+ } catch (e) {
187
+ // response not JSON
188
+ }
189
+ throw new Error(errorMessage);
190
+ }
191
+
192
+ const result = await response.json();
193
+ thinkingBubble.remove();
194
+
195
+ if (isSummarizeMode) {
196
+ createMessageBubble(
197
+ result.summary || "No summary generated.",
198
+ "Aidan",
199
+ result.audioUrl,
200
+ result.pdfUrl
201
+ );
202
+ } else {
203
+ createMessageBubble(
204
+ result.caption || result.answer || "No caption generated.",
205
+ "Aidan",
206
+ result.audio,
207
+ null
208
+ );
209
+ }
210
+ } catch (error) {
211
+ thinkingBubble.remove();
212
+ createMessageBubble(`⚠️ Error: ${error.message}`, "Aidan");
213
+ } finally {
214
+ resetFileInputs(); // βœ… Only reset upload inputs, KEEP preview bubble
215
+ }
216
+ }
217
+
218
  function resetFileInputs() {
219
  selectedFile = null;
220
  fileUpload.value = '';
221
  imageUpload.value = '';
222
+ // βœ… DO NOT remove file preview bubble anymore
223
  }
224
 
225
  // Loader CSS
 
238
  0% { transform: rotate(0deg); }
239
  100% { transform: rotate(360deg); }
240
  }
241
+ .audio-toggle {
242
+ cursor: pointer;
243
+ transition: all 0.2s;
244
+ }
245
  `;
246
  document.head.appendChild(style);
247
+ });