| function() {
|
| console.log("[WanGP] main JS initialized");
|
| window.updateAndTrigger = function(action) {
|
| const hiddenTextbox = document.querySelector('#queue_action_input textarea');
|
| const hiddenButton = document.querySelector('#queue_action_trigger');
|
| if (hiddenTextbox && hiddenButton) {
|
| hiddenTextbox.value = action;
|
| hiddenTextbox.dispatchEvent(new Event('input', { bubbles: true }));
|
| hiddenButton.click();
|
| } else {
|
| console.error("Could not find hidden queue action elements.");
|
| }
|
| };
|
|
|
| window.scrollToQueueTop = function() {
|
| const container = document.querySelector('#queue-scroll-container');
|
| if (container) container.scrollTop = 0;
|
| };
|
| window.scrollToQueueBottom = function() {
|
| const container = document.querySelector('#queue-scroll-container');
|
| if (container) container.scrollTop = container.scrollHeight;
|
| };
|
|
|
| window.showImageModal = function(action) {
|
| const hiddenTextbox = document.querySelector('#modal_action_input textarea');
|
| const hiddenButton = document.querySelector('#modal_action_trigger');
|
| if (hiddenTextbox && hiddenButton) {
|
| hiddenTextbox.value = action;
|
| hiddenTextbox.dispatchEvent(new Event('input', { bubbles: true }));
|
| hiddenButton.click();
|
| }
|
| };
|
| window.closeImageModal = function() {
|
| const closeButton = document.querySelector('#modal_close_trigger_btn');
|
| if (closeButton) closeButton.click();
|
| };
|
|
|
| let lastSelectedVideoTime = null;
|
| let selectedVideoTimeTimer = null;
|
|
|
| function pushSelectedVideoTime(currentTime) {
|
| const hiddenTextbox = document.querySelector('#selected_video_time_input textarea, #selected_video_time_input input');
|
| if (!hiddenTextbox) return;
|
| hiddenTextbox.value = String(currentTime);
|
| hiddenTextbox.dispatchEvent(new Event('input', { bubbles: true }));
|
| hiddenTextbox.dispatchEvent(new Event('change', { bubbles: true }));
|
| }
|
|
|
| function scheduleSelectedVideoTimeUpdate(video, immediate = false) {
|
| if (!(video instanceof HTMLVideoElement) || !video.closest('#gallery')) return;
|
| const currentTime = Math.max(0, Math.round(Number(video.currentTime || 0) * 1000) / 1000);
|
| if (!Number.isFinite(currentTime)) return;
|
| const commit = () => {
|
| if (lastSelectedVideoTime === currentTime) return;
|
| lastSelectedVideoTime = currentTime;
|
| pushSelectedVideoTime(currentTime);
|
| };
|
| if (immediate) {
|
| clearTimeout(selectedVideoTimeTimer);
|
| commit();
|
| return;
|
| }
|
| clearTimeout(selectedVideoTimeTimer);
|
| selectedVideoTimeTimer = setTimeout(commit, 180);
|
| }
|
|
|
| function handleGalleryVideoEvent(event, immediate = false) {
|
| const video = event?.target;
|
| if (!(video instanceof HTMLVideoElement) || !video.closest('#gallery')) return;
|
| scheduleSelectedVideoTimeUpdate(video, immediate);
|
| }
|
|
|
| let draggedItem = null;
|
|
|
| function attachDelegatedDragAndDrop(container) {
|
| if (container.dataset.dndDelegated) return;
|
| container.dataset.dndDelegated = 'true';
|
|
|
| container.addEventListener('dragstart', (e) => {
|
| const row = e.target.closest('.draggable-row');
|
| if (!row || e.target.closest('.action-button') || e.target.closest('.hover-image')) {
|
| if (row) e.preventDefault();
|
| return;
|
| }
|
| draggedItem = row;
|
| setTimeout(() => draggedItem.classList.add('dragging'), 0);
|
| });
|
|
|
| container.addEventListener('dragend', () => {
|
| if (draggedItem) {
|
| draggedItem.classList.remove('dragging');
|
| }
|
| draggedItem = null;
|
| document.querySelectorAll('.drag-over-top, .drag-over-bottom').forEach(el => {
|
| el.classList.remove('drag-over-top', 'drag-over-bottom');
|
| });
|
| });
|
|
|
| container.addEventListener('dragover', (e) => {
|
| e.preventDefault();
|
| const targetRow = e.target.closest('.draggable-row');
|
|
|
| document.querySelectorAll('.drag-over-top, .drag-over-bottom').forEach(el => {
|
| el.classList.remove('drag-over-top', 'drag-over-bottom');
|
| });
|
|
|
| if (targetRow && draggedItem && targetRow !== draggedItem) {
|
| const rect = targetRow.getBoundingClientRect();
|
| const midpoint = rect.top + rect.height / 2;
|
|
|
| if (e.clientY < midpoint) {
|
| targetRow.classList.add('drag-over-top');
|
| } else {
|
| targetRow.classList.add('drag-over-bottom');
|
| }
|
| }
|
| });
|
|
|
| container.addEventListener('drop', (e) => {
|
| e.preventDefault();
|
| const targetRow = e.target.closest('.draggable-row');
|
| if (!draggedItem || !targetRow || targetRow === draggedItem) return;
|
|
|
| const oldIndex = draggedItem.dataset.index;
|
| let newIndex = parseInt(targetRow.dataset.index);
|
|
|
| if (targetRow.classList.contains('drag-over-bottom')) {
|
| newIndex++;
|
| }
|
|
|
| if (oldIndex != newIndex) {
|
| const action = `move_${oldIndex}_to_${newIndex}`;
|
| window.updateAndTrigger(action);
|
| }
|
| });
|
| }
|
|
|
| const observer = new MutationObserver((mutations, obs) => {
|
| const container = document.querySelector('#queue_html_container');
|
| if (container) {
|
| attachDelegatedDragAndDrop(container);
|
| obs.disconnect();
|
| }
|
| });
|
|
|
| const targetNode = document.querySelector('gradio-app');
|
| if (targetNode) {
|
| observer.observe(targetNode, { childList: true, subtree: true });
|
| ['loadedmetadata', 'seeked', 'pause', 'click'].forEach((eventName) => {
|
| document.addEventListener(eventName, (event) => handleGalleryVideoEvent(event, true), true);
|
| });
|
| document.addEventListener('timeupdate', (event) => handleGalleryVideoEvent(event, false), true);
|
| }
|
|
|
| const hit = n => n?.id === "img_editor" || n?.classList?.contains("wheel-pass");
|
| addEventListener("wheel", e => {
|
| const path = e.composedPath?.() || (() => { let a=[],n=e.target; for(;n;n=n.parentNode||n.host) a.push(n); return a; })();
|
| if (path.some(hit)) e.stopImmediatePropagation();
|
| }, { capture: true, passive: true });
|
|
|