incognitolm commited on
Commit
132681e
Β·
1 Parent(s): 4768abb

Editing UI

Browse files
Files changed (1) hide show
  1. public/js/chat.js +70 -0
public/js/chat.js CHANGED
@@ -307,6 +307,38 @@ function sendSvg() {
307
 
308
  // ── Inline editing ────────────────────────────────────────────────────────
309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  /**
311
  * User message edit: replaces bubble content with a textarea + toolbar
312
  * (tool toggles + attach) + Cancel/Send buttons.
@@ -325,9 +357,18 @@ function startUserEdit(wrap, index, msg, originalText) {
325
 
326
  // File preview row (for newly attached files during edit)
327
  const editAttachments = [];
 
 
 
 
328
  const filePreviewRow = document.createElement('div');
329
  filePreviewRow.className = 'edit-file-preview-row';
330
  bubble.appendChild(filePreviewRow);
 
 
 
 
 
331
 
332
  // Bottom toolbar: tools + attach on left, cancel+send on right
333
  const toolbar = document.createElement('div');
@@ -357,6 +398,35 @@ function startUserEdit(wrap, index, msg, originalText) {
357
  toolRow.appendChild(btn);
358
  });
359
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
  // Attach button
361
  const attachBtn = document.createElement('button');
362
  attachBtn.className = 'edit-attach-btn';
 
307
 
308
  // ── Inline editing ────────────────────────────────────────────────────────
309
 
310
+ /**
311
+ * Extract image attachments from message content.
312
+ * Message content can be a string or array with image_url objects.
313
+ */
314
+ function extractAttachmentsFromContent(content) {
315
+ if (!content || typeof content === 'string') return [];
316
+ if (!Array.isArray(content)) return [];
317
+
318
+ const attachments = [];
319
+ content.forEach(item => {
320
+ if (item.type === 'image_url' && item.image_url?.url) {
321
+ const dataUrl = item.image_url.url;
322
+ // Parse data URL to get mimeType and base64
323
+ if (dataUrl.startsWith('data:')) {
324
+ const comma = dataUrl.indexOf(',');
325
+ if (comma > 0) {
326
+ const mimeType = dataUrl.slice(5, dataUrl.indexOf(';'));
327
+ const base64 = dataUrl.slice(comma + 1);
328
+ const ext = mimeType.split('/')[1] || 'png';
329
+ attachments.push({
330
+ type: 'image',
331
+ name: `image.${ext}`,
332
+ base64,
333
+ mimeType,
334
+ });
335
+ }
336
+ }
337
+ }
338
+ });
339
+ return attachments;
340
+ }
341
+
342
  /**
343
  * User message edit: replaces bubble content with a textarea + toolbar
344
  * (tool toggles + attach) + Cancel/Send buttons.
 
357
 
358
  // File preview row (for newly attached files during edit)
359
  const editAttachments = [];
360
+ // Populate with existing attachments from the message
361
+ const existingAttachments = extractAttachmentsFromContent(msg.content);
362
+ editAttachments.push(...existingAttachments);
363
+
364
  const filePreviewRow = document.createElement('div');
365
  filePreviewRow.className = 'edit-file-preview-row';
366
  bubble.appendChild(filePreviewRow);
367
+
368
+ // Render existing attachments initially
369
+ if (editAttachments.length > 0) {
370
+ renderEditFilePreview(editAttachments, filePreviewRow);
371
+ }
372
 
373
  // Bottom toolbar: tools + attach on left, cancel+send on right
374
  const toolbar = document.createElement('div');
 
398
  toolRow.appendChild(btn);
399
  });
400
 
401
+ // Add paste event listener to textarea for images
402
+ ta.addEventListener('paste', async (e) => {
403
+ const items = e.clipboardData?.items || [];
404
+ for (const item of items) {
405
+ if (item.type.startsWith('image/')) {
406
+ e.preventDefault();
407
+ const file = item.getAsFile();
408
+ if (file) {
409
+ const dataUrl = await new Promise((res, rej) => {
410
+ const reader = new FileReader();
411
+ reader.onload = () => res(reader.result);
412
+ reader.onerror = rej;
413
+ reader.readAsDataURL(file);
414
+ });
415
+ const comma = dataUrl.indexOf(',');
416
+ const mimeType = dataUrl.slice(5, dataUrl.indexOf(';'));
417
+ const base64 = dataUrl.slice(comma + 1);
418
+ editAttachments.push({
419
+ type: 'image',
420
+ name: file.name || `image.${mimeType.split('/')[1] || 'png'}`,
421
+ base64,
422
+ mimeType,
423
+ });
424
+ renderEditFilePreview(editAttachments, filePreviewRow);
425
+ }
426
+ }
427
+ }
428
+ });
429
+
430
  // Attach button
431
  const attachBtn = document.createElement('button');
432
  attachBtn.className = 'edit-attach-btn';