From 189895bd01651ad0c3f0010bb96dce1a8053e7d2 Mon Sep 17 00:00:00 2001 From: city-unit <140349364+city-unit@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:16:10 -0400 Subject: [PATCH] Just added uploading via drag/drop --- public/scripts/extensions/gallery/index.js | 124 +++++++++++++++++++-- 1 file changed, 115 insertions(+), 9 deletions(-) diff --git a/public/scripts/extensions/gallery/index.js b/public/scripts/extensions/gallery/index.js index e6e023565..49cc58718 100644 --- a/public/scripts/extensions/gallery/index.js +++ b/public/scripts/extensions/gallery/index.js @@ -3,6 +3,7 @@ import { this_chid, characters, callPopup, + getRequestHeaders, } from "../../../script.js"; import { selected_group } from "../../group-chats.js"; import { loadFileToDocument } from "../../utils.js"; @@ -34,9 +35,54 @@ async function getGalleryItems(url) { } /** - * Displays a character gallery. The gallery is initialized using the nanogallery2 library. - * This function takes care of preparing the gallery items, loading necessary resources, - * and ensuring body position is correctly set. + * Initializes a gallery using the provided items and sets up the drag-and-drop functionality. + * It uses the nanogallery2 library to display the items and also initializes + * event listeners to handle drag-and-drop of files onto the gallery. + * + * @param {Array} items - An array of objects representing the items to display in the gallery. + * @param {string} url - The URL to use when a file is dropped onto the gallery for uploading. + * @returns {Promise} - Promise representing the completion of the gallery initialization. + */ +async function initGallery(items, url) { + $("#my-gallery").nanogallery2({ + items: items, + thumbnailHeight: 150, + thumbnailWidth: 150, + }); + + // Initialize dropzone handlers + const dropZone = $('#dialogue_popup'); + dropZone.on('dragover', function (e) { + e.stopPropagation(); // Ensure this event doesn't propagate + e.preventDefault(); + $(this).addClass('dragging'); // Add a CSS class to change appearance during drag-over + }); + + dropZone.on('dragleave', function (e) { + e.stopPropagation(); // Ensure this event doesn't propagate + $(this).removeClass('dragging'); + }); + + dropZone.on('drop', function (e) { + e.stopPropagation(); // Ensure this event doesn't propagate + e.preventDefault(); + $(this).removeClass('dragging'); + let file = e.originalEvent.dataTransfer.files[0]; + uploadFile(file, url); // Added url parameter to know where to upload + }); +} + +/** + * Displays a character gallery using the nanogallery2 library. + * + * This function takes care of: + * - Loading necessary resources for the gallery on the first invocation. + * - Preparing gallery items based on the character or group selection. + * - Handling the drag-and-drop functionality for image upload. + * - Displaying the gallery in a popup. + * - Cleaning up resources when the gallery popup is closed. + * + * @returns {Promise} - Promise representing the completion of the gallery display process. */ async function showCharGallery() { // Load necessary files if it's the first time calling the function @@ -62,16 +108,13 @@ async function showCharGallery() { const items = await getGalleryItems(url); let close = callPopup('', "text"); + console.log("close", close); if ($("body").css("position") === "fixed") { $("body").css("position", "static"); } - setTimeout(() => { - $("#my-gallery").nanogallery2({ - items: items, - thumbnailHeight: 150, - thumbnailWidth: 150, - }); + setTimeout(async () => { + await initGallery(items, url); }, 100); close.then(() => { @@ -79,12 +122,75 @@ async function showCharGallery() { if ($("body").css("position") === "static") { $("body").css("position", "fixed"); } + const dropZone = $('#dialogue_popup'); + dropZone.off('dragover dragleave drop'); }); } catch (err) { console.error(err); } } +/** + * Uploads a given file to a specified URL. + * Once the file is uploaded, it provides a success message using toastr, + * destroys the existing gallery, fetches the latest items, and reinitializes the gallery. + * + * @param {File} file - The file object to be uploaded. + * @param {string} url - The URL indicating where the file should be uploaded. + * @returns {Promise} - Promise representing the completion of the file upload and gallery refresh. + */ +async function uploadFile(file, url) { + // Convert the file to a base64 string + const reader = new FileReader(); + reader.onloadend = async function () { + const base64Data = reader.result; + + // Create the payload + const payload = { + image: base64Data + }; + + // Add the ch_name from the provided URL (assuming it's the character name) + payload.ch_name = url; + + try { + const headers = await getRequestHeaders(); + + // Merge headers with content-type for JSON + Object.assign(headers, { + 'Content-Type': 'application/json' + }); + + const response = await fetch('/uploadimage', { + method: 'POST', + headers: headers, + body: JSON.stringify(payload) + }); + + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + + const result = await response.json(); + + toastr.success('File uploaded successfully. Saved at: ' + result.path); + + // Refresh the gallery + $("#my-gallery").nanogallery2("destroy"); // Destroy old gallery + const newItems = await getGalleryItems(url); // Fetch the latest items + initGallery(newItems, url); // Reinitialize the gallery with new items and pass 'url' + + + } catch (error) { + console.error("There was an issue uploading the file:", error); + + // Replacing alert with toastr error notification + toastr.error('Failed to upload the file.'); + } + } + reader.readAsDataURL(file); +} + $(document).ready(function () { // Register an event listener eventSource.on("charManagementDropdown", (selectedOptionId) => {