WI: Split entry header and editor
| @@ -201,6 +201,10 @@ | |||
| 201 | transition: opacity 500ms; | 201 | transition: opacity 500ms; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | .world_entry_edit { | ||
| 205 | display: contents; | ||
| 206 | } | ||
| 207 | |||
| 204 | .disabledWIEntry { | 208 | .disabledWIEntry { |
| 205 | opacity: 0.4; | 209 | opacity: 0.4; |
| 206 | filter: grayscale(1); | 210 | filter: grayscale(1); |
| @@ -6193,79 +6193,7 @@ | |||
| 6193 | </div> | 6193 | </div> |
| 6194 | </div> | 6194 | </div> |
| 6195 | <div id="entry_edit_template" class="template_element"> | 6195 | <div id="entry_edit_template" class="template_element"> |
| 6196 | <div class="world_entry"> | 6196 | <div class="world_entry_edit"> |
| 6197 | <form class="world_entry_form wi-card-entry"> | ||
| 6198 | <div class="inline-drawer wide100p"> | ||
| 6199 | <div class="inline-drawer-header gap5px padding0"> | ||
| 6200 | <span class="drag-handle">☰</span> | ||
| 6201 | <div class="gap5px world_entry_thin_controls wide100p alignitemscenter"> | ||
| 6202 | <div class="inline-drawer-toggle fa-fw fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 6203 | <div class="fa-solid fa-toggle-on killSwitch" name="entryKillSwitch" data-i18n="[title]Toggle entry's active state." title="Toggle entry's active state."></div> | ||
| 6204 | <div class="flex-container alignitemscenter wide100p"> | ||
| 6205 | <div class="WIEntryTitleAndStatus flex-container flex1 alignitemscenter"> | ||
| 6206 | <div class="flex-container flex1"> | ||
| 6207 | <textarea class="text_pole" rows="1" name="comment" data-i18n="[placeholder]Entry Title/Memo" placeholder="Entry Title/Memo"></textarea> | ||
| 6208 | </div> | ||
| 6209 | <!-- <span class="world_entry_form_position_value"></span> --> | ||
| 6210 | <select data-i18n="[title]WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized" title="WI Entry Status: 🔵 Constant 🟢 Normal 🔗 Vectorized" name="entryStateSelector" class="text_pole widthNatural margin0"> | ||
| 6211 | <option value="constant" title="Constant" data-i18n="[title]WI_Entry_Status_Constant">🔵</option> | ||
| 6212 | <option value="normal" title="Normal" data-i18n="[title]WI_Entry_Status_Normal">🟢</option> | ||
| 6213 | <option value="vectorized" title="Vectorized" data-i18n="[title]WI_Entry_Status_Vectorized">🔗</option> | ||
| 6214 | </select> | ||
| 6215 | </div> | ||
| 6216 | <div class="WIEnteryHeaderControls flex-container"> | ||
| 6217 | <div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text"> | ||
| 6218 | <label for="position" class="WIEntryHeaderTitleMobile" data-i18n="Position:">Position:</label> | ||
| 6219 | <select name="position" class="text_pole widthNatural margin0" data-i18n="[title]T_Position" title="↑Char: Before Character Definitions ↓Char: After Character Definitions ↑EM: Before Example Messages ↓EM: After Example Messages ↑AN: Before Author's Note ↓AN: After Author's Note @D ⚙️: at Depth (System) @D 👤: at Depth (User) @D 🤖: at Depth (Assistant)"> | ||
| 6220 | <option value="0" data-role="" data-i18n="Before Char Defs"> | ||
| 6221 | ↑Char | ||
| 6222 | </option> | ||
| 6223 | <option value="1" data-role="" data-i18n="After Char Defs"> | ||
| 6224 | ↓Char | ||
| 6225 | </option> | ||
| 6226 | <option value="5" data-role="" data-i18n="Before EM"> | ||
| 6227 | ↑EM | ||
| 6228 | </option> | ||
| 6229 | <option value="6" data-role="" data-i18n="After EM"> | ||
| 6230 | ↓EM | ||
| 6231 | </option> | ||
| 6232 | <option value="2" data-role="" data-i18n="Before AN"> | ||
| 6233 | ↑AN | ||
| 6234 | </option> | ||
| 6235 | <option value="3" data-role="" data-i18n="After AN"> | ||
| 6236 | ↓AN | ||
| 6237 | </option> | ||
| 6238 | <option value="4" data-role="0" data-i18n="at Depth System"> | ||
| 6239 | @D ⚙️ | ||
| 6240 | </option> | ||
| 6241 | <option value="4" data-role="1" data-i18n="at Depth User"> | ||
| 6242 | @D 👤 | ||
| 6243 | </option> | ||
| 6244 | <option value="4" data-role="2" data-i18n="at Depth AI"> | ||
| 6245 | @D 🤖 | ||
| 6246 | </option> | ||
| 6247 | </select> | ||
| 6248 | </div> | ||
| 6249 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap"> | ||
| 6250 | <label for="depth" class="WIEntryHeaderTitleMobile" data-i18n="Depth:">Depth:</label> | ||
| 6251 | <input title="Depth" class="text_pole wideMax100px margin0" type="number" name="depth" data-i18n="[title]Depth" placeholder="" min="0" max="9999" /> | ||
| 6252 | </div> | ||
| 6253 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap"> | ||
| 6254 | <label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Order:">Order:</label> | ||
| 6255 | <input title="Order" data-i18n="[title]Order" class="text_pole wideMax100px margin0" type="number" name="order" placeholder="" min="0" max="9999" /> | ||
| 6256 | </div> | ||
| 6257 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer"> | ||
| 6258 | <label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Trigger %:">Trigger %:</label> | ||
| 6259 | <input title="Probability" data-i18n="[title]Probability" class="text_pole wideMax100px margin0" type="number" name="probability" placeholder="" min="0" max="100" /> | ||
| 6260 | </div> | ||
| 6261 | </div> | ||
| 6262 | </div> | ||
| 6263 | </div> | ||
| 6264 | <i class="menu_button move_entry_button fa-solid fa-right-left" title="Move Entry to Another Lorebook" data-i18n="[title]Move Entry to Another Lorebook"></i> | ||
| 6265 | <i class="menu_button duplicate_entry_button fa-solid fa-paste" title="Duplicate world info entry" data-i18n="[title]Duplicate world info entry" type="submit" value=""></i> | ||
| 6266 | <i class="menu_button delete_entry_button fa-solid fa-trash-can" title="Delete world info entry" data-i18n="[title]Delete world info entry" type="submit" value=""></i> | ||
| 6267 | </div> | ||
| 6268 | <div class="inline-drawer-content flex-container paddingBottom5px wide100p"> | ||
| 6269 | <div class="flex-container wide100p alignitemscenter"> | 6197 | <div class="flex-container wide100p alignitemscenter"> |
| 6270 | <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter"> | 6198 | <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter"> |
| 6271 | <div class="world_entry_form_control keyprimary flex1"> | 6199 | <div class="world_entry_form_control keyprimary flex1"> |
| @@ -6557,6 +6485,81 @@ | |||
| 6557 | </div> | 6485 | </div> |
| 6558 | </div> | 6486 | </div> |
| 6559 | </div> | 6487 | </div> |
| 6488 | <div class="world_entry"> | ||
| 6489 | <form class="world_entry_form wi-card-entry"> | ||
| 6490 | <div class="inline-drawer wide100p"> | ||
| 6491 | <div class="inline-drawer-header gap5px padding0"> | ||
| 6492 | <span class="drag-handle">☰</span> | ||
| 6493 | <div class="gap5px world_entry_thin_controls wide100p alignitemscenter"> | ||
| 6494 | <div class="inline-drawer-toggle fa-fw fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 6495 | <div class="fa-solid fa-toggle-on killSwitch" name="entryKillSwitch" data-i18n="[title]Toggle entry's active state." title="Toggle entry's active state."></div> | ||
| 6496 | <div class="flex-container alignitemscenter wide100p"> | ||
| 6497 | <div class="WIEntryTitleAndStatus flex-container flex1 alignitemscenter"> | ||
| 6498 | <div class="flex-container flex1"> | ||
| 6499 | <textarea class="text_pole" rows="1" name="comment" data-i18n="[placeholder]Entry Title/Memo" placeholder="Entry Title/Memo"></textarea> | ||
| 6500 | </div> | ||
| 6501 | <!-- <span class="world_entry_form_position_value"></span> --> | ||
| 6502 | <select data-i18n="[title]WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized" title="WI Entry Status: 🔵 Constant 🟢 Normal 🔗 Vectorized" name="entryStateSelector" class="text_pole widthNatural margin0"> | ||
| 6503 | <option value="constant" title="Constant" data-i18n="[title]WI_Entry_Status_Constant">🔵</option> | ||
| 6504 | <option value="normal" title="Normal" data-i18n="[title]WI_Entry_Status_Normal">🟢</option> | ||
| 6505 | <option value="vectorized" title="Vectorized" data-i18n="[title]WI_Entry_Status_Vectorized">🔗</option> | ||
| 6506 | </select> | ||
| 6507 | </div> | ||
| 6508 | <div class="WIEnteryHeaderControls flex-container"> | ||
| 6509 | <div name="PositionBlock" class="world_entry_form_control world_entry_form_radios wi-enter-footer-text"> | ||
| 6510 | <label for="position" class="WIEntryHeaderTitleMobile" data-i18n="Position:">Position:</label> | ||
| 6511 | <select name="position" class="text_pole widthNatural margin0" data-i18n="[title]T_Position" title="↑Char: Before Character Definitions ↓Char: After Character Definitions ↑EM: Before Example Messages ↓EM: After Example Messages ↑AN: Before Author's Note ↓AN: After Author's Note @D ⚙️: at Depth (System) @D 👤: at Depth (User) @D 🤖: at Depth (Assistant)"> | ||
| 6512 | <option value="0" data-role="" data-i18n="Before Char Defs"> | ||
| 6513 | ↑Char | ||
| 6514 | </option> | ||
| 6515 | <option value="1" data-role="" data-i18n="After Char Defs"> | ||
| 6516 | ↓Char | ||
| 6517 | </option> | ||
| 6518 | <option value="5" data-role="" data-i18n="Before EM"> | ||
| 6519 | ↑EM | ||
| 6520 | </option> | ||
| 6521 | <option value="6" data-role="" data-i18n="After EM"> | ||
| 6522 | ↓EM | ||
| 6523 | </option> | ||
| 6524 | <option value="2" data-role="" data-i18n="Before AN"> | ||
| 6525 | ↑AN | ||
| 6526 | </option> | ||
| 6527 | <option value="3" data-role="" data-i18n="After AN"> | ||
| 6528 | ↓AN | ||
| 6529 | </option> | ||
| 6530 | <option value="4" data-role="0" data-i18n="at Depth System"> | ||
| 6531 | @D ⚙️ | ||
| 6532 | </option> | ||
| 6533 | <option value="4" data-role="1" data-i18n="at Depth User"> | ||
| 6534 | @D 👤 | ||
| 6535 | </option> | ||
| 6536 | <option value="4" data-role="2" data-i18n="at Depth AI"> | ||
| 6537 | @D 🤖 | ||
| 6538 | </option> | ||
| 6539 | </select> | ||
| 6540 | </div> | ||
| 6541 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap"> | ||
| 6542 | <label for="depth" class="WIEntryHeaderTitleMobile" data-i18n="Depth:">Depth:</label> | ||
| 6543 | <input title="Depth" class="text_pole wideMax100px margin0" type="number" name="depth" data-i18n="[title]Depth" placeholder="" min="0" max="9999" /> | ||
| 6544 | </div> | ||
| 6545 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap"> | ||
| 6546 | <label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Order:">Order:</label> | ||
| 6547 | <input title="Order" data-i18n="[title]Order" class="text_pole wideMax100px margin0" type="number" name="order" placeholder="" min="0" max="9999" /> | ||
| 6548 | </div> | ||
| 6549 | <div class="world_entry_form_control wi-enter-footer-text flex-container flexNoGap probabilityContainer"> | ||
| 6550 | <label for="order" class="WIEntryHeaderTitleMobile" data-i18n="Trigger %:">Trigger %:</label> | ||
| 6551 | <input title="Probability" data-i18n="[title]Probability" class="text_pole wideMax100px margin0" type="number" name="probability" placeholder="" min="0" max="100" /> | ||
| 6552 | </div> | ||
| 6553 | </div> | ||
| 6554 | </div> | ||
| 6555 | </div> | ||
| 6556 | <i class="menu_button move_entry_button fa-solid fa-right-left" title="Move Entry to Another Lorebook" data-i18n="[title]Move Entry to Another Lorebook"></i> | ||
| 6557 | <i class="menu_button duplicate_entry_button fa-solid fa-paste" title="Duplicate world info entry" data-i18n="[title]Duplicate world info entry" type="submit" value=""></i> | ||
| 6558 | <i class="menu_button delete_entry_button fa-solid fa-trash-can" title="Delete world info entry" data-i18n="[title]Delete world info entry" type="submit" value=""></i> | ||
| 6559 | </div> | ||
| 6560 | <div class="inline-drawer-content inline-drawer-outlet flex-container paddingBottom5px wide100p "> | ||
| 6561 | <!-- Outlet for world_entry_edit --> | ||
| 6562 | </div> | ||
| 6560 | </div> | 6563 | </div> |
| 6561 | </form> | 6564 | </form> |
| 6562 | </div> | 6565 | </div> |
| @@ -58,7 +58,8 @@ export const scan_state = { | |||
| 58 | MIN_ACTIVATIONS: 3, | 58 | MIN_ACTIVATIONS: 3, |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | const WI_ENTRY_EDIT_TEMPLATE = $('#entry_edit_template .world_entry'); | 61 | const WI_ENTRY_HEADER_TEMPLATE = $('#entry_edit_template .world_entry'); |
| 62 | const WI_ENTRY_EDIT_TEMPLATE = $('#entry_edit_template .world_entry_edit'); | ||
| 62 | 63 | ||
| 63 | export let world_info = {}; | 64 | export let world_info = {}; |
| 64 | export let selected_world_info = []; | 65 | export let selected_world_info = []; |
| @@ -1939,9 +1940,8 @@ function updateWorldEntryKeyOptionsCache(keyOptions, { remove = false, reset = f | |||
| 1939 | worldEntryKeyOptionsCache.sort((a, b) => b.count - a.count || a.text.localeCompare(b.text)); | 1940 | worldEntryKeyOptionsCache.sort((a, b) => b.count - a.count || a.text.localeCompare(b.text)); |
| 1940 | } | 1941 | } |
| 1941 | 1942 | ||
| 1942 | function clearEntryList() { | 1943 | function clearEntryList($list) { |
| 1943 | console.time('clearEntryList'); | 1944 | console.time('clearEntryList'); |
| 1944 | const $list = $('#world_popup_entries_list'); | ||
| 1945 | 1945 | ||
| 1946 | if (!$list.children().length) { | 1946 | if (!$list.children().length) { |
| 1947 | console.debug('List already empty, skipping cleanup.'); | 1947 | console.debug('List already empty, skipping cleanup.'); |
| @@ -2007,7 +2007,7 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no | |||
| 2007 | 2007 | ||
| 2008 | worldEntriesList.css({ 'opacity': 0, 'transition': 'opacity 250ms ease-in-out' }); | 2008 | worldEntriesList.css({ 'opacity': 0, 'transition': 'opacity 250ms ease-in-out' }); |
| 2009 | await delay(250); | 2009 | await delay(250); |
| 2010 | clearEntryList(); | 2010 | clearEntryList(worldEntriesList); |
| 2011 | worldEntriesList.show(); | 2011 | worldEntriesList.show(); |
| 2012 | 2012 | ||
| 2013 | if (!data || !('entries' in data)) { | 2013 | if (!data || !('entries' in data)) { |
| @@ -2104,7 +2104,7 @@ async function displayWorldEntries(name, data, navigation = navigation_option.no | |||
| 2104 | try { | 2104 | try { |
| 2105 | // Prevent saveWorldInfo from firing timeouts while rendering the list | 2105 | // Prevent saveWorldInfo from firing timeouts while rendering the list |
| 2106 | isSaveWorldInfoDisabled = true; | 2106 | isSaveWorldInfoDisabled = true; |
| 2107 | clearEntryList(); | 2107 | clearEntryList(worldEntriesList); |
| 2108 | 2108 | ||
| 2109 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); | 2109 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); |
| 2110 | const blocks = []; | 2110 | const blocks = []; |
| @@ -2885,82 +2885,14 @@ function handleEntryKillSwitchHelper({ entryKillSwitch, entry, data, name, setWI | |||
| 2885 | export async function getWorldEntry(name, data, entry) { | 2885 | export async function getWorldEntry(name, data, entry) { |
| 2886 | if (!data.entries[entry.uid]) return; | 2886 | if (!data.entries[entry.uid]) return; |
| 2887 | 2887 | ||
| 2888 | const template = WI_ENTRY_EDIT_TEMPLATE.clone(); | 2888 | const headerTemplate = WI_ENTRY_HEADER_TEMPLATE.clone(); |
| 2889 | template.data('uid', entry.uid); | 2889 | headerTemplate.data('uid', entry.uid); |
| 2890 | template.attr('uid', entry.uid); | 2890 | headerTemplate.attr('uid', entry.uid); |
| 2891 | 2891 | ||
| 2892 | if (typeof power_user.wi_key_input_plaintext === 'undefined') power_user.wi_key_input_plaintext = true; | 2892 | if (typeof power_user.wi_key_input_plaintext === 'undefined') power_user.wi_key_input_plaintext = true; |
| 2893 | 2893 | ||
| 2894 | // Key inputs | ||
| 2895 | const keyInput = enableKeysInputHelper({ template, entry, entryPropName: 'key', originalDataValueName: 'keys', name, data }); | ||
| 2896 | const keySecondaryInput = enableKeysInputHelper({ template, entry, entryPropName: 'keysecondary', originalDataValueName: 'secondary_keys', name, data }); | ||
| 2897 | |||
| 2898 | // Key input switch | ||
| 2899 | template.find('.switch_input_type_icon').on('click', function () { | ||
| 2900 | power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext; | ||
| 2901 | saveSettingsDebounced(); | ||
| 2902 | const uid = ($(this).parents('.world_entry')).data('uid'); | ||
| 2903 | updateEditor(uid, false); | ||
| 2904 | $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click'); | ||
| 2905 | }).each((_, icon) => { | ||
| 2906 | $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off')); | ||
| 2907 | $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off')); | ||
| 2908 | }); | ||
| 2909 | |||
| 2910 | // Logic AND/NOT | ||
| 2911 | const selectiveLogicDropdown = template.find('select[name="entryLogicType"]'); | ||
| 2912 | selectiveLogicDropdown.data('uid', entry.uid); | ||
| 2913 | selectiveLogicDropdown.on('click', e => e.stopPropagation()); | ||
| 2914 | selectiveLogicDropdown.on('input', async function () { | ||
| 2915 | const uid = $(this).data('uid'); | ||
| 2916 | const value = Number($(this).val()); | ||
| 2917 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; | ||
| 2918 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); | ||
| 2919 | await saveWorldInfo(name, data); | ||
| 2920 | }); | ||
| 2921 | template.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input'); | ||
| 2922 | |||
| 2923 | // Character filter | ||
| 2924 | const characterFilterLabel = template.find('label[for="characterFilter"] > small'); | ||
| 2925 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 2926 | const characterExclusionInput = template.find('input[name="character_exclusion"]'); | ||
| 2927 | characterExclusionInput.data('uid', entry.uid); | ||
| 2928 | characterExclusionInput.on('input', async function () { | ||
| 2929 | const uid = $(this).data('uid'); | ||
| 2930 | const value = $(this).prop('checked'); | ||
| 2931 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 2932 | if (data.entries[uid].characterFilter) { | ||
| 2933 | if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) { | ||
| 2934 | delete data.entries[uid].characterFilter; | ||
| 2935 | } else { | ||
| 2936 | data.entries[uid].characterFilter.isExclude = value; | ||
| 2937 | } | ||
| 2938 | } else if (value) { | ||
| 2939 | Object.assign(data.entries[uid], { characterFilter: { isExclude: true, names: [], tags: [] } }); | ||
| 2940 | } | ||
| 2941 | if (data.entries[uid]?.characterFilter?.names?.length > 0) { | ||
| 2942 | for (const name of [...data.entries[uid].characterFilter.names]) { | ||
| 2943 | if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) { | ||
| 2944 | data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name); | ||
| 2945 | } | ||
| 2946 | } | ||
| 2947 | } | ||
| 2948 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | ||
| 2949 | await saveWorldInfo(name, data); | ||
| 2950 | }); | ||
| 2951 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input'); | ||
| 2952 | |||
| 2953 | const characterFilter = template.find('select[name="characterFilter"]'); | ||
| 2954 | characterFilter.data('uid', entry.uid); | ||
| 2955 | initCharacterFilterSelect2Helper(characterFilter, t); | ||
| 2956 | fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext }); | ||
| 2957 | handleCharacterFilterChangeHelper({ | ||
| 2958 | characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t, | ||
| 2959 | }); | ||
| 2960 | |||
| 2961 | // Comment | 2894 | // Comment |
| 2962 | const commentInput = template.find('textarea[name="comment"]'); | 2895 | const commentInput = headerTemplate.find('textarea[name="comment"]'); |
| 2963 | const commentToggle = template.find('input[name="addMemo"]'); | ||
| 2964 | commentInput.data('uid', entry.uid); | 2896 | commentInput.data('uid', entry.uid); |
| 2965 | commentInput.on('input', async function (_, { skipReset } = {}) { | 2897 | commentInput.on('input', async function (_, { skipReset } = {}) { |
| 2966 | const uid = $(this).data('uid'); | 2898 | const uid = $(this).data('uid'); |
| @@ -2970,157 +2902,43 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2970 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); | 2902 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); |
| 2971 | await saveWorldInfo(name, data); | 2903 | await saveWorldInfo(name, data); |
| 2972 | }); | 2904 | }); |
| 2973 | commentToggle.data('uid', entry.uid); | ||
| 2974 | commentToggle.on('input', async function () { | ||
| 2975 | const uid = $(this).data('uid'); | ||
| 2976 | const value = $(this).prop('checked'); | ||
| 2977 | const commentContainer = $(this).closest('.world_entry').find('.commentContainer'); | ||
| 2978 | data.entries[uid].addMemo = value; | ||
| 2979 | await saveWorldInfo(name, data); | ||
| 2980 | value ? commentContainer.show() : commentContainer.hide(); | ||
| 2981 | }); | ||
| 2982 | commentInput.val(entry.comment).trigger('input', { skipReset: true }); | 2905 | commentInput.val(entry.comment).trigger('input', { skipReset: true }); |
| 2983 | commentToggle.prop('checked', true).trigger('input'); | ||
| 2984 | commentToggle.parent().hide(); | ||
| 2985 | |||
| 2986 | // Content | ||
| 2987 | const counter = template.find('.world_entry_form_token_counter'); | ||
| 2988 | const countTokensDebounced = debounce(async function (counter, value) { | ||
| 2989 | const numberOfTokens = await getTokenCountAsync(value); | ||
| 2990 | $(counter).text(numberOfTokens); | ||
| 2991 | }, debounce_timeout.relaxed); | ||
| 2992 | const contentInputId = `world_entry_content_${entry.uid}`; | ||
| 2993 | const contentInput = template.find('textarea[name="content"]'); | ||
| 2994 | contentInput.data('uid', entry.uid); | ||
| 2995 | contentInput.attr('id', contentInputId); | ||
| 2996 | contentInput.on('input', async function (_, { skipCount } = {}) { | ||
| 2997 | const uid = $(this).data('uid'); | ||
| 2998 | const value = $(this).val(); | ||
| 2999 | data.entries[uid].content = value; | ||
| 3000 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); | ||
| 3001 | await saveWorldInfo(name, data); | ||
| 3002 | if (!skipCount) countTokensDebounced(counter, value); | ||
| 3003 | }); | ||
| 3004 | contentInput.val(entry.content).trigger('input', { skipCount: true }); | ||
| 3005 | template.find('.editor_maximize').attr('data-for', contentInputId); | ||
| 3006 | template.find('.inline-drawer-toggle').on('click', function () { | ||
| 3007 | if (counter.data('first-run')) { | ||
| 3008 | counter.data('first-run', false); | ||
| 3009 | countTokensDebounced(counter, contentInput.val()); | ||
| 3010 | if (!keyInput.isFancy) initScrollHeight(keyInput.control); | ||
| 3011 | if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control); | ||
| 3012 | } | ||
| 3013 | }); | ||
| 3014 | |||
| 3015 | // Selective | ||
| 3016 | const selectiveInput = template.find('input[name="selective"]'); | ||
| 3017 | selectiveInput.data('uid', entry.uid); | ||
| 3018 | selectiveInput.on('input', async function () { | ||
| 3019 | const uid = $(this).data('uid'); | ||
| 3020 | const value = $(this).prop('checked'); | ||
| 3021 | data.entries[uid].selective = value; | ||
| 3022 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); | ||
| 3023 | await saveWorldInfo(name, data); | ||
| 3024 | const keysecondary = $(this).closest('.world_entry').find('.keysecondary'); | ||
| 3025 | const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole'); | ||
| 3026 | const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect'); | ||
| 3027 | const keyprimaryHeight = keyprimaryselect.outerHeight(); | ||
| 3028 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); | ||
| 3029 | value ? keysecondary.show() : keysecondary.hide(); | ||
| 3030 | }); | ||
| 3031 | selectiveInput.prop('checked', true).trigger('input'); | ||
| 3032 | selectiveInput.parent().hide(); | ||
| 3033 | 2906 | ||
| 3034 | // Order | 2907 | // Order |
| 3035 | const orderInput = template.find('input[name="order"]'); | 2908 | const orderInput = headerTemplate.find('input[name="order"]'); |
| 3036 | orderInput.data('uid', entry.uid); | 2909 | orderInput.data('uid', entry.uid); |
| 3037 | orderInput.on('input', async function () { | 2910 | orderInput.on('input', async function () { |
| 3038 | const uid = $(this).data('uid'); | 2911 | const uid = $(this).data('uid'); |
| 3039 | const value = Number($(this).val()); | 2912 | const value = Number($(this).val()); |
| 3040 | data.entries[uid].order = !isNaN(value) ? value : 0; | 2913 | data.entries[uid].order = !isNaN(value) ? value : 0; |
| 3041 | updatePosOrdDisplayHelper({ template, data, uid }); | 2914 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); |
| 3042 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); | 2915 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); |
| 3043 | await saveWorldInfo(name, data); | 2916 | await saveWorldInfo(name, data); |
| 3044 | }); | 2917 | }); |
| 3045 | orderInput.val(entry.order).trigger('input'); | 2918 | orderInput.val(entry.order).trigger('input'); |
| 3046 | orderInput.css('width', 'calc(3em + 15px)'); | 2919 | orderInput.css('width', 'calc(3em + 15px)'); |
| 3047 | 2920 | ||
| 3048 | // Group | ||
| 3049 | const groupInput = template.find('input[name="group"]'); | ||
| 3050 | groupInput.data('uid', entry.uid); | ||
| 3051 | groupInput.on('input', async function () { | ||
| 3052 | const uid = $(this).data('uid'); | ||
| 3053 | const value = String($(this).val()).trim(); | ||
| 3054 | data.entries[uid].group = value; | ||
| 3055 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); | ||
| 3056 | await saveWorldInfo(name, data); | ||
| 3057 | }); | ||
| 3058 | groupInput.val(entry.group ?? '').trigger('input'); | ||
| 3059 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); | ||
| 3060 | |||
| 3061 | // Inclusion priority | ||
| 3062 | const groupOverrideInput = template.find('input[name="groupOverride"]'); | ||
| 3063 | groupOverrideInput.data('uid', entry.uid); | ||
| 3064 | groupOverrideInput.on('input', async function () { | ||
| 3065 | const uid = $(this).data('uid'); | ||
| 3066 | const value = $(this).prop('checked'); | ||
| 3067 | data.entries[uid].groupOverride = value; | ||
| 3068 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); | ||
| 3069 | await saveWorldInfo(name, data); | ||
| 3070 | }); | ||
| 3071 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input'); | ||
| 3072 | |||
| 3073 | // Group weight | ||
| 3074 | handleNumberInputHelper({ | ||
| 3075 | inputElem: template.find('input[name="groupWeight"]'), | ||
| 3076 | entry, entryKey: 'groupWeight', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3077 | min: 1, max: 10000, clamp: true, | ||
| 3078 | }); | ||
| 3079 | |||
| 3080 | // Sticky, cooldown, delay | ||
| 3081 | handleNumberInputHelper({ | ||
| 3082 | inputElem: template.find('input[name="sticky"]'), | ||
| 3083 | entry, entryKey: 'sticky', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3084 | min: 1, max: 10000, clamp: false, | ||
| 3085 | }); | ||
| 3086 | handleNumberInputHelper({ | ||
| 3087 | inputElem: template.find('input[name="cooldown"]'), | ||
| 3088 | entry, entryKey: 'cooldown', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3089 | min: 1, max: 10000, clamp: false, | ||
| 3090 | }); | ||
| 3091 | handleNumberInputHelper({ | ||
| 3092 | inputElem: template.find('input[name="delay"]'), | ||
| 3093 | entry, entryKey: 'delay', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3094 | min: 1, max: 10000, clamp: false, | ||
| 3095 | }); | ||
| 3096 | |||
| 3097 | // Probability | 2921 | // Probability |
| 3098 | handleProbabilityInputHelper({ probabilityInput: template.find('input[name="probability"]'), data, entry, name, setWIOriginalDataValue, saveWorldInfo }); | 2922 | handleProbabilityInputHelper({ probabilityInput: headerTemplate.find('input[name="probability"]'), data, entry, name, setWIOriginalDataValue, saveWorldInfo }); |
| 3099 | handleProbabilityToggleHelper({ | ||
| 3100 | probabilityToggle: template.find('input[name="useProbability"]'), | ||
| 3101 | data, entry, name, | ||
| 3102 | probabilityInput: template.find('input[name="probability"]'), | ||
| 3103 | setWIOriginalDataValue, saveWorldInfo, | ||
| 3104 | }); | ||
| 3105 | 2923 | ||
| 3106 | // Depth | 2924 | // Depth |
| 3107 | handleNumberInputHelper({ | 2925 | handleNumberInputHelper({ |
| 3108 | inputElem: template.find('input[name="depth"]'), | 2926 | inputElem: headerTemplate.find('input[name="depth"]'), |
| 3109 | entry, entryKey: 'depth', data, name, setWIOriginalDataValue, saveWorldInfo, | 2927 | entry, entryKey: 'depth', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3110 | min: 0, max: MAX_SCAN_DEPTH, clamp: false, | 2928 | min: 0, max: MAX_SCAN_DEPTH, clamp: false, |
| 3111 | }); | 2929 | }); |
| 3112 | template.find('input[name="depth"]').css('width', 'calc(3em + 15px)'); | 2930 | headerTemplate.find('input[name="depth"]').css('width', 'calc(3em + 15px)'); |
| 3113 | 2931 | ||
| 3114 | // Position | 2932 | // Position |
| 3115 | if (entry.position === undefined) entry.position = 0; | 2933 | if (entry.position === undefined) entry.position = 0; |
| 3116 | const positionInput = template.find('select[name="position"]'); | 2934 | const positionInput = headerTemplate.find('select[name="position"]'); |
| 3117 | positionInput.data('uid', entry.uid); | 2935 | positionInput.data('uid', entry.uid); |
| 3118 | positionInput.on('click', e => e.stopPropagation()); | 2936 | positionInput.on('click', e => e.stopPropagation()); |
| 3119 | positionInput.on('input', async function () { | 2937 | positionInput.on('input', async function () { |
| 3120 | const uid = $(this).data('uid'); | 2938 | const uid = $(this).data('uid'); |
| 3121 | const value = Number($(this).val()); | 2939 | const value = Number($(this).val()); |
| 3122 | data.entries[uid].position = !isNaN(value) ? value : 0; | 2940 | data.entries[uid].position = !isNaN(value) ? value : 0; |
| 3123 | const depthInput = template.find('input[name="depth"]'); | 2941 | const depthInput = headerTemplate.find('input[name="depth"]'); |
| 3124 | if (value === world_info_position.atDepth) { | 2942 | if (value === world_info_position.atDepth) { |
| 3125 | depthInput.prop('disabled', false); | 2943 | depthInput.prop('disabled', false); |
| 3126 | depthInput.css('visibility', 'visible'); | 2944 | depthInput.css('visibility', 'visible'); |
| @@ -3131,64 +2949,29 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3131 | depthInput.css('visibility', 'hidden'); | 2949 | depthInput.css('visibility', 'hidden'); |
| 3132 | data.entries[uid].role = null; | 2950 | data.entries[uid].role = null; |
| 3133 | } | 2951 | } |
| 3134 | updatePosOrdDisplayHelper({ template, data, uid }); | 2952 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); |
| 3135 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); | 2953 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); |
| 3136 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); | 2954 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); |
| 3137 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); | 2955 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); |
| 3138 | await saveWorldInfo(name, data); | 2956 | await saveWorldInfo(name, data); |
| 3139 | }); | 2957 | }); |
| 3140 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; | 2958 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; |
| 3141 | template.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input'); | 2959 | headerTemplate.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input'); |
| 3142 | |||
| 3143 | // UID display | ||
| 3144 | template.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`); | ||
| 3145 | 2960 | ||
| 3146 | // Tri-state selector | 2961 | // Tri-state selector |
| 3147 | handleEntryStateSelectorHelper({ | 2962 | handleEntryStateSelectorHelper({ |
| 3148 | entryStateSelector: template.find('select[name="entryStateSelector"]'), | 2963 | entryStateSelector: headerTemplate.find('select[name="entryStateSelector"]'), |
| 3149 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, | 2964 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3150 | }); | 2965 | }); |
| 3151 | 2966 | ||
| 3152 | // Kill switch | 2967 | // Kill switch |
| 3153 | handleEntryKillSwitchHelper({ | 2968 | handleEntryKillSwitchHelper({ |
| 3154 | entryKillSwitch: template.find('div[name="entryKillSwitch"]'), | 2969 | entryKillSwitch: headerTemplate.find('div[name="entryKillSwitch"]'), |
| 3155 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, template, | 2970 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, template: headerTemplate, |
| 3156 | }); | ||
| 3157 | |||
| 3158 | // Exclude/prevent recursion | ||
| 3159 | handleMatchCheckboxHelper({ template, entry, fieldName: 'excludeRecursion', data, name }); | ||
| 3160 | handleMatchCheckboxHelper({ template, entry, fieldName: 'preventRecursion', data, name }); | ||
| 3161 | |||
| 3162 | // Delay until recursion | ||
| 3163 | const delayUntilRecursionInput = template.find('input[name="delay_until_recursion"]'); | ||
| 3164 | delayUntilRecursionInput.data('uid', entry.uid); | ||
| 3165 | const delayUntilRecursionLevelInput = template.find('input[name="delayUntilRecursionLevel"]'); | ||
| 3166 | delayUntilRecursionLevelInput.data('uid', entry.uid); | ||
| 3167 | delayUntilRecursionInput.on('input', async function () { | ||
| 3168 | const uid = $(this).data('uid'); | ||
| 3169 | const toggled = $(this).prop('checked'); | ||
| 3170 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; | ||
| 3171 | if (!toggled) delayUntilRecursionLevelInput.val(''); | ||
| 3172 | data.entries[uid].delayUntilRecursion = value; | ||
| 3173 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3174 | await saveWorldInfo(name, data); | ||
| 3175 | }); | ||
| 3176 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input'); | ||
| 3177 | delayUntilRecursionLevelInput.on('input', async function () { | ||
| 3178 | const uid = $(this).data('uid'); | ||
| 3179 | const content = $(this).val(); | ||
| 3180 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) | ||
| 3181 | : content === 1 ? true | ||
| 3182 | : !isNaN(Number(content)) ? Number(content) | ||
| 3183 | : false; | ||
| 3184 | data.entries[uid].delayUntilRecursion = value; | ||
| 3185 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3186 | await saveWorldInfo(name, data); | ||
| 3187 | }); | 2971 | }); |
| 3188 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input'); | ||
| 3189 | 2972 | ||
| 3190 | // Duplicate/delete/move buttons | 2973 | // Duplicate/delete/move buttons |
| 3191 | template.find('.duplicate_entry_button').data('uid', entry.uid).on('click', async function () { | 2974 | headerTemplate.find('.duplicate_entry_button').data('uid', entry.uid).on('click', async function () { |
| 3192 | const uid = $(this).data('uid'); | 2975 | const uid = $(this).data('uid'); |
| 3193 | const entryDup = duplicateWorldInfoEntry(data, uid); | 2976 | const entryDup = duplicateWorldInfoEntry(data, uid); |
| 3194 | if (entryDup) { | 2977 | if (entryDup) { |
| @@ -3196,7 +2979,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3196 | updateEditor(entryDup.uid); | 2979 | updateEditor(entryDup.uid); |
| 3197 | } | 2980 | } |
| 3198 | }); | 2981 | }); |
| 3199 | template.find('.delete_entry_button').data('uid', entry.uid).on('click', async function (e) { | 2982 | headerTemplate.find('.delete_entry_button').data('uid', entry.uid).on('click', async function (e) { |
| 3200 | e.stopPropagation(); | 2983 | e.stopPropagation(); |
| 3201 | const uid = $(this).data('uid'); | 2984 | const uid = $(this).data('uid'); |
| 3202 | const deleted = await deleteWorldInfoEntry(data, uid); | 2985 | const deleted = await deleteWorldInfoEntry(data, uid); |
| @@ -3205,7 +2988,7 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3205 | await saveWorldInfo(name, data); | 2988 | await saveWorldInfo(name, data); |
| 3206 | updateEditor(navigation_option.previous); | 2989 | updateEditor(navigation_option.previous); |
| 3207 | }); | 2990 | }); |
| 3208 | template.find('.move_entry_button').attr('data-uid', entry.uid).attr('data-current-world', name).on('click', async function (e) { | 2991 | headerTemplate.find('.move_entry_button').attr('data-uid', entry.uid).attr('data-current-world', name).on('click', async function (e) { |
| 3209 | e.stopPropagation(); | 2992 | e.stopPropagation(); |
| 3210 | const sourceUid = $(this).attr('data-uid'); | 2993 | const sourceUid = $(this).attr('data-uid'); |
| 3211 | const sourceWorld = $(this).attr('data-current-world'); | 2994 | const sourceWorld = $(this).attr('data-current-world'); |
| @@ -3257,8 +3040,167 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3257 | await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid); | 3040 | await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid); |
| 3258 | }); | 3041 | }); |
| 3259 | 3042 | ||
| 3043 | let drawerInitialized = false; | ||
| 3044 | let drawerDestroyTimeout = null; | ||
| 3045 | headerTemplate.find('.inline-drawer-toggle').on('click', function () { | ||
| 3046 | if (drawerDestroyTimeout) { | ||
| 3047 | clearTimeout(drawerDestroyTimeout); | ||
| 3048 | drawerDestroyTimeout = null; | ||
| 3049 | } | ||
| 3050 | if (drawerInitialized) { | ||
| 3051 | drawerDestroyTimeout = setTimeout(() => { | ||
| 3052 | // Drawer was reopened, so we don't destroy it | ||
| 3053 | if (editOutlet.is(':visible')) { | ||
| 3054 | return; | ||
| 3055 | } | ||
| 3056 | drawerInitialized = false; | ||
| 3057 | clearEntryList(editOutlet); | ||
| 3058 | }, debounce_timeout.relaxed); | ||
| 3059 | } else { | ||
| 3060 | drawerInitialized = true; | ||
| 3061 | addEditorDrawerContent(); | ||
| 3062 | } | ||
| 3063 | }); | ||
| 3064 | |||
| 3065 | const editOutlet = headerTemplate.find('.inline-drawer-outlet'); | ||
| 3066 | |||
| 3067 | function addEditorDrawerContent() { | ||
| 3068 | const editTemplate = WI_ENTRY_EDIT_TEMPLATE.clone(); | ||
| 3069 | |||
| 3070 | // UID display | ||
| 3071 | editTemplate.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`); | ||
| 3072 | |||
| 3073 | // Key inputs | ||
| 3074 | const keyInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'key', originalDataValueName: 'keys', name, data }); | ||
| 3075 | const keySecondaryInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'keysecondary', originalDataValueName: 'secondary_keys', name, data }); | ||
| 3076 | |||
| 3077 | // Key input switch | ||
| 3078 | editTemplate.find('.switch_input_type_icon').on('click', function () { | ||
| 3079 | power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext; | ||
| 3080 | saveSettingsDebounced(); | ||
| 3081 | const uid = ($(this).parents('.world_entry')).data('uid'); | ||
| 3082 | updateEditor(uid, false); | ||
| 3083 | $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click'); | ||
| 3084 | }).each((_, icon) => { | ||
| 3085 | $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off')); | ||
| 3086 | $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off')); | ||
| 3087 | }); | ||
| 3088 | |||
| 3089 | // Probability toggle | ||
| 3090 | handleProbabilityToggleHelper({ | ||
| 3091 | probabilityToggle: editTemplate.find('input[name="useProbability"]'), | ||
| 3092 | data, entry, name, | ||
| 3093 | probabilityInput: headerTemplate.find('input[name="probability"]'), | ||
| 3094 | setWIOriginalDataValue, saveWorldInfo, | ||
| 3095 | }); | ||
| 3096 | |||
| 3097 | // Comment toggle | ||
| 3098 | const commentToggle = editTemplate.find('input[name="addMemo"]'); | ||
| 3099 | commentToggle.data('uid', entry.uid); | ||
| 3100 | commentToggle.on('input', async function () { | ||
| 3101 | const uid = $(this).data('uid'); | ||
| 3102 | const value = $(this).prop('checked'); | ||
| 3103 | const commentContainer = $(this).closest('.world_entry').find('.commentContainer'); | ||
| 3104 | data.entries[uid].addMemo = value; | ||
| 3105 | await saveWorldInfo(name, data); | ||
| 3106 | value ? commentContainer.show() : commentContainer.hide(); | ||
| 3107 | }); | ||
| 3108 | commentToggle.prop('checked', true).trigger('input'); | ||
| 3109 | commentToggle.parent().hide(); | ||
| 3110 | |||
| 3111 | // Logic AND/NOT | ||
| 3112 | const selectiveLogicDropdown = editTemplate.find('select[name="entryLogicType"]'); | ||
| 3113 | selectiveLogicDropdown.data('uid', entry.uid); | ||
| 3114 | selectiveLogicDropdown.on('click', e => e.stopPropagation()); | ||
| 3115 | selectiveLogicDropdown.on('input', async function () { | ||
| 3116 | const uid = $(this).data('uid'); | ||
| 3117 | const value = Number($(this).val()); | ||
| 3118 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; | ||
| 3119 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); | ||
| 3120 | await saveWorldInfo(name, data); | ||
| 3121 | }); | ||
| 3122 | editTemplate.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input'); | ||
| 3123 | |||
| 3124 | // Selective | ||
| 3125 | const selectiveInput = editTemplate.find('input[name="selective"]'); | ||
| 3126 | selectiveInput.data('uid', entry.uid); | ||
| 3127 | selectiveInput.on('input', async function () { | ||
| 3128 | const uid = $(this).data('uid'); | ||
| 3129 | const value = $(this).prop('checked'); | ||
| 3130 | data.entries[uid].selective = value; | ||
| 3131 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); | ||
| 3132 | await saveWorldInfo(name, data); | ||
| 3133 | const keysecondary = $(this).closest('.world_entry').find('.keysecondary'); | ||
| 3134 | const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole'); | ||
| 3135 | const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect'); | ||
| 3136 | const keyprimaryHeight = keyprimaryselect.outerHeight(); | ||
| 3137 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); | ||
| 3138 | value ? keysecondary.show() : keysecondary.hide(); | ||
| 3139 | }); | ||
| 3140 | selectiveInput.prop('checked', true).trigger('input'); | ||
| 3141 | selectiveInput.parent().hide(); | ||
| 3142 | |||
| 3143 | // Character filter | ||
| 3144 | const characterFilterLabel = editTemplate.find('label[for="characterFilter"] > small'); | ||
| 3145 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 3146 | const characterExclusionInput = editTemplate.find('input[name="character_exclusion"]'); | ||
| 3147 | characterExclusionInput.data('uid', entry.uid); | ||
| 3148 | characterExclusionInput.on('input', async function () { | ||
| 3149 | const uid = $(this).data('uid'); | ||
| 3150 | const value = $(this).prop('checked'); | ||
| 3151 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 3152 | if (data.entries[uid].characterFilter) { | ||
| 3153 | if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) { | ||
| 3154 | delete data.entries[uid].characterFilter; | ||
| 3155 | } else { | ||
| 3156 | data.entries[uid].characterFilter.isExclude = value; | ||
| 3157 | } | ||
| 3158 | } else if (value) { | ||
| 3159 | Object.assign(data.entries[uid], { characterFilter: { isExclude: true, names: [], tags: [] } }); | ||
| 3160 | } | ||
| 3161 | if (data.entries[uid]?.characterFilter?.names?.length > 0) { | ||
| 3162 | for (const name of [...data.entries[uid].characterFilter.names]) { | ||
| 3163 | if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) { | ||
| 3164 | data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name); | ||
| 3165 | } | ||
| 3166 | } | ||
| 3167 | } | ||
| 3168 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | ||
| 3169 | await saveWorldInfo(name, data); | ||
| 3170 | }); | ||
| 3171 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input'); | ||
| 3172 | |||
| 3173 | const characterFilter = editTemplate.find('select[name="characterFilter"]'); | ||
| 3174 | characterFilter.data('uid', entry.uid); | ||
| 3175 | initCharacterFilterSelect2Helper(characterFilter, t); | ||
| 3176 | fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext }); | ||
| 3177 | handleCharacterFilterChangeHelper({ | ||
| 3178 | characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t, | ||
| 3179 | }); | ||
| 3180 | |||
| 3181 | // Content | ||
| 3182 | const counter = editTemplate.find('.world_entry_form_token_counter'); | ||
| 3183 | const countTokensDebounced = debounce(async function (counter, value) { | ||
| 3184 | const numberOfTokens = await getTokenCountAsync(value); | ||
| 3185 | $(counter).text(numberOfTokens); | ||
| 3186 | }, debounce_timeout.relaxed); | ||
| 3187 | const contentInputId = `world_entry_content_${entry.uid}`; | ||
| 3188 | const contentInput = editTemplate.find('textarea[name="content"]'); | ||
| 3189 | contentInput.data('uid', entry.uid); | ||
| 3190 | contentInput.attr('id', contentInputId); | ||
| 3191 | contentInput.on('input', async function (_, { skipCount } = {}) { | ||
| 3192 | const uid = $(this).data('uid'); | ||
| 3193 | const value = $(this).val(); | ||
| 3194 | data.entries[uid].content = value; | ||
| 3195 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); | ||
| 3196 | await saveWorldInfo(name, data); | ||
| 3197 | if (!skipCount) countTokensDebounced(counter, value); | ||
| 3198 | }); | ||
| 3199 | contentInput.val(entry.content).trigger('input', { skipCount: true }); | ||
| 3200 | editTemplate.find('.editor_maximize').attr('data-for', contentInputId); | ||
| 3201 | |||
| 3260 | // Scan depth | 3202 | // Scan depth |
| 3261 | const scanDepthInput = template.find('input[name="scanDepth"]'); | 3203 | const scanDepthInput = editTemplate.find('input[name="scanDepth"]'); |
| 3262 | scanDepthInput.data('uid', entry.uid); | 3204 | scanDepthInput.data('uid', entry.uid); |
| 3263 | scanDepthInput.on('input', async function () { | 3205 | scanDepthInput.on('input', async function () { |
| 3264 | const uid = $(this).data('uid'); | 3206 | const uid = $(this).data('uid'); |
| @@ -3280,30 +3222,111 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3280 | }); | 3222 | }); |
| 3281 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input'); | 3223 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input'); |
| 3282 | 3224 | ||
| 3225 | // Group | ||
| 3226 | const groupInput = editTemplate.find('input[name="group"]'); | ||
| 3227 | groupInput.data('uid', entry.uid); | ||
| 3228 | groupInput.on('input', async function () { | ||
| 3229 | const uid = $(this).data('uid'); | ||
| 3230 | const value = String($(this).val()).trim(); | ||
| 3231 | data.entries[uid].group = value; | ||
| 3232 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); | ||
| 3233 | await saveWorldInfo(name, data); | ||
| 3234 | }); | ||
| 3235 | groupInput.val(entry.group ?? '').trigger('input'); | ||
| 3236 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); | ||
| 3237 | |||
| 3238 | // Inclusion priority | ||
| 3239 | const groupOverrideInput = editTemplate.find('input[name="groupOverride"]'); | ||
| 3240 | groupOverrideInput.data('uid', entry.uid); | ||
| 3241 | groupOverrideInput.on('input', async function () { | ||
| 3242 | const uid = $(this).data('uid'); | ||
| 3243 | const value = $(this).prop('checked'); | ||
| 3244 | data.entries[uid].groupOverride = value; | ||
| 3245 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); | ||
| 3246 | await saveWorldInfo(name, data); | ||
| 3247 | }); | ||
| 3248 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input'); | ||
| 3249 | |||
| 3250 | // Group weight | ||
| 3251 | handleNumberInputHelper({ | ||
| 3252 | inputElem: editTemplate.find('input[name="groupWeight"]'), | ||
| 3253 | entry, entryKey: 'groupWeight', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3254 | min: 1, max: 10000, clamp: true, | ||
| 3255 | }); | ||
| 3256 | |||
| 3257 | // Sticky, cooldown, delay | ||
| 3258 | handleNumberInputHelper({ | ||
| 3259 | inputElem: editTemplate.find('input[name="sticky"]'), | ||
| 3260 | entry, entryKey: 'sticky', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3261 | min: 1, max: 10000, clamp: false, | ||
| 3262 | }); | ||
| 3263 | handleNumberInputHelper({ | ||
| 3264 | inputElem: editTemplate.find('input[name="cooldown"]'), | ||
| 3265 | entry, entryKey: 'cooldown', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3266 | min: 1, max: 10000, clamp: false, | ||
| 3267 | }); | ||
| 3268 | handleNumberInputHelper({ | ||
| 3269 | inputElem: editTemplate.find('input[name="delay"]'), | ||
| 3270 | entry, entryKey: 'delay', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3271 | min: 1, max: 10000, clamp: false, | ||
| 3272 | }); | ||
| 3273 | |||
| 3274 | // Exclude/prevent recursion | ||
| 3275 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'excludeRecursion', data, name }); | ||
| 3276 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'preventRecursion', data, name }); | ||
| 3277 | |||
| 3278 | // Delay until recursion | ||
| 3279 | const delayUntilRecursionInput = editTemplate.find('input[name="delay_until_recursion"]'); | ||
| 3280 | delayUntilRecursionInput.data('uid', entry.uid); | ||
| 3281 | const delayUntilRecursionLevelInput = editTemplate.find('input[name="delayUntilRecursionLevel"]'); | ||
| 3282 | delayUntilRecursionLevelInput.data('uid', entry.uid); | ||
| 3283 | delayUntilRecursionInput.on('input', async function () { | ||
| 3284 | const uid = $(this).data('uid'); | ||
| 3285 | const toggled = $(this).prop('checked'); | ||
| 3286 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; | ||
| 3287 | if (!toggled) delayUntilRecursionLevelInput.val(''); | ||
| 3288 | data.entries[uid].delayUntilRecursion = value; | ||
| 3289 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3290 | await saveWorldInfo(name, data); | ||
| 3291 | }); | ||
| 3292 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input'); | ||
| 3293 | delayUntilRecursionLevelInput.on('input', async function () { | ||
| 3294 | const uid = $(this).data('uid'); | ||
| 3295 | const content = $(this).val(); | ||
| 3296 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) | ||
| 3297 | : content === 1 ? true | ||
| 3298 | : !isNaN(Number(content)) ? Number(content) | ||
| 3299 | : false; | ||
| 3300 | data.entries[uid].delayUntilRecursion = value; | ||
| 3301 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3302 | await saveWorldInfo(name, data); | ||
| 3303 | }); | ||
| 3304 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input'); | ||
| 3305 | |||
| 3283 | // Boolean selects | 3306 | // Boolean selects |
| 3284 | handleBooleanSelectHelper({ | 3307 | handleBooleanSelectHelper({ |
| 3285 | selectElem: template.find('select[name="caseSensitive"]'), | 3308 | selectElem: editTemplate.find('select[name="caseSensitive"]'), |
| 3286 | entry, entryKey: 'caseSensitive', data, name, setWIOriginalDataValue, saveWorldInfo, | 3309 | entry, entryKey: 'caseSensitive', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3287 | }); | 3310 | }); |
| 3288 | handleBooleanSelectHelper({ | 3311 | handleBooleanSelectHelper({ |
| 3289 | selectElem: template.find('select[name="matchWholeWords"]'), | 3312 | selectElem: editTemplate.find('select[name="matchWholeWords"]'), |
| 3290 | entry, entryKey: 'matchWholeWords', data, name, setWIOriginalDataValue, saveWorldInfo, | 3313 | entry, entryKey: 'matchWholeWords', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3291 | }); | 3314 | }); |
| 3292 | handleBooleanSelectHelper({ | 3315 | handleBooleanSelectHelper({ |
| 3293 | selectElem: template.find('select[name="useGroupScoring"]'), | 3316 | selectElem: editTemplate.find('select[name="useGroupScoring"]'), |
| 3294 | entry, entryKey: 'useGroupScoring', data, name, setWIOriginalDataValue, saveWorldInfo, | 3317 | entry, entryKey: 'useGroupScoring', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3295 | }); | 3318 | }); |
| 3296 | 3319 | ||
| 3297 | // Match checkboxes | 3320 | // Match checkboxes |
| 3298 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchPersonaDescription', data, name }); | 3321 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchPersonaDescription', data, name }); |
| 3299 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterDescription', data, name }); | 3322 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDescription', data, name }); |
| 3300 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterPersonality', data, name }); | 3323 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterPersonality', data, name }); |
| 3301 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCharacterDepthPrompt', data, name }); | 3324 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDepthPrompt', data, name }); |
| 3302 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchScenario', data, name }); | 3325 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchScenario', data, name }); |
| 3303 | handleMatchCheckboxHelper({ template, entry, fieldName: 'matchCreatorNotes', data, name }); | 3326 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCreatorNotes', data, name }); |
| 3304 | 3327 | ||
| 3305 | // Automation ID | 3328 | // Automation ID |
| 3306 | const automationIdInput = template.find('input[name="automationId"]'); | 3329 | const automationIdInput = editTemplate.find('input[name="automationId"]'); |
| 3307 | automationIdInput.data('uid', entry.uid); | 3330 | automationIdInput.data('uid', entry.uid); |
| 3308 | automationIdInput.on('input', async function () { | 3331 | automationIdInput.on('input', async function () { |
| 3309 | const uid = $(this).data('uid'); | 3332 | const uid = $(this).data('uid'); |
| @@ -3315,9 +3338,17 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3315 | automationIdInput.val(entry.automationId ?? '').trigger('input'); | 3338 | automationIdInput.val(entry.automationId ?? '').trigger('input'); |
| 3316 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); | 3339 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); |
| 3317 | 3340 | ||
| 3318 | template.find('.inline-drawer-content').css('display', 'none'); | 3341 | countTokensDebounced(counter, contentInput.val()); |
| 3342 | if (!keyInput.isFancy) initScrollHeight(keyInput.control); | ||
| 3343 | if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control); | ||
| 3344 | |||
| 3345 | editTemplate.find('.inline-drawer-content').css('display', 'none'); | ||
| 3346 | editOutlet.append(editTemplate); | ||
| 3347 | } | ||
| 3348 | |||
| 3349 | headerTemplate.find('.inline-drawer-content').css('display', 'none'); | ||
| 3319 | 3350 | ||
| 3320 | return template; | 3351 | return headerTemplate; |
| 3321 | } | 3352 | } |
| 3322 | 3353 | ||
| 3323 | /** | 3354 | /** |