Merge pull request #2686 from SillyTavern/fix-extensions-toggle Wait for settings before reloading after toggling extensions

3167c85791b2ebf8708e45ebff6aa9b6fe4a8dfc

Wolfsblvt <wolfsblvt@gmail.com>

Signed
2 files changed, +24 -8Showing whitespace changes
public/scripts/extensions.js+17 -1
@@ -21,6 +21,7 @@ const defaultUrl = 'http://localhost:5100';
21let saveMetadataTimeout = null;21let saveMetadataTimeout = null;
2222
23let requiresReload = false;23let requiresReload = false;
24let stateChanged = false;
2425
25export function saveMetadataDebounced() {26export function saveMetadataDebounced() {
26 const context = getContext();27 const context = getContext();
@@ -238,6 +239,7 @@ function onEnableExtensionClick() {
238239
239async function enableExtension(name, reload = true) {240async function enableExtension(name, reload = true) {
240 extension_settings.disabledExtensions = extension_settings.disabledExtensions.filter(x => x !== name);241 extension_settings.disabledExtensions = extension_settings.disabledExtensions.filter(x => x !== name);
242 stateChanged = true;
241 await saveSettings();243 await saveSettings();
242 if (reload) {244 if (reload) {
243 location.reload();245 location.reload();
@@ -248,6 +250,7 @@ async function enableExtension(name, reload = true) {
248250
249async function disableExtension(name, reload = true) {251async function disableExtension(name, reload = true) {
250 extension_settings.disabledExtensions.push(name);252 extension_settings.disabledExtensions.push(name);
253 stateChanged = true;
251 await saveSettings();254 await saveSettings();
252 if (reload) {255 if (reload) {
253 location.reload();256 location.reload();
@@ -657,7 +660,20 @@ async function showExtensionsDetails() {
657 await oldPopup.complete(POPUP_RESULT.CANCELLED);660 await oldPopup.complete(POPUP_RESULT.CANCELLED);
658 }661 }
659662
660 const popup = new Popup(html, POPUP_TYPE.TEXT, '', { okButton: 'Close', wide: true, large: true, customButtons: [updateAllButton], allowVerticalScrolling: true });663 const popup = new Popup(html, POPUP_TYPE.TEXT, '', {
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 popupPromise = popup.show();677 popupPromise = popup.show();
662 } catch (error) {678 } catch (error) {
663 toastr.error('Error loading extensions. See browser console for details.');679 toastr.error('Error loading extensions. See browser console for details.');
public/scripts/popup.js+7 -7
@@ -40,8 +40,8 @@ export const POPUP_RESULT = {
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`.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 * @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.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 * @property {CustomPopupInput[]?} [customInputs=null] - Custom inputs to add to the popup. The display below the content and the input box, one by one.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 * @property {(popup: Popup) => boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close43 * @property {(popup: Popup) => Promise<boolean?>|boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close
44 * @property {(popup: Popup) => void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up44 * @property {(popup: Popup) => Promise<void?>|void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up
45 * @property {number?} [cropAspect=null] - Aspect ratio for the crop popup45 * @property {number?} [cropAspect=null] - Aspect ratio for the crop popup
46 * @property {string?} [cropImage=null] - Image URL to display in the crop popup46 * @property {string?} [cropImage=null] - Image URL to display in the crop popup
47 */47 */
@@ -138,8 +138,8 @@ export class Popup {
138 /** @readonly @type {CustomPopupButton[]|string[]?} */ customButtons;138 /** @readonly @type {CustomPopupButton[]|string[]?} */ customButtons;
139 /** @readonly @type {CustomPopupInput[]} */ customInputs;139 /** @readonly @type {CustomPopupInput[]} */ customInputs;
140140
141 /** @type {(popup: Popup) => boolean?} */ onClosing;141 /** @type {(popup: Popup) => Promise<boolean?>|boolean?} */ onClosing;
142 /** @type {(popup: Popup) => void?} */ onClose;142 /** @type {(popup: Popup) => Promise<void?>|void?} */ onClose;
143143
144 /** @type {POPUP_RESULT|number} */ result;144 /** @type {POPUP_RESULT|number} */ result;
145 /** @type {any} */ value;145 /** @type {any} */ value;
@@ -509,7 +509,7 @@ export class Popup {
509 this.result = result;509 this.result = result;
510510
511 if (this.onClosing) {511 if (this.onClosing) {
512 const shouldClose = this.onClosing(this);512 const shouldClose = await this.onClosing(this);
513 if (!shouldClose) {513 if (!shouldClose) {
514 this.#isClosingPrevented = true;514 this.#isClosingPrevented = true;
515 // Set values back if we cancel out of closing the popup515 // Set values back if we cancel out of closing the popup
@@ -547,13 +547,13 @@ export class Popup {
547 fixToastrForDialogs();547 fixToastrForDialogs();
548548
549 // After the dialog is actually completely closed, remove it from the DOM549 // After the dialog is actually completely closed, remove it from the DOM
550 runAfterAnimation(this.dlg, () => {550 runAfterAnimation(this.dlg, async () => {
551 // Call the close on the dialog551 // Call the close on the dialog
552 this.dlg.close();552 this.dlg.close();
553553
554 // Run a possible custom handler right before DOM removal554 // Run a possible custom handler right before DOM removal
555 if (this.onClose) {555 if (this.onClose) {
556 this.onClose(this);556 await this.onClose(this);
557 }557 }
558558
559 // Remove it from the dom559 // Remove it from the dom