diff --git a/public/css/promptmanager.css b/public/css/promptmanager.css index c2c2e3ab8..76d09290b 100644 --- a/public/css/promptmanager.css +++ b/public/css/promptmanager.css @@ -38,6 +38,15 @@ color: var(--white50a); } +#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt_invisible { + display: none; +} + +#completion_prompt_manager #completion_prompt_manager_list .completion_prompt_manager_prompt_visible { + display: grid; +} + + #completion_prompt_manager #completion_prompt_manager_list li.completion_prompt_manager_list_head .prompt_manager_prompt_tokens, #completion_prompt_manager #completion_prompt_manager_list li.completion_prompt_manager_prompt .prompt_manager_prompt_tokens { text-align: right; diff --git a/public/scripts/DraggableList.js b/public/scripts/DraggableList.js deleted file mode 100644 index dd5a27d84..000000000 --- a/public/scripts/DraggableList.js +++ /dev/null @@ -1,127 +0,0 @@ -/** - * Base Module for draggable lists - * - * Markup: - * - */ -function DraggableListModule(listElement, onSwap) { - if (!listElement) return; - - this.list = listElement; - this.onSwap = onSwap; - this.dragged = null; - - this.init(); -} - -DraggableListModule.prototype.init = function () { - this.list.addEventListener("dragstart", (event) => { - if (event.target.className.includes("draggable")) { - this.dragged = event.target; - event.target.style.opacity = '0.5'; - } - }, false); - - this.list.addEventListener("dragend", (event) => { - if (event.target.className.includes("draggable")) { - event.target.style.opacity = ""; - } - }, false); - - this.list.addEventListener("dragover", (event) => { - event.preventDefault(); - const draggable = this.getClosestDraggable(event.target) || this.getClosestDroppable(event.target); - if (draggable) { - const rect = draggable.getBoundingClientRect(); - const overLocation = event.clientY - rect.top; - const halfHeight = rect.height / 2; - if (overLocation < halfHeight) { - draggable.style.background = "linear-gradient(to top, transparent, transparent 75%, rgb(225, 138, 36))"; - } else { - draggable.style.background = "linear-gradient(to bottom, transparent, transparent 75%, rgb(225, 138, 36))"; - } - } - }, false); - - this.list.addEventListener("dragleave", (event) => { - event.preventDefault(); - const draggable = this.getClosestDraggable(event.target) || this.getClosestDroppable(event.target); - if (draggable) draggable.style.background = ""; - - }, false); - - this.list.addEventListener("drop", (event) => { - event.preventDefault(); - const draggable = this.getClosestDraggable(event.target) || this.getClosestDroppable(event.target); - - if (draggable) { - draggable.style.background = ""; - const rect = draggable.getBoundingClientRect(); - const dropLocation = event.clientY - rect.top; - const halfHeight = rect.height / 2; - if (dropLocation < halfHeight) { - this.insertBefore(draggable, this.dragged); - } else { - this.insertAfter(draggable, this.dragged); - } - } - }, false); -} - -DraggableListModule.prototype.getClosestDraggable = function (element) { - return element !== this.list && element.closest('#' + this.list.id) - ? element.closest('.draggable') - : null; -} - -DraggableListModule.prototype.getClosestDroppable = function (element) { - return element !== this.list && element.closest('#' + this.list.id) - ? element.closest('.droppable') - : null; -} - -DraggableListModule.prototype.insertBefore = function (target, origin) { - if (!target || !origin) return; - target.style.background = ""; - origin.style.opacity = ""; - - target.parentNode.insertBefore(origin, target); - - this.onSwap(target, origin, 'before'); -} - -DraggableListModule.prototype.insertAfter = function (target, origin) { - if (!target || !origin) return; - target.style.background = ""; - origin.style.opacity = ""; - - if (target.nextSibling) { - target.parentNode.insertBefore(origin, target.nextSibling); - } else { - target.parentNode.appendChild(origin); - } - - this.onSwap(target, origin, 'after'); -} - -/** - * Draggable Prompt List - */ -function DraggablePromptListModule(listElement, onChange) { - DraggableListModule.call(this, listElement, onChange); -} - -DraggablePromptListModule.prototype = Object.create(DraggableListModule.prototype); - -DraggablePromptListModule.prototype.constructor = DraggablePromptListModule; - -export {DraggablePromptListModule}; diff --git a/public/scripts/PromptManager.js b/public/scripts/PromptManager.js index 2a05e46ef..e1fcde850 100644 --- a/public/scripts/PromptManager.js +++ b/public/scripts/PromptManager.js @@ -1,4 +1,3 @@ -import {DraggablePromptListModule as DraggableList} from "./DraggableList.js"; import {callPopup, event_types, eventSource, substituteParams} from "../script.js"; import {TokenHandler} from "./openai.js"; import {power_user} from "./power-user.js"; @@ -1142,18 +1141,18 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () { if (!prompt) return; const advancedEnabled = this.serviceSettings.prompt_manager_settings.showAdvancedSettings; - let draggableEnabled = true; - if (prompt.system_prompt && !advancedEnabled) draggableEnabled = false; + + let visibleClass = `${prefix}prompt_manager_prompt_visible`; if (prompt.marker && prompt.identifier !== 'newMainChat' && prompt.identifier !== 'chatHistory' && prompt.identifier !== 'characterInfo' && - !advancedEnabled) return; + !advancedEnabled) visibleClass = `${prefix}prompt_manager_prompt_invisible`; const listEntry = this.getPromptListEntry(this.activeCharacter, prompt.identifier); const enabledClass = listEntry.enabled ? '' : `${prefix}prompt_manager_prompt_disabled`; - const draggableClass = draggableEnabled ? 'draggable' : 'droppable'; + const draggableClass = `${prefix}prompt_manager_prompt_draggable`; const markerClass = prompt.marker ? `${prefix}prompt_manager_marker` : ''; const tokens = this.tokenHandler?.getCounts()[prompt.identifier] ?? 0; @@ -1209,7 +1208,7 @@ PromptManagerModule.prototype.renderPromptManagerListItems = function () { } listItemHtml += ` -
  • +
  • ${prompt.marker ? '' : ''} ${!prompt.marker && prompt.system_prompt ? '' : ''} @@ -1368,30 +1367,21 @@ PromptManagerModule.prototype.getFormattedDate = function() { * @returns {void} */ PromptManagerModule.prototype.makeDraggable = function () { - const handleOrderChange = (target, origin, direction) => { - const promptList = this.getPromptListForCharacter(this.activeCharacter); + $('#completion_prompt_manager_list').sortable({ + items: `.${this.configuration.prefix}prompt_manager_prompt_draggable`, + update: ( event, ui ) => { + const promptList = this.getPromptListForCharacter(this.activeCharacter); + const promptOrder = $('#completion_prompt_manager_list').sortable('toArray', {attribute: 'data-pm-identifier'}); + const idToObjectMap = new Map(promptList.map(prompt => [prompt.identifier, prompt])); + const newPromptList = promptOrder.map(identifier => idToObjectMap.get(identifier)); - const targetIndex = promptList.findIndex(entry => entry.identifier === target.dataset.pmIdentifier); - const originIndex = promptList.findIndex(entry => entry.identifier === origin.dataset.pmIdentifier); + this.removePromptListForCharacter(this.activeCharacter); + this.addPromptListForCharacter(this.activeCharacter, newPromptList); - const [entry] = promptList.splice(originIndex, 1); + this.log('Prompt order updated.') - const insertAfter = 'after' === direction; - const newIndex = originIndex < targetIndex ? (insertAfter ? targetIndex : targetIndex - 1) : (insertAfter ? targetIndex + 1 : targetIndex); - promptList.splice(newIndex, 0, entry); - - if (power_user.console_log_prompts) { - // For debugging purpose, fetch the actual position instead of using calculations. - const targetDebug = promptList.findIndex(prompt => prompt.identifier === target.dataset.pmIdentifier); - const originDebug = promptList.findIndex(prompt => prompt.identifier === origin.dataset.pmIdentifier); - - this.log(`Moved ${origin.dataset.pmIdentifier} from position ${originIndex + 1} to position ${originDebug + 1} ${direction} ${target.dataset.pmIdentifier}, which now has position ${targetDebug + 1}`); - - } - this.saveServiceSettings(); - }; - - if (true === this.configuration.draggable) new DraggableList(this.listElement, handleOrderChange); + this.saveServiceSettings(); + }}); }; /**