Get rid of isSaveWorldInfoDisabled

70141aa565be1f2832a015ebe232fdd3d3bbaa5e

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

1 files changed, +61 -71Showing whitespace changes
public/scripts/world-info.js+61 -71
@@ -86,7 +86,6 @@ const saveSettingsDebounced = debounce(() => {
86}, debounce_timeout.relaxed);86}, debounce_timeout.relaxed);
87const sortFn = (a, b) => b.order - a.order;87const sortFn = (a, b) => b.order - a.order;
88let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); };88let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); };
89let isSaveWorldInfoDisabled = false;
9089
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.
92export const worldInfoFilter = new FilterHelper(() => updateEditor());91export 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);
21082105
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}
26472642
2648/**2643/**
@@ -2736,7 +2731,7 @@ function handleCharacterFilterChangeHelper({ characterFilter, data, entry, name,
2736 */2731 */
2737function handleProbabilityInputHelper({ probabilityInput, data, entry, name, setWIOriginalDataValue, saveWorldInfo }) {2732function 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}
27552750
@@ -2758,12 +2753,12 @@ function handleProbabilityInputHelper({ probabilityInput, data, entry, name, set
2758 */2753 */
2759function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, probabilityInput, setWIOriginalDataValue, saveWorldInfo }) {2754function 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}
27792774
@@ -2782,14 +2777,14 @@ function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, p
2782 */2777 */
2783function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo }) {2778function 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}
27942789
2795/**2790/**
@@ -2797,7 +2792,7 @@ function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, se
2797 */2792 */
2798function handleNumberInputHelper({ inputElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo, min, max, clamp = false }) {2793function 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}
28182813
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}
28552850
2856/**2851/**
@@ -2892,28 +2887,28 @@ export async function getWorldEntry(name, data, entry) {
2892 // Comment2887 // 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 });
29042899
2905 // Order2900 // 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)');
29182913
2919 // Probability2914 // 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 });
29582953
2959 // Tri-state selector2954 // Tri-state selector
2960 handleEntryStateSelectorHelper({2955 handleEntryStateSelectorHelper({
@@ -3098,39 +3093,39 @@ export async function getWorldEntry(name, data, entry) {
3098 // Comment toggle3093 // 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();
31113106
3112 // Logic AND/NOT3107 // 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 });
31243119
3125 // Selective3120 // 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();
31433138
3144 // Character filter3139 // 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 });
31733168
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);
32023197
3203 // Scan depth3198 // 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 });
32253220
3226 // Group3221 // 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);
32383233
3239 // Inclusion priority3234 // 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 });
32503245
3251 // Group weight3246 // 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 });
33063301
3307 // Boolean selects3302 // Boolean selects
3308 handleBooleanSelectHelper({3303 handleBooleanSelectHelper({
@@ -3329,14 +3324,14 @@ export async function getWorldEntry(name, data, entry) {
3329 // Automation ID3324 // 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);
33413336
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 saved3583 * @return {Promise<void>} A promise that resolves when the world info is saved
3589 */3584 */
3590export async function saveWorldInfo(name, data, immediately = false) {3585export 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 }