Merge pull request #2686 from SillyTavern/fix-extensions-toggle Wait for settings before reloading after toggling extensions
Signed| @@ -21,6 +21,7 @@ const defaultUrl = 'http://localhost:5100'; | ||
| 21 | 21 | let saveMetadataTimeout = null; |
| 22 | 22 | |
| 23 | 23 | let requiresReload = false; |
| 24 | +let stateChanged = false; | |
| 24 | 25 | |
| 25 | 26 | export function saveMetadataDebounced() { |
| 26 | 27 | const context = getContext(); |
| @@ -238,6 +239,7 @@ function onEnableExtensionClick() { | ||
| 238 | 239 | |
| 239 | 240 | async function enableExtension(name, reload = true) { |
| 240 | 241 | extension_settings.disabledExtensions = extension_settings.disabledExtensions.filter(x => x !== name); |
| 242 | + stateChanged = true; | |
| 241 | 243 | await saveSettings(); |
| 242 | 244 | if (reload) { |
| 243 | 245 | location.reload(); |
| @@ -248,6 +250,7 @@ async function enableExtension(name, reload = true) { | ||
| 248 | 250 | |
| 249 | 251 | async function disableExtension(name, reload = true) { |
| 250 | 252 | extension_settings.disabledExtensions.push(name); |
| 253 | + stateChanged = true; | |
| 251 | 254 | await saveSettings(); |
| 252 | 255 | if (reload) { |
| 253 | 256 | location.reload(); |
| @@ -657,7 +660,20 @@ async function showExtensionsDetails() { | ||
| 657 | 660 | await oldPopup.complete(POPUP_RESULT.CANCELLED); |
| 658 | 661 | } |
| 659 | 662 | |
| 660 | 663 | const popup = new Popup(html, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, customButtons: [updateAllButton], allowVerticalScrolling: true }); |
| 664 | + okButton: 'Close', | |
| 665 | + wide: true, | |
| 666 | + large: true, | |
| 667 | + customButtons: [updateAllButton], | |
| 668 | + allowVerticalScrolling: true, | |
| 669 | + onClosing: async () => { | |
| 670 | + if (stateChanged) { | |
| 671 | + toastr.info('The page will be reloaded shortly...', 'Extensions state changed'); | |
| 672 | + await saveSettings(); | |
| 673 | + } | |
| 674 | + return true; | |
| 675 | + }, | |
| 676 | + }); | |
| 661 | 677 | popupPromise = popup.show(); |
| 662 | 678 | } catch (error) { |
| 663 | 679 | toastr.error('Error loading extensions. See browser console for details.'); |
| @@ -40,8 +40,8 @@ export const POPUP_RESULT = { | ||
| 40 | 40 | * @property {POPUP_RESULT|number?} [defaultResult=POPUP_RESULT.AFFIRMATIVE] - The default result of this popup when Enter is pressed. Can be changed from `POPUP_RESULT.AFFIRMATIVE`. |
| 41 | 41 | * @property {CustomPopupButton[]|string[]?} [customButtons=null] - Custom buttons to add to the popup. If only strings are provided, the buttons will be added with default options, and their result will be in order from `2` onward. |
| 42 | 42 | * @property {CustomPopupInput[]?} [customInputs=null] - Custom inputs to add to the popup. The display below the content and the input box, one by one. |
| 43 | 43 | * @property {(popup: Popup) => Promise<boolean?>|boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close |
| 44 | 44 | * @property {(popup: Popup) => Promise<void?>|void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up |
| 45 | 45 | * @property {number?} [cropAspect=null] - Aspect ratio for the crop popup |
| 46 | 46 | * @property {string?} [cropImage=null] - Image URL to display in the crop popup |
| 47 | 47 | */ |
| @@ -138,8 +138,8 @@ export class Popup { | ||
| 138 | 138 | /** @readonly @type {CustomPopupButton[]|string[]?} */ customButtons; |
| 139 | 139 | /** @readonly @type {CustomPopupInput[]} */ customInputs; |
| 140 | 140 | |
| 141 | 141 | /** @type {(popup: Popup) => Promise<boolean?>|boolean?} */ onClosing; |
| 142 | 142 | /** @type {(popup: Popup) => Promise<void?>|void?} */ onClose; |
| 143 | 143 | |
| 144 | 144 | /** @type {POPUP_RESULT|number} */ result; |
| 145 | 145 | /** @type {any} */ value; |
| @@ -509,7 +509,7 @@ export class Popup { | ||
| 509 | 509 | this.result = result; |
| 510 | 510 | |
| 511 | 511 | if (this.onClosing) { |
| 512 | 512 | const shouldClose = await this.onClosing(this); |
| 513 | 513 | if (!shouldClose) { |
| 514 | 514 | this.#isClosingPrevented = true; |
| 515 | 515 | // Set values back if we cancel out of closing the popup |
| @@ -547,13 +547,13 @@ export class Popup { | ||
| 547 | 547 | fixToastrForDialogs(); |
| 548 | 548 | |
| 549 | 549 | // After the dialog is actually completely closed, remove it from the DOM |
| 550 | 550 | runAfterAnimation(this.dlg, async () => { |
| 551 | 551 | // Call the close on the dialog |
| 552 | 552 | this.dlg.close(); |
| 553 | 553 | |
| 554 | 554 | // Run a possible custom handler right before DOM removal |
| 555 | 555 | if (this.onClose) { |
| 556 | 556 | await this.onClose(this); |
| 557 | 557 | } |
| 558 | 558 | |
| 559 | 559 | // Remove it from the dom |