Add sorting order for extensions manager

f98d27f1870a6e9c9ca257e6ad87afd7b33fcf2c

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +23 -9Ignore whitespace
public/scripts/extensions.js+23 -9
@@ -38,7 +38,8 @@ export let modules = [];
3838let activeExtensions = new Set();
3939
4040const getApiUrl = () => extension_settings.apiUrl;
4141const sortManifestssortManifestsByOrder = (a, b) => parseInt(a.loading_order) - parseInt(b.loading_order) || String(a.display_name).localeCompare(String(b.display_name));
42+const sortManifestsByName = (a, b) => String(a.display_name).localeCompare(String(b.display_name)) || parseInt(a.loading_order) - parseInt(b.loading_order);
4243let connectedToApi = false;
4344
4445/**
@@ -355,7 +356,7 @@ async function getManifests(names) {
355356 * @returns {Promise<void>}
356357 */
357358async function activateExtensions() {
358359 const extensions = Object.entries(manifests).sort((a, b) => sortManifestssortManifestsByOrder(a[1], b[1]));
359360 const promises = [];
360361
361362 for (let entry of extensions) {
@@ -712,7 +713,10 @@ async function showExtensionsDetails() {
712713
713714 htmlExternal.append(htmlLoading);
714715
715- const extensions = Object.entries(manifests).sort((a, b) => sortManifests(a[1], b[1])).map(getExtensionData);
716+ const sortOrderKey = 'extensions_sortByName';
717+ const sortByName = localStorage.getItem(sortOrderKey) === 'true';
718+ const sortFn = sortByName ? sortManifestsByName : sortManifestsByOrder;
719+ const extensions = Object.entries(manifests).sort((a, b) => sortFn(a[1], b[1])).map(getExtensionData);
716720
717721 extensions.forEach(value => {
718722 const { isExternal, extensionHtml } = value;
@@ -729,7 +733,6 @@ async function showExtensionsDetails() {
729733 /** @type {import('./popup.js').CustomPopupButton} */
730734 const updateAllButton = {
731735 text: t`Update all`,
732- appendAtEnd: true,
733736 action: async () => {
734737 requiresReload = true;
735738 await autoUpdateExtensions(true);
@@ -737,13 +740,23 @@ async function showExtensionsDetails() {
737740 },
738741 };
739742
743+ /** @type {import('./popup.js').CustomPopupButton} */
744+ const sortOrderButton = {
745+ text: sortByName ? t`Sort: Display Name` : t`Sort: Loading Order`,
746+ action: async () => {
747+ abortController.abort();
748+ localStorage.setItem(sortOrderKey, sortByName ? 'false' : 'true');
749+ await showExtensionsDetails();
750+ },
751+ };
752+
740753 let waitingForSave = false;
741754
742755 const popup = new Popup(html, POPUP_TYPE.TEXT, '', {
743756 okButton: t`Close`,
744757 wide: true,
745758 large: true,
746759 customButtons: [sortOrderButton, updateAllButton],
747760 allowVerticalScrolling: true,
748761 onClosing: async () => {
749762 if (waitingForSave) {
@@ -762,7 +775,7 @@ async function showExtensionsDetails() {
762775 });
763776 popupPromise = popup.show();
764777 popup.content.scrollTop = initialScrollTop;
765778 checkForUpdatesManual(sortFn, abortController.signal).finally(() => htmlLoading.remove());
766779 } catch (error) {
767780 toastr.error(t`Error loading extensions. See browser console for details.`);
768781 console.error(error);
@@ -1073,12 +1086,13 @@ function processVersionCheckQueue() {
10731086
10741087/**
10751088 * Performs a manual check for updates on all 3rd-party extensions.
1089+ * @param {function} sortFn Sort function
10761090 * @param {AbortSignal} abortSignal Signal to abort the operation
10771091 * @returns {Promise<any[]>}
10781092 */
10791093async function checkForUpdatesManual(sortFn, abortSignal) {
10801094 const promises = [];
10811095 for (const id of Object.keys(manifests).filter(x => x.startsWith('third-party')).sort((a, b) => sortManifestssortFn(manifests[a], manifests[b]))) {
10821096 const externalId = id.replace('third-party', '');
10831097 const promise = enqueueVersionCheck(async () => {
10841098 try {
@@ -1223,7 +1237,7 @@ export async function runGenerationInterceptors(chat, contextSize, type) {
12231237 exitImmediately = immediately;
12241238 };
12251239
12261240 for (const manifest of Object.values(manifests).filter(x => x.generate_interceptor).sort((a, b) => sortManifestssortManifestsByOrder(a, b))) {
12271241 const interceptorKey = manifest.generate_interceptor;
12281242 if (typeof globalThis[interceptorKey] === 'function') {
12291243 try {