From f98d27f1870a6e9c9ca257e6ad87afd7b33fcf2c Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:59:41 +0200 Subject: [PATCH] Add sorting order for extensions manager --- public/scripts/extensions.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index e8da94a6f..c0ba05067 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -38,7 +38,8 @@ export let modules = []; let activeExtensions = new Set(); const getApiUrl = () => extension_settings.apiUrl; -const sortManifests = (a, b) => parseInt(a.loading_order) - parseInt(b.loading_order) || String(a.display_name).localeCompare(String(b.display_name)); +const sortManifestsByOrder = (a, b) => parseInt(a.loading_order) - parseInt(b.loading_order) || String(a.display_name).localeCompare(String(b.display_name)); +const sortManifestsByName = (a, b) => String(a.display_name).localeCompare(String(b.display_name)) || parseInt(a.loading_order) - parseInt(b.loading_order); let connectedToApi = false; /** @@ -355,7 +356,7 @@ async function getManifests(names) { * @returns {Promise} */ async function activateExtensions() { - const extensions = Object.entries(manifests).sort((a, b) => sortManifests(a[1], b[1])); + const extensions = Object.entries(manifests).sort((a, b) => sortManifestsByOrder(a[1], b[1])); const promises = []; for (let entry of extensions) { @@ -712,7 +713,10 @@ async function showExtensionsDetails() { htmlExternal.append(htmlLoading); - const extensions = Object.entries(manifests).sort((a, b) => sortManifests(a[1], b[1])).map(getExtensionData); + const sortOrderKey = 'extensions_sortByName'; + const sortByName = localStorage.getItem(sortOrderKey) === 'true'; + const sortFn = sortByName ? sortManifestsByName : sortManifestsByOrder; + const extensions = Object.entries(manifests).sort((a, b) => sortFn(a[1], b[1])).map(getExtensionData); extensions.forEach(value => { const { isExternal, extensionHtml } = value; @@ -729,7 +733,6 @@ async function showExtensionsDetails() { /** @type {import('./popup.js').CustomPopupButton} */ const updateAllButton = { text: t`Update all`, - appendAtEnd: true, action: async () => { requiresReload = true; await autoUpdateExtensions(true); @@ -737,13 +740,23 @@ async function showExtensionsDetails() { }, }; + /** @type {import('./popup.js').CustomPopupButton} */ + const sortOrderButton = { + text: sortByName ? t`Sort: Display Name` : t`Sort: Loading Order`, + action: async () => { + abortController.abort(); + localStorage.setItem(sortOrderKey, sortByName ? 'false' : 'true'); + await showExtensionsDetails(); + }, + }; + let waitingForSave = false; const popup = new Popup(html, POPUP_TYPE.TEXT, '', { okButton: t`Close`, wide: true, large: true, - customButtons: [updateAllButton], + customButtons: [sortOrderButton, updateAllButton], allowVerticalScrolling: true, onClosing: async () => { if (waitingForSave) { @@ -762,7 +775,7 @@ async function showExtensionsDetails() { }); popupPromise = popup.show(); popup.content.scrollTop = initialScrollTop; - checkForUpdatesManual(abortController.signal).finally(() => htmlLoading.remove()); + checkForUpdatesManual(sortFn, abortController.signal).finally(() => htmlLoading.remove()); } catch (error) { toastr.error(t`Error loading extensions. See browser console for details.`); console.error(error); @@ -1073,12 +1086,13 @@ function processVersionCheckQueue() { /** * Performs a manual check for updates on all 3rd-party extensions. + * @param {function} sortFn Sort function * @param {AbortSignal} abortSignal Signal to abort the operation * @returns {Promise} */ -async function checkForUpdatesManual(abortSignal) { +async function checkForUpdatesManual(sortFn, abortSignal) { const promises = []; - for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party')).sort((a, b) => sortManifests(manifests[a], manifests[b]))) { + for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party')).sort((a, b) => sortFn(manifests[a], manifests[b]))) { const externalId = id.replace('third-party', ''); const promise = enqueueVersionCheck(async () => { try { @@ -1223,7 +1237,7 @@ export async function runGenerationInterceptors(chat, contextSize, type) { exitImmediately = immediately; }; - for (const manifest of Object.values(manifests).filter(x => x.generate_interceptor).sort((a, b) => sortManifests(a, b))) { + for (const manifest of Object.values(manifests).filter(x => x.generate_interceptor).sort((a, b) => sortManifestsByOrder(a, b))) { const interceptorKey = manifest.generate_interceptor; if (typeof globalThis[interceptorKey] === 'function') { try {