Merge pull request #4117 from SillyTavern/goodbye-isSaveWorldInfoDisabled Add skip save checks to all on-init event handlers
Signed| @@ -86,7 +86,6 @@ const saveSettingsDebounced = debounce(() => { | |||
| 86 | }, debounce_timeout.relaxed); | 86 | }, debounce_timeout.relaxed); |
| 87 | const sortFn = (a, b) => b.order - a.order; | 87 | const sortFn = (a, b) => b.order - a.order; |
| 88 | let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); }; | 88 | let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); }; |
| 89 | let isSaveWorldInfoDisabled = false; | ||
| 90 | 89 | ||
| 91 | // Do not optimize. updateEditor is a function that is updated by the displayWorldEntries with new data. | 90 | // Do not optimize. updateEditor is a function that is updated by the displayWorldEntries with new data. |
| 92 | export const worldInfoFilter = new FilterHelper(() => updateEditor()); | 91 | export const worldInfoFilter = new FilterHelper(() => updateEditor()); |
| @@ -2102,8 +2101,6 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no | |||
| 2102 | showNavigator: true, | 2101 | showNavigator: true, |
| 2103 | callback: async function (/** @type {object[]} */ page) { | 2102 | callback: async function (/** @type {object[]} */ page) { |
| 2104 | try { | 2103 | try { |
| 2105 | // Prevent saveWorldInfo from firing timeouts while rendering the list | ||
| 2106 | isSaveWorldInfoDisabled = true; | ||
| 2107 | clearEntryList(worldEntriesList); | 2104 | clearEntryList(worldEntriesList); |
| 2108 | 2105 | ||
| 2109 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); | 2106 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); |
| @@ -2131,8 +2128,6 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no | |||
| 2131 | worldEntriesList.append(blocks); | 2128 | worldEntriesList.append(blocks); |
| 2132 | } catch (error) { | 2129 | } catch (error) { |
| 2133 | console.error('Error while rendering WI entries:', error); | 2130 | console.error('Error while rendering WI entries:', error); |
| 2134 | } finally { | ||
| 2135 | isSaveWorldInfoDisabled = false; | ||
| 2136 | } | 2131 | } |
| 2137 | }, | 2132 | }, |
| 2138 | afterSizeSelectorChange: function (e) { | 2133 | afterSizeSelectorChange: function (e) { |
| @@ -2635,14 +2630,14 @@ function handleMatchCheckboxHelper({ template, entry, fieldName, data, name }) { | |||
| 2635 | const key = originalWIDataKeyMap[fieldName]; | 2630 | const key = originalWIDataKeyMap[fieldName]; |
| 2636 | const checkBoxElem = template.find(`input[type="checkbox"][name="${fieldName}"]`); | 2631 | const checkBoxElem = template.find(`input[type="checkbox"][name="${fieldName}"]`); |
| 2637 | checkBoxElem.data('uid', entry.uid); | 2632 | checkBoxElem.data('uid', entry.uid); |
| 2638 | checkBoxElem.on('input', async function () { | 2633 | checkBoxElem.on('input', async function (_, { noSave = false } = {}) { |
| 2639 | const uid = $(this).data('uid'); | 2634 | const uid = $(this).data('uid'); |
| 2640 | const value = $(this).prop('checked'); | 2635 | const value = $(this).prop('checked'); |
| 2641 | data.entries[uid][fieldName] = value; | 2636 | data.entries[uid][fieldName] = value; |
| 2642 | setWIOriginalDataValue(data, uid, key, data.entries[uid][fieldName]); | 2637 | setWIOriginalDataValue(data, uid, key, data.entries[uid][fieldName]); |
| 2643 | await saveWorldInfo(name, data); | 2638 | !noSave && await saveWorldInfo(name, data); |
| 2644 | }); | 2639 | }); |
| 2645 | checkBoxElem.prop('checked', !!entry[fieldName]).trigger('input'); | 2640 | checkBoxElem.prop('checked', !!entry[fieldName]).trigger('input', { noSave: true }); |
| 2646 | } | 2641 | } |
| 2647 | 2642 | ||
| 2648 | /** | 2643 | /** |
| @@ -2736,7 +2731,7 @@ function handleCharacterFilterChangeHelper({ characterFilter, data, entry, name, | |||
| 2736 | */ | 2731 | */ |
| 2737 | function handleProbabilityInputHelper({ probabilityInput, data, entry, name, setWIOriginalDataValue, saveWorldInfo }) { | 2732 | function handleProbabilityInputHelper({ probabilityInput, data, entry, name, setWIOriginalDataValue, saveWorldInfo }) { |
| 2738 | probabilityInput.data('uid', entry.uid); | 2733 | probabilityInput.data('uid', entry.uid); |
| 2739 | probabilityInput.on('input', async function () { | 2734 | probabilityInput.on('input', async function (_, { noSave = false } = {}) { |
| 2740 | const uid = $(this).data('uid'); | 2735 | const uid = $(this).data('uid'); |
| 2741 | const value = Number($(this).val()); | 2736 | const value = Number($(this).val()); |
| 2742 | data.entries[uid].probability = !isNaN(value) ? value : null; | 2737 | data.entries[uid].probability = !isNaN(value) ? value : null; |
| @@ -2747,9 +2742,9 @@ function handleProbabilityInputHelper({ probabilityInput, data, entry, name, set | |||
| 2747 | } | 2742 | } |
| 2748 | } | 2743 | } |
| 2749 | setWIOriginalDataValue(data, uid, 'extensions.probability', data.entries[uid].probability); | 2744 | setWIOriginalDataValue(data, uid, 'extensions.probability', data.entries[uid].probability); |
| 2750 | await saveWorldInfo(name, data); | 2745 | !noSave && await saveWorldInfo(name, data); |
| 2751 | }); | 2746 | }); |
| 2752 | probabilityInput.val(entry.probability).trigger('input'); | 2747 | probabilityInput.val(entry.probability).trigger('input', { noSave: true }); |
| 2753 | probabilityInput.css('width', 'calc(3em + 15px)'); | 2748 | probabilityInput.css('width', 'calc(3em + 15px)'); |
| 2754 | } | 2749 | } |
| 2755 | 2750 | ||
| @@ -2758,12 +2753,12 @@ function handleProbabilityInputHelper({ probabilityInput, data, entry, name, set | |||
| 2758 | */ | 2753 | */ |
| 2759 | function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, probabilityInput, setWIOriginalDataValue, saveWorldInfo }) { | 2754 | function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, probabilityInput, setWIOriginalDataValue, saveWorldInfo }) { |
| 2760 | probabilityToggle.data('uid', entry.uid); | 2755 | probabilityToggle.data('uid', entry.uid); |
| 2761 | probabilityToggle.on('input', async function () { | 2756 | probabilityToggle.on('input', async function (_, { noSave = false } = {}) { |
| 2762 | const uid = $(this).data('uid'); | 2757 | const uid = $(this).data('uid'); |
| 2763 | const value = $(this).prop('checked'); | 2758 | const value = $(this).prop('checked'); |
| 2764 | data.entries[uid].useProbability = value; | 2759 | data.entries[uid].useProbability = value; |
| 2765 | const probabilityContainer = $(this).closest('.world_entry').find('.probabilityContainer'); | 2760 | const probabilityContainer = $(this).closest('.world_entry').find('.probabilityContainer'); |
| 2766 | await saveWorldInfo(name, data); | 2761 | !noSave && await saveWorldInfo(name, data); |
| 2767 | value ? probabilityContainer.show() : probabilityContainer.hide(); | 2762 | value ? probabilityContainer.show() : probabilityContainer.hide(); |
| 2768 | if (value && data.entries[uid].probability === null) { | 2763 | if (value && data.entries[uid].probability === null) { |
| 2769 | data.entries[uid].probability = 100; | 2764 | data.entries[uid].probability = 100; |
| @@ -2771,9 +2766,9 @@ function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, p | |||
| 2771 | if (!value) { | 2766 | if (!value) { |
| 2772 | data.entries[uid].probability = null; | 2767 | data.entries[uid].probability = null; |
| 2773 | } | 2768 | } |
| 2774 | probabilityInput.val(data.entries[uid].probability).trigger('input'); | 2769 | probabilityInput.val(data.entries[uid].probability).trigger('input', { noSave }); |
| 2775 | }); | 2770 | }); |
| 2776 | probabilityToggle.prop('checked', true).trigger('input'); | 2771 | probabilityToggle.prop('checked', true).trigger('input', { noSave: true }); |
| 2777 | probabilityToggle.parent().hide(); | 2772 | probabilityToggle.parent().hide(); |
| 2778 | } | 2773 | } |
| 2779 | 2774 | ||
| @@ -2782,14 +2777,14 @@ function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, p | |||
| 2782 | */ | 2777 | */ |
| 2783 | function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo }) { | 2778 | function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo }) { |
| 2784 | selectElem.data('uid', entry.uid); | 2779 | selectElem.data('uid', entry.uid); |
| 2785 | selectElem.on('input', async function () { | 2780 | selectElem.on('input', async function (_, { noSave = false } = {}) { |
| 2786 | const uid = $(this).data('uid'); | 2781 | const uid = $(this).data('uid'); |
| 2787 | const value = $(this).val(); | 2782 | const value = $(this).val(); |
| 2788 | data.entries[uid][entryKey] = value === 'null' ? null : value === 'true'; | 2783 | data.entries[uid][entryKey] = value === 'null' ? null : value === 'true'; |
| 2789 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); | 2784 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); |
| 2790 | await saveWorldInfo(name, data); | 2785 | !noSave && await saveWorldInfo(name, data); |
| 2791 | }); | 2786 | }); |
| 2792 | selectElem.val((entry[entryKey] === null || entry[entryKey] === undefined) ? 'null' : entry[entryKey] ? 'true' : 'false').trigger('input'); | 2787 | selectElem.val((entry[entryKey] === null || entry[entryKey] === undefined) ? 'null' : entry[entryKey] ? 'true' : 'false').trigger('input', { noSave: true }); |
| 2793 | } | 2788 | } |
| 2794 | 2789 | ||
| 2795 | /** | 2790 | /** |
| @@ -2797,7 +2792,7 @@ function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, se | |||
| 2797 | */ | 2792 | */ |
| 2798 | function handleNumberInputHelper({ inputElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo, min, max, clamp = false }) { | 2793 | function handleNumberInputHelper({ inputElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo, min, max, clamp = false }) { |
| 2799 | inputElem.data('uid', entry.uid); | 2794 | inputElem.data('uid', entry.uid); |
| 2800 | inputElem.on('input', async function () { | 2795 | inputElem.on('input', async function (_, { noSave = false } = {}) { |
| 2801 | const uid = $(this).data('uid'); | 2796 | const uid = $(this).data('uid'); |
| 2802 | let value = Number($(this).val()); | 2797 | let value = Number($(this).val()); |
| 2803 | if (clamp) { | 2798 | if (clamp) { |
| @@ -2811,9 +2806,9 @@ function handleNumberInputHelper({ inputElem, entry, entryKey, data, name, setWI | |||
| 2811 | } | 2806 | } |
| 2812 | data.entries[uid][entryKey] = !isNaN(value) ? value : null; | 2807 | data.entries[uid][entryKey] = !isNaN(value) ? value : null; |
| 2813 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); | 2808 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); |
| 2814 | await saveWorldInfo(name, data); | 2809 | !noSave && await saveWorldInfo(name, data); |
| 2815 | }); | 2810 | }); |
| 2816 | inputElem.val(entry[entryKey] ?? (clamp ? min : '')).trigger('input'); | 2811 | inputElem.val(entry[entryKey] ?? (clamp ? min : '')).trigger('input', { noSave: true }); |
| 2817 | } | 2812 | } |
| 2818 | 2813 | ||
| 2819 | /** | 2814 | /** |
| @@ -2824,7 +2819,7 @@ function handleEntryStateSelectorHelper({ entryStateSelector, entry, data, name, | |||
| 2824 | entryStateSelector.on('click', function (event) { | 2819 | entryStateSelector.on('click', function (event) { |
| 2825 | event.stopPropagation(); | 2820 | event.stopPropagation(); |
| 2826 | }); | 2821 | }); |
| 2827 | entryStateSelector.on('input', async function () { | 2822 | entryStateSelector.on('input', async function (_, { noSave = false } = {}) { |
| 2828 | const uid = entry.uid; | 2823 | const uid = entry.uid; |
| 2829 | const value = $(this).val(); | 2824 | const value = $(this).val(); |
| 2830 | switch (value) { | 2825 | switch (value) { |
| @@ -2847,10 +2842,10 @@ function handleEntryStateSelectorHelper({ entryStateSelector, entry, data, name, | |||
| 2847 | setWIOriginalDataValue(data, uid, 'extensions.vectorized', true); | 2842 | setWIOriginalDataValue(data, uid, 'extensions.vectorized', true); |
| 2848 | break; | 2843 | break; |
| 2849 | } | 2844 | } |
| 2850 | await saveWorldInfo(name, data); | 2845 | !noSave && await saveWorldInfo(name, data); |
| 2851 | }); | 2846 | }); |
| 2852 | const entryState = () => entry.constant === true ? 'constant' : entry.vectorized === true ? 'vectorized' : 'normal'; | 2847 | const entryState = () => entry.constant === true ? 'constant' : entry.vectorized === true ? 'vectorized' : 'normal'; |
| 2853 | entryStateSelector.find(`option[value=${entryState()}]`).prop('selected', true).trigger('input'); | 2848 | entryStateSelector.find(`option[value=${entryState()}]`).prop('selected', true).trigger('input', { noSave: true }); |
| 2854 | } | 2849 | } |
| 2855 | 2850 | ||
| 2856 | /** | 2851 | /** |
| @@ -2892,28 +2887,28 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2892 | // Comment | 2887 | // Comment |
| 2893 | const commentInput = headerTemplate.find('textarea[name="comment"]'); | 2888 | const commentInput = headerTemplate.find('textarea[name="comment"]'); |
| 2894 | commentInput.data('uid', entry.uid); | 2889 | commentInput.data('uid', entry.uid); |
| 2895 | commentInput.on('input', async function (_, { skipReset } = {}) { | 2890 | commentInput.on('input', async function (_, { skipReset = false, noSave = false } = {}) { |
| 2896 | const uid = $(this).data('uid'); | 2891 | const uid = $(this).data('uid'); |
| 2897 | const value = $(this).val(); | 2892 | const value = $(this).val(); |
| 2898 | !skipReset && await resetScrollHeight(this); | 2893 | !skipReset && await resetScrollHeight(this); |
| 2899 | data.entries[uid].comment = value; | 2894 | data.entries[uid].comment = value; |
| 2900 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); | 2895 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); |
| 2901 | await saveWorldInfo(name, data); | 2896 | !noSave && await saveWorldInfo(name, data); |
| 2902 | }); | 2897 | }); |
| 2903 | commentInput.val(entry.comment).trigger('input', { skipReset: true }); | 2898 | commentInput.val(entry.comment).trigger('input', { skipReset: true, noSave: true }); |
| 2904 | 2899 | ||
| 2905 | // Order | 2900 | // Order |
| 2906 | const orderInput = headerTemplate.find('input[name="order"]'); | 2901 | const orderInput = headerTemplate.find('input[name="order"]'); |
| 2907 | orderInput.data('uid', entry.uid); | 2902 | orderInput.data('uid', entry.uid); |
| 2908 | orderInput.on('input', async function () { | 2903 | orderInput.on('input', async function (_, { noSave = false } = {}) { |
| 2909 | const uid = $(this).data('uid'); | 2904 | const uid = $(this).data('uid'); |
| 2910 | const value = Number($(this).val()); | 2905 | const value = Number($(this).val()); |
| 2911 | data.entries[uid].order = !isNaN(value) ? value : 0; | 2906 | data.entries[uid].order = !isNaN(value) ? value : 0; |
| 2912 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); | 2907 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); |
| 2913 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); | 2908 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); |
| 2914 | await saveWorldInfo(name, data); | 2909 | !noSave && await saveWorldInfo(name, data); |
| 2915 | }); | 2910 | }); |
| 2916 | orderInput.val(entry.order).trigger('input'); | 2911 | orderInput.val(entry.order).trigger('input', { noSave: true }); |
| 2917 | orderInput.css('width', 'calc(3em + 15px)'); | 2912 | orderInput.css('width', 'calc(3em + 15px)'); |
| 2918 | 2913 | ||
| 2919 | // Probability | 2914 | // Probability |
| @@ -2932,7 +2927,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2932 | const positionInput = headerTemplate.find('select[name="position"]'); | 2927 | const positionInput = headerTemplate.find('select[name="position"]'); |
| 2933 | positionInput.data('uid', entry.uid); | 2928 | positionInput.data('uid', entry.uid); |
| 2934 | positionInput.on('click', e => e.stopPropagation()); | 2929 | positionInput.on('click', e => e.stopPropagation()); |
| 2935 | positionInput.on('input', async function () { | 2930 | positionInput.on('input', async function (_, { noSave = false } = {}) { |
| 2936 | const uid = $(this).data('uid'); | 2931 | const uid = $(this).data('uid'); |
| 2937 | const value = Number($(this).val()); | 2932 | const value = Number($(this).val()); |
| 2938 | data.entries[uid].position = !isNaN(value) ? value : 0; | 2933 | data.entries[uid].position = !isNaN(value) ? value : 0; |
| @@ -2951,10 +2946,10 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2951 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); | 2946 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); |
| 2952 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); | 2947 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); |
| 2953 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); | 2948 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); |
| 2954 | await saveWorldInfo(name, data); | 2949 | !noSave && await saveWorldInfo(name, data); |
| 2955 | }); | 2950 | }); |
| 2956 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; | 2951 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; |
| 2957 | headerTemplate.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input'); | 2952 | headerTemplate.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input', { noSave: true }); |
| 2958 | 2953 | ||
| 2959 | // Tri-state selector | 2954 | // Tri-state selector |
| 2960 | handleEntryStateSelectorHelper({ | 2955 | handleEntryStateSelectorHelper({ |
| @@ -3098,39 +3093,39 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3098 | // Comment toggle | 3093 | // Comment toggle |
| 3099 | const commentToggle = editTemplate.find('input[name="addMemo"]'); | 3094 | const commentToggle = editTemplate.find('input[name="addMemo"]'); |
| 3100 | commentToggle.data('uid', entry.uid); | 3095 | commentToggle.data('uid', entry.uid); |
| 3101 | commentToggle.on('input', async function () { | 3096 | commentToggle.on('input', async function (_, { noSave = false } = {}) { |
| 3102 | const uid = $(this).data('uid'); | 3097 | const uid = $(this).data('uid'); |
| 3103 | const value = $(this).prop('checked'); | 3098 | const value = $(this).prop('checked'); |
| 3104 | const commentContainer = $(this).closest('.world_entry').find('.commentContainer'); | 3099 | const commentContainer = $(this).closest('.world_entry').find('.commentContainer'); |
| 3105 | data.entries[uid].addMemo = value; | 3100 | data.entries[uid].addMemo = value; |
| 3106 | await saveWorldInfo(name, data); | 3101 | !noSave && await saveWorldInfo(name, data); |
| 3107 | value ? commentContainer.show() : commentContainer.hide(); | 3102 | value ? commentContainer.show() : commentContainer.hide(); |
| 3108 | }); | 3103 | }); |
| 3109 | commentToggle.prop('checked', true).trigger('input'); | 3104 | commentToggle.prop('checked', true).trigger('input', { noSave: true }); |
| 3110 | commentToggle.parent().hide(); | 3105 | commentToggle.parent().hide(); |
| 3111 | 3106 | ||
| 3112 | // Logic AND/NOT | 3107 | // Logic AND/NOT |
| 3113 | const selectiveLogicDropdown = editTemplate.find('select[name="entryLogicType"]'); | 3108 | const selectiveLogicDropdown = editTemplate.find('select[name="entryLogicType"]'); |
| 3114 | selectiveLogicDropdown.data('uid', entry.uid); | 3109 | selectiveLogicDropdown.data('uid', entry.uid); |
| 3115 | selectiveLogicDropdown.on('click', e => e.stopPropagation()); | 3110 | selectiveLogicDropdown.on('click', e => e.stopPropagation()); |
| 3116 | selectiveLogicDropdown.on('input', async function () { | 3111 | selectiveLogicDropdown.on('input', async function (_, { noSave = false } = {}) { |
| 3117 | const uid = $(this).data('uid'); | 3112 | const uid = $(this).data('uid'); |
| 3118 | const value = Number($(this).val()); | 3113 | const value = Number($(this).val()); |
| 3119 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; | 3114 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; |
| 3120 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); | 3115 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); |
| 3121 | await saveWorldInfo(name, data); | 3116 | !noSave && await saveWorldInfo(name, data); |
| 3122 | }); | 3117 | }); |
| 3123 | editTemplate.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input'); | 3118 | editTemplate.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input', { noSave: true }); |
| 3124 | 3119 | ||
| 3125 | // Selective | 3120 | // Selective |
| 3126 | const selectiveInput = editTemplate.find('input[name="selective"]'); | 3121 | const selectiveInput = editTemplate.find('input[name="selective"]'); |
| 3127 | selectiveInput.data('uid', entry.uid); | 3122 | selectiveInput.data('uid', entry.uid); |
| 3128 | selectiveInput.on('input', async function () { | 3123 | selectiveInput.on('input', async function (_, { noSave = false } = {}) { |
| 3129 | const uid = $(this).data('uid'); | 3124 | const uid = $(this).data('uid'); |
| 3130 | const value = $(this).prop('checked'); | 3125 | const value = $(this).prop('checked'); |
| 3131 | data.entries[uid].selective = value; | 3126 | data.entries[uid].selective = value; |
| 3132 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); | 3127 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); |
| 3133 | await saveWorldInfo(name, data); | 3128 | !noSave && await saveWorldInfo(name, data); |
| 3134 | const keysecondary = $(this).closest('.world_entry').find('.keysecondary'); | 3129 | const keysecondary = $(this).closest('.world_entry').find('.keysecondary'); |
| 3135 | const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole'); | 3130 | const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole'); |
| 3136 | const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect'); | 3131 | const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect'); |
| @@ -3138,7 +3133,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3138 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); | 3133 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); |
| 3139 | value ? keysecondary.show() : keysecondary.hide(); | 3134 | value ? keysecondary.show() : keysecondary.hide(); |
| 3140 | }); | 3135 | }); |
| 3141 | selectiveInput.prop('checked', true).trigger('input'); | 3136 | selectiveInput.prop('checked', true).trigger('input', { noSave: true }); |
| 3142 | selectiveInput.parent().hide(); | 3137 | selectiveInput.parent().hide(); |
| 3143 | 3138 | ||
| 3144 | // Character filter | 3139 | // Character filter |
| @@ -3146,7 +3141,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3146 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); | 3141 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); |
| 3147 | const characterExclusionInput = editTemplate.find('input[name="character_exclusion"]'); | 3142 | const characterExclusionInput = editTemplate.find('input[name="character_exclusion"]'); |
| 3148 | characterExclusionInput.data('uid', entry.uid); | 3143 | characterExclusionInput.data('uid', entry.uid); |
| 3149 | characterExclusionInput.on('input', async function () { | 3144 | characterExclusionInput.on('input', async function (_, { noSave = false } = {}) { |
| 3150 | const uid = $(this).data('uid'); | 3145 | const uid = $(this).data('uid'); |
| 3151 | const value = $(this).prop('checked'); | 3146 | const value = $(this).prop('checked'); |
| 3152 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); | 3147 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); |
| @@ -3167,9 +3162,9 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3167 | } | 3162 | } |
| 3168 | } | 3163 | } |
| 3169 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | 3164 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); |
| 3170 | await saveWorldInfo(name, data); | 3165 | !noSave && await saveWorldInfo(name, data); |
| 3171 | }); | 3166 | }); |
| 3172 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input'); | 3167 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input', { noSave: true }); |
| 3173 | 3168 | ||
| 3174 | const characterFilter = editTemplate.find('select[name="characterFilter"]'); | 3169 | const characterFilter = editTemplate.find('select[name="characterFilter"]'); |
| 3175 | characterFilter.data('uid', entry.uid); | 3170 | characterFilter.data('uid', entry.uid); |
| @@ -3189,21 +3184,21 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3189 | const contentInput = editTemplate.find('textarea[name="content"]'); | 3184 | const contentInput = editTemplate.find('textarea[name="content"]'); |
| 3190 | contentInput.data('uid', entry.uid); | 3185 | contentInput.data('uid', entry.uid); |
| 3191 | contentInput.attr('id', contentInputId); | 3186 | contentInput.attr('id', contentInputId); |
| 3192 | contentInput.on('input', async function (_, { skipCount } = {}) { | 3187 | contentInput.on('input', async function (_, { skipCount, noSave } = {}) { |
| 3193 | const uid = $(this).data('uid'); | 3188 | const uid = $(this).data('uid'); |
| 3194 | const value = $(this).val(); | 3189 | const value = $(this).val(); |
| 3195 | data.entries[uid].content = value; | 3190 | data.entries[uid].content = value; |
| 3196 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); | 3191 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); |
| 3197 | await saveWorldInfo(name, data); | 3192 | !noSave && await saveWorldInfo(name, data); |
| 3198 | if (!skipCount) countTokensDebounced(counter, value); | 3193 | if (!skipCount) countTokensDebounced(counter, value); |
| 3199 | }); | 3194 | }); |
| 3200 | contentInput.val(entry.content).trigger('input', { skipCount: true }); | 3195 | contentInput.val(entry.content).trigger('input', { skipCount: true, noSave: true }); |
| 3201 | editTemplate.find('.editor_maximize').attr('data-for', contentInputId); | 3196 | editTemplate.find('.editor_maximize').attr('data-for', contentInputId); |
| 3202 | 3197 | ||
| 3203 | // Scan depth | 3198 | // Scan depth |
| 3204 | const scanDepthInput = editTemplate.find('input[name="scanDepth"]'); | 3199 | const scanDepthInput = editTemplate.find('input[name="scanDepth"]'); |
| 3205 | scanDepthInput.data('uid', entry.uid); | 3200 | scanDepthInput.data('uid', entry.uid); |
| 3206 | scanDepthInput.on('input', async function () { | 3201 | scanDepthInput.on('input', async function (_, { noSave = false } = {}) { |
| 3207 | const uid = $(this).data('uid'); | 3202 | const uid = $(this).data('uid'); |
| 3208 | const isEmpty = $(this).val() === ''; | 3203 | const isEmpty = $(this).val() === ''; |
| 3209 | const value = Number($(this).val()); | 3204 | const value = Number($(this).val()); |
| @@ -3219,34 +3214,34 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3219 | } | 3214 | } |
| 3220 | data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null; | 3215 | data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null; |
| 3221 | setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth); | 3216 | setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth); |
| 3222 | await saveWorldInfo(name, data); | 3217 | !noSave && await saveWorldInfo(name, data); |
| 3223 | }); | 3218 | }); |
| 3224 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input'); | 3219 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input', { noSave: true }); |
| 3225 | 3220 | ||
| 3226 | // Group | 3221 | // Group |
| 3227 | const groupInput = editTemplate.find('input[name="group"]'); | 3222 | const groupInput = editTemplate.find('input[name="group"]'); |
| 3228 | groupInput.data('uid', entry.uid); | 3223 | groupInput.data('uid', entry.uid); |
| 3229 | groupInput.on('input', async function () { | 3224 | groupInput.on('input', async function (_, { noSave = false } = {}) { |
| 3230 | const uid = $(this).data('uid'); | 3225 | const uid = $(this).data('uid'); |
| 3231 | const value = String($(this).val()).trim(); | 3226 | const value = String($(this).val()).trim(); |
| 3232 | data.entries[uid].group = value; | 3227 | data.entries[uid].group = value; |
| 3233 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); | 3228 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); |
| 3234 | await saveWorldInfo(name, data); | 3229 | !noSave && await saveWorldInfo(name, data); |
| 3235 | }); | 3230 | }); |
| 3236 | groupInput.val(entry.group ?? '').trigger('input'); | 3231 | groupInput.val(entry.group ?? '').trigger('input', { noSave: true }); |
| 3237 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); | 3232 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); |
| 3238 | 3233 | ||
| 3239 | // Inclusion priority | 3234 | // Inclusion priority |
| 3240 | const groupOverrideInput = editTemplate.find('input[name="groupOverride"]'); | 3235 | const groupOverrideInput = editTemplate.find('input[name="groupOverride"]'); |
| 3241 | groupOverrideInput.data('uid', entry.uid); | 3236 | groupOverrideInput.data('uid', entry.uid); |
| 3242 | groupOverrideInput.on('input', async function () { | 3237 | groupOverrideInput.on('input', async function (_, { noSave = false } = {}) { |
| 3243 | const uid = $(this).data('uid'); | 3238 | const uid = $(this).data('uid'); |
| 3244 | const value = $(this).prop('checked'); | 3239 | const value = $(this).prop('checked'); |
| 3245 | data.entries[uid].groupOverride = value; | 3240 | data.entries[uid].groupOverride = value; |
| 3246 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); | 3241 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); |
| 3247 | await saveWorldInfo(name, data); | 3242 | !noSave && await saveWorldInfo(name, data); |
| 3248 | }); | 3243 | }); |
| 3249 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input'); | 3244 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input', { noSave: true }); |
| 3250 | 3245 | ||
| 3251 | // Group weight | 3246 | // Group weight |
| 3252 | handleNumberInputHelper({ | 3247 | handleNumberInputHelper({ |
| @@ -3281,17 +3276,17 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3281 | delayUntilRecursionInput.data('uid', entry.uid); | 3276 | delayUntilRecursionInput.data('uid', entry.uid); |
| 3282 | const delayUntilRecursionLevelInput = editTemplate.find('input[name="delayUntilRecursionLevel"]'); | 3277 | const delayUntilRecursionLevelInput = editTemplate.find('input[name="delayUntilRecursionLevel"]'); |
| 3283 | delayUntilRecursionLevelInput.data('uid', entry.uid); | 3278 | delayUntilRecursionLevelInput.data('uid', entry.uid); |
| 3284 | delayUntilRecursionInput.on('input', async function () { | 3279 | delayUntilRecursionInput.on('input', async function (_, { noSave = false } = {}) { |
| 3285 | const uid = $(this).data('uid'); | 3280 | const uid = $(this).data('uid'); |
| 3286 | const toggled = $(this).prop('checked'); | 3281 | const toggled = $(this).prop('checked'); |
| 3287 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; | 3282 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; |
| 3288 | if (!toggled) delayUntilRecursionLevelInput.val(''); | 3283 | if (!toggled) delayUntilRecursionLevelInput.val(''); |
| 3289 | data.entries[uid].delayUntilRecursion = value; | 3284 | data.entries[uid].delayUntilRecursion = value; |
| 3290 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | 3285 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); |
| 3291 | await saveWorldInfo(name, data); | 3286 | !noSave && await saveWorldInfo(name, data); |
| 3292 | }); | 3287 | }); |
| 3293 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input'); | 3288 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input', { noSave: true }); |
| 3294 | delayUntilRecursionLevelInput.on('input', async function () { | 3289 | delayUntilRecursionLevelInput.on('input', async function (_, { noSave = false } = {}) { |
| 3295 | const uid = $(this).data('uid'); | 3290 | const uid = $(this).data('uid'); |
| 3296 | const content = $(this).val(); | 3291 | const content = $(this).val(); |
| 3297 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) | 3292 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) |
| @@ -3300,9 +3295,9 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3300 | : false; | 3295 | : false; |
| 3301 | data.entries[uid].delayUntilRecursion = value; | 3296 | data.entries[uid].delayUntilRecursion = value; |
| 3302 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | 3297 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); |
| 3303 | await saveWorldInfo(name, data); | 3298 | !noSave && await saveWorldInfo(name, data); |
| 3304 | }); | 3299 | }); |
| 3305 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input'); | 3300 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input', { noSave: true }); |
| 3306 | 3301 | ||
| 3307 | // Boolean selects | 3302 | // Boolean selects |
| 3308 | handleBooleanSelectHelper({ | 3303 | handleBooleanSelectHelper({ |
| @@ -3329,14 +3324,14 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3329 | // Automation ID | 3324 | // Automation ID |
| 3330 | const automationIdInput = editTemplate.find('input[name="automationId"]'); | 3325 | const automationIdInput = editTemplate.find('input[name="automationId"]'); |
| 3331 | automationIdInput.data('uid', entry.uid); | 3326 | automationIdInput.data('uid', entry.uid); |
| 3332 | automationIdInput.on('input', async function () { | 3327 | automationIdInput.on('input', async function (_, { noSave = false } = {}) { |
| 3333 | const uid = $(this).data('uid'); | 3328 | const uid = $(this).data('uid'); |
| 3334 | const value = $(this).val(); | 3329 | const value = $(this).val(); |
| 3335 | data.entries[uid].automationId = value; | 3330 | data.entries[uid].automationId = value; |
| 3336 | setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId); | 3331 | setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId); |
| 3337 | await saveWorldInfo(name, data); | 3332 | !noSave && await saveWorldInfo(name, data); |
| 3338 | }); | 3333 | }); |
| 3339 | automationIdInput.val(entry.automationId ?? '').trigger('input'); | 3334 | automationIdInput.val(entry.automationId ?? '').trigger('input', { noSave: true }); |
| 3340 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); | 3335 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); |
| 3341 | 3336 | ||
| 3342 | countTokensDebounced(counter, contentInput.val()); | 3337 | countTokensDebounced(counter, contentInput.val()); |
| @@ -3588,11 +3583,6 @@ async function _save(name, data) { | |||
| 3588 | * @return {Promise<void>} A promise that resolves when the world info is saved | 3583 | * @return {Promise<void>} A promise that resolves when the world info is saved |
| 3589 | */ | 3584 | */ |
| 3590 | export async function saveWorldInfo(name, data, immediately = false) { | 3585 | export async function saveWorldInfo(name, data, immediately = false) { |
| 3591 | // Saving is temporarily disabled | ||
| 3592 | if (isSaveWorldInfoDisabled) { | ||
| 3593 | return; | ||
| 3594 | } | ||
| 3595 | |||
| 3596 | if (!name || !data) { | 3586 | if (!name || !data) { |
| 3597 | return; | 3587 | return; |
| 3598 | } | 3588 | } |