Fix gallery duplicate uploads
| @@ -16,6 +16,8 @@ declare var ai; | ||
| 16 | 16 | |
| 17 | 17 | // Jquery plugins |
| 18 | 18 | interface JQuery { |
| 19 | + nanogallery2(options?: any): JQuery; | |
| 20 | + nanogallery2(method: string, options?: any): JQuery; | |
| 19 | 21 | pagination(method: 'getCurrentPageNum'): number; |
| 20 | 22 | pagination(method: string, options?: any): JQuery; |
| 21 | 23 | pagination(options?: any): JQuery; |
| @@ -3,6 +3,7 @@ import { | ||
| 3 | 3 | this_chid, |
| 4 | 4 | characters, |
| 5 | 5 | getRequestHeaders, |
| 6 | + event_types, | |
| 6 | 7 | } from '../../../script.js'; |
| 7 | 8 | import { groups, selected_group } from '../../group-chats.js'; |
| 8 | 9 | import { loadFileToDocument, delay } from '../../utils.js'; |
| @@ -25,6 +26,27 @@ let paginationVisiblePages = 10; | ||
| 25 | 26 | let paginationMaxLinesPerPage = 2; |
| 26 | 27 | let galleryMaxRows = 3; |
| 27 | 28 | |
| 29 | +$('body').on('click', '.dragClose', function () { | |
| 30 | + const relatedId = $(this).data('related-id'); // Get the ID of the related draggable | |
| 31 | + $(`body > .draggable[id="${relatedId}"]`).remove(); // Remove the associated draggable | |
| 32 | +}); | |
| 33 | + | |
| 34 | +const CUSTOM_GALLERY_REMOVED_EVENT = 'galleryRemoved'; | |
| 35 | + | |
| 36 | +const mutationObserver = new MutationObserver((mutations) => { | |
| 37 | + mutations.forEach((mutation) => { | |
| 38 | + mutation.removedNodes.forEach((node) => { | |
| 39 | + if (node instanceof HTMLElement && node.tagName === 'DIV' && node.id === 'gallery') { | |
| 40 | + eventSource.emit(CUSTOM_GALLERY_REMOVED_EVENT); | |
| 41 | + } | |
| 42 | + }); | |
| 43 | + }); | |
| 44 | +}); | |
| 45 | + | |
| 46 | +mutationObserver.observe(document.body, { | |
| 47 | + childList: true, | |
| 48 | + subtree: false, | |
| 49 | +}); | |
| 28 | 50 | |
| 29 | 51 | /** |
| 30 | 52 | * Retrieves a list of gallery items based on a given URL. This function calls an API endpoint |
| @@ -59,7 +81,9 @@ async function getGalleryItems(url) { | ||
| 59 | 81 | * @returns {Promise<void>} - Promise representing the completion of the gallery initialization. |
| 60 | 82 | */ |
| 61 | 83 | async function initGallery(items, url) { |
| 84 | + const nonce = `nonce-${Math.random().toString(36).substring(2, 15)}`; | |
| 62 | 85 | const gallery = $('#dragGallery'); |
| 86 | + gallery.addClass(nonce); | |
| 63 | 87 | gallery.nanogallery2({ |
| 64 | 88 | 'items': items, |
| 65 | 89 | thumbnailWidth: 'auto', |
| @@ -82,16 +106,26 @@ async function initGallery(items, url) { | ||
| 82 | 106 | fnThumbnailOpen: viewWithDragbox, |
| 83 | 107 | }); |
| 84 | 108 | |
| 109 | + const dragDropHandler = new DragAndDropHandler(`#dragGallery.${nonce}`, async (files, event) => { | |
| 110 | + let file = files[0]; | |
| 111 | + uploadFile(file, url); // Added url parameter to know where to upload | |
| 112 | + }); | |
| 85 | 113 | |
| 86 | 114 | eventSource.on('resizeUI',const resizeHandler = function (elmntName) { |
| 87 | 115 | gallery.nanogallery2('resize'); |
| 88 | 116 | }); |
| 89 | 117 | |
| 90 | - const dragDropHandler = new DragAndDropHandler('#dragGallery', async (files, event) => { | |
| 118 | + eventSource.on('resizeUI', resizeHandler); | |
| 91 | - let file = files[0]; | |
| 119 | + | |
| 92 | - uploadFile(file, url); // Added url parameter to know where to upload | |
| 120 | + eventSource.once(event_types.CHAT_CHANGED, function () { | |
| 121 | + gallery.closest('#gallery').remove(); | |
| 93 | 122 | }); |
| 94 | 123 | |
| 124 | + eventSource.once(CUSTOM_GALLERY_REMOVED_EVENT, function () { | |
| 125 | + gallery.nanogallery2('destroy'); | |
| 126 | + dragDropHandler.destroy(); | |
| 127 | + eventSource.removeListener('resizeUI', resizeHandler); | |
| 128 | + }); | |
| 95 | 129 | |
| 96 | 130 | // Set dropzone height to be the same as the parent |
| 97 | 131 | gallery.css('height', gallery.parent().css('height')); |
| @@ -140,16 +174,10 @@ async function showCharGallery() { | ||
| 140 | 174 | |
| 141 | 175 | const items = await getGalleryItems(url); |
| 142 | 176 | // if there already is a gallery, destroy it and place this one in its place |
| 143 | 177 | if ($('#dragGallery').lengthclosest('#gallery') {.remove(); |
| 144 | - $('#dragGallery').nanogallery2('destroy'); | |
| 145 | - initGallery(items, url); | |
| 146 | - } else { | |
| 147 | 178 | makeMovable(); |
| 148 | - setTimeout(async () => { | |
| 179 | + await delay(100); | |
| 149 | 180 | await initGallery(items, url); |
| 150 | - }, 100); | |
| 151 | - } | |
| 152 | - | |
| 153 | 181 | } catch (err) { |
| 154 | 182 | console.trace(); |
| 155 | 183 | console.error(err); |
| @@ -202,11 +230,11 @@ async function uploadFile(file, url) { | ||
| 202 | 230 | toastr.success('File uploaded successfully. Saved at: ' + result.path); |
| 203 | 231 | |
| 204 | 232 | // Refresh the gallery |
| 205 | - $('#dragGallery').nanogallery2('destroy'); // Destroy old gallery | |
| 206 | 233 | const newItems = await getGalleryItems(url); // Fetch the latest items |
| 207 | - initGallery(newItems, url); // Reinitialize the gallery with new items and pass 'url' | |
| 234 | + $('#dragGallery').closest('#gallery').remove(); // Destroy old gallery | |
| 208 | - | |
| 235 | + makeMovable(); | |
| 209 | - | |
| 236 | + await delay(100); | |
| 237 | + await initGallery(newItems, url); // Reinitialize the gallery with new items and pass 'url' | |
| 210 | 238 | } catch (error) { |
| 211 | 239 | console.error('There was an issue uploading the file:', error); |
| 212 | 240 | |
| @@ -273,11 +301,6 @@ function makeMovable(id = 'gallery') { | ||
| 273 | 301 | e.preventDefault(); |
| 274 | 302 | return false; |
| 275 | 303 | }); |
| 276 | - | |
| 277 | - $('body').on('click', '.dragClose', function () { | |
| 278 | - const relatedId = $(this).data('related-id'); // Get the ID of the related draggable | |
| 279 | - $(`#${relatedId}`).remove(); // Remove the associated draggable | |
| 280 | - }); | |
| 281 | 304 | } |
| 282 | 305 | |
| 283 | 306 | /** |
| @@ -358,11 +381,6 @@ function makeDragImg(id, url) { | ||
| 358 | 381 | } else { |
| 359 | 382 | console.error('Failed to append the template content or retrieve the appended content.'); |
| 360 | 383 | } |
| 361 | - | |
| 362 | - $('body').on('click', '.dragClose', function () { | |
| 363 | - const relatedId = $(this).data('related-id'); // Get the ID of the related draggable | |
| 364 | - $(`#${relatedId}`).remove(); // Remove the associated draggable | |
| 365 | - }); | |
| 366 | 384 | } |
| 367 | 385 | |
| 368 | 386 | /** |
| @@ -401,7 +419,8 @@ function viewWithDragbox(items) { | ||
| 401 | 419 | |
| 402 | 420 | |
| 403 | 421 | // Registers a simple command for opening the char gallery. |
| 404 | 422 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'show-gallery', |
| 423 | + name: 'show-gallery', | |
| 405 | 424 | aliases: ['sg'], |
| 406 | 425 | callback: () => { |
| 407 | 426 | showCharGallery(); |
| @@ -409,7 +428,8 @@ SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'show-gallery | ||
| 409 | 428 | }, |
| 410 | 429 | helpString: 'Shows the gallery.', |
| 411 | 430 | })); |
| 412 | 431 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'list-gallery', |
| 432 | + name: 'list-gallery', | |
| 413 | 433 | aliases: ['lg'], |
| 414 | 434 | callback: listGalleryCommand, |
| 415 | 435 | returns: 'list of images', |