Merge pull request #4096 from SillyTavern/TopbarFadeMUIAndGetWorldEntryRefactors UI performance optimizations and refactoring
Signed| @@ -55,6 +55,7 @@ | |||
| 55 | 55 | ||
| 56 | /* Flashing for highlighting animation */ | 56 | /* Flashing for highlighting animation */ |
| 57 | @keyframes flash { | 57 | @keyframes flash { |
| 58 | |||
| 58 | 0%, | 59 | 0%, |
| 59 | 50%, | 60 | 50%, |
| 60 | 100% { | 61 | 100% { |
| @@ -122,3 +123,12 @@ | |||
| 122 | border-top-color: var(--progFlashColor); | 123 | border-top-color: var(--progFlashColor); |
| 123 | } | 124 | } |
| 124 | } | 125 | } |
| 126 | |||
| 127 | /* Scroll delay animations */ | ||
| 128 | @keyframes hide-scroll { | ||
| 129 | |||
| 130 | from, | ||
| 131 | to { | ||
| 132 | overflow-y: hidden; | ||
| 133 | } | ||
| 134 | } | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | #rm_print_characters_block.group_overlay_mode_select .character_select { | 1 | #rm_print_characters_block.group_overlay_mode_select .character_select { |
| 2 | transition: background-color 0.4s ease; | 2 | transition: background-color var(--animation-duration-3x) ease; |
| 3 | background-color: rgba(170, 170, 170, 0.15); | 3 | background-color: rgba(170, 170, 170, 0.15); |
| 4 | } | 4 | } |
| 5 | 5 | ||
| @@ -18,7 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | #load-spinner { | 19 | #load-spinner { |
| 20 | --spinner-size: 2em; | 20 | --spinner-size: 2em; |
| 21 | transition: all 300ms ease-out; | 21 | transition: all var(--animation-duration-2x) ease-out; |
| 22 | opacity: 1; | 22 | opacity: 1; |
| 23 | top: calc(50% - var(--spinner-size) / 2); | 23 | top: calc(50% - var(--spinner-size) / 2); |
| 24 | left: calc(50% - var(--spinner-size) / 2); | 24 | left: calc(50% - var(--spinner-size) / 2); |
| @@ -23,7 +23,7 @@ body.login .userSelect { | |||
| 23 | width: 30%; | 23 | width: 30%; |
| 24 | cursor: pointer; | 24 | cursor: pointer; |
| 25 | margin: 5px 0; | 25 | margin: 5px 0; |
| 26 | transition: background-color 0.15s ease-in-out; | 26 | transition: background-color var(--animation-duration) ease-in-out; |
| 27 | display: flex; | 27 | display: flex; |
| 28 | align-items: center; | 28 | align-items: center; |
| 29 | justify-content: center; | 29 | justify-content: center; |
| @@ -43,7 +43,7 @@ | |||
| 43 | height: 25px; | 43 | height: 25px; |
| 44 | margin-left: 5px; | 44 | margin-left: 5px; |
| 45 | opacity: 0.5; | 45 | opacity: 0.5; |
| 46 | transition: all 250ms; | 46 | transition: all var(--animation-duration-2x); |
| 47 | position: unset !important; | 47 | position: unset !important; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| @@ -237,6 +237,15 @@ | |||
| 237 | top: var(--topBarBlockSize) !important; | 237 | top: var(--topBarBlockSize) !important; |
| 238 | left: 0 !important; | 238 | left: 0 !important; |
| 239 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); | 239 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2)); |
| 240 | |||
| 241 | @starting-style { | ||
| 242 | height: 0; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | #left-nav-panel:not(.openDrawer), | ||
| 247 | #right-nav-panel:not(.openDrawer) { | ||
| 248 | height: 0; | ||
| 240 | } | 249 | } |
| 241 | 250 | ||
| 242 | /* | 251 | /* |
| @@ -79,7 +79,7 @@ | |||
| 79 | justify-content: center; | 79 | justify-content: center; |
| 80 | margin-left: 0.25em; | 80 | margin-left: 0.25em; |
| 81 | cursor: pointer; | 81 | cursor: pointer; |
| 82 | transition: 0.3s ease-in-out; | 82 | transition: var(--animation-duration-2x) ease-in-out; |
| 83 | height: 20px; | 83 | height: 20px; |
| 84 | width: 20px; | 84 | width: 20px; |
| 85 | filter: drop-shadow(0px 0px 2px black); | 85 | filter: drop-shadow(0px 0px 2px black); |
| @@ -239,7 +239,7 @@ | |||
| 239 | flex-direction: column; | 239 | flex-direction: column; |
| 240 | justify-content: center; | 240 | justify-content: center; |
| 241 | margin-left: 0.25em; | 241 | margin-left: 0.25em; |
| 242 | transition: 0.3s ease-in-out; | 242 | transition: var(--animation-duration-2x) ease-in-out; |
| 243 | filter: drop-shadow(0px 0px 2px black); | 243 | filter: drop-shadow(0px 0px 2px black); |
| 244 | } | 244 | } |
| 245 | 245 | ||
| @@ -172,7 +172,7 @@ | |||
| 172 | #rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"] { | 172 | #rm_group_members .group_member:not(.disabled) .right_menu_button[data-action="disable"] { |
| 173 | opacity: 0.4; | 173 | opacity: 0.4; |
| 174 | filter: brightness(0.5); | 174 | filter: brightness(0.5); |
| 175 | transition: all 0.2s ease-in-out; | 175 | transition: all var(--animation-duration-2x) ease-in-out; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | /* #rm_group_members .right_menu_button[data-action="speak"]:hover, */ | 178 | /* #rm_group_members .right_menu_button[data-action="speak"]:hover, */ |
| @@ -125,7 +125,7 @@ | |||
| 125 | background-color: unset; | 125 | background-color: unset; |
| 126 | color: var(--SmartThemeBodyColor); | 126 | color: var(--SmartThemeBodyColor); |
| 127 | opacity: 0.5; | 127 | opacity: 0.5; |
| 128 | transition: opacity 200ms ease-in-out; | 128 | transition: opacity var(--animation-duration-2x) ease-in-out; |
| 129 | position: relative; | 129 | position: relative; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| @@ -203,7 +203,7 @@ | |||
| 203 | /* Styling for choice remove icon */ | 203 | /* Styling for choice remove icon */ |
| 204 | span.select2.select2-container .select2-selection__choice__remove { | 204 | span.select2.select2-container .select2-selection__choice__remove { |
| 205 | cursor: pointer; | 205 | cursor: pointer; |
| 206 | transition: background-color 0.3s; | 206 | transition: background-color var(--animation-duration-2x); |
| 207 | color: var(--SmartThemeBodyColor); | 207 | color: var(--SmartThemeBodyColor); |
| 208 | background-color: var(--black50a); | 208 | background-color: var(--black50a); |
| 209 | } | 209 | } |
| @@ -220,7 +220,7 @@ span.select2.select2-container .select2-selection__choice__remove:hover { | |||
| 220 | 220 | ||
| 221 | .select2_choice_clickable_buttonstyle+span.select2-container .select2-selection__choice__display { | 221 | .select2_choice_clickable_buttonstyle+span.select2-container .select2-selection__choice__display { |
| 222 | cursor: pointer; | 222 | cursor: pointer; |
| 223 | transition: background-color 0.3s; | 223 | transition: background-color var(--animation-duration-2x); |
| 224 | color: var(--SmartThemeBodyColor); | 224 | color: var(--SmartThemeBodyColor); |
| 225 | background-color: var(--black50a); | 225 | background-color: var(--black50a); |
| 226 | white-space: break-spaces; | 226 | white-space: break-spaces; |
| @@ -332,6 +332,10 @@ | |||
| 332 | overflow: hidden; | 332 | overflow: hidden; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | .overflowYScroll { | ||
| 336 | overflow-y: scroll; | ||
| 337 | } | ||
| 338 | |||
| 335 | .padding0 { | 339 | .padding0 { |
| 336 | padding: 0; | 340 | padding: 0; |
| 337 | } | 341 | } |
| @@ -480,7 +484,7 @@ | |||
| 480 | } | 484 | } |
| 481 | 485 | ||
| 482 | .hoverglow { | 486 | .hoverglow { |
| 483 | transition: opacity 200ms; | 487 | transition: opacity var(--animation-duration-2x); |
| 484 | } | 488 | } |
| 485 | 489 | ||
| 486 | .hoverglow:hover { | 490 | .hoverglow:hover { |
| @@ -167,7 +167,7 @@ | |||
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | .rm_tag_filter .tag.actionable { | 169 | .rm_tag_filter .tag.actionable { |
| 170 | transition: opacity 200ms; | 170 | transition: opacity var(--animation-duration-2x); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | .rm_tag_filter .tag:hover { | 173 | .rm_tag_filter .tag:hover { |
| @@ -19,6 +19,7 @@ body:not(.tts) #ttsExtensionNarrateAll { | |||
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | body.no-hotswap .hotswap, | 21 | body.no-hotswap .hotswap, |
| 22 | body.no-hotswap .hotswap~hr, | ||
| 22 | body.no-timer .mes_timer, | 23 | body.no-timer .mes_timer, |
| 23 | body.no-timestamps .timestamp, | 24 | body.no-timestamps .timestamp, |
| 24 | body.no-tokenCount .tokenCounterDisplay, | 25 | body.no-tokenCount .tokenCounterDisplay, |
| @@ -28,6 +29,12 @@ body.hideChatAvatars .mesAvatarWrapper .avatar { | |||
| 28 | display: none !important; | 29 | display: none !important; |
| 29 | } | 30 | } |
| 30 | 31 | ||
| 32 | body.no-hotswap #CharListButtonAndHotSwaps .flex-container { | ||
| 33 | flex-wrap: nowrap; | ||
| 34 | align-items: flex-end; | ||
| 35 | flex-flow: row; | ||
| 36 | } | ||
| 37 | |||
| 31 | body.hideChatAvatars .last_mes:not(.smallSysMes) { | 38 | body.hideChatAvatars .last_mes:not(.smallSysMes) { |
| 32 | padding-bottom: 20px !important; | 39 | padding-bottom: 20px !important; |
| 33 | } | 40 | } |
| @@ -198,7 +198,11 @@ | |||
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | .world_entry { | 200 | .world_entry { |
| 201 | transition: opacity 500ms; | 201 | transition: opacity var(--animation-duration-3x); |
| 202 | } | ||
| 203 | |||
| 204 | .world_entry_edit { | ||
| 205 | display: contents; | ||
| 202 | } | 206 | } |
| 203 | 207 | ||
| 204 | .disabledWIEntry { | 208 | .disabledWIEntry { |
| @@ -267,7 +271,7 @@ select.keyselect+span.select2-container .select2-selection--multiple { | |||
| 267 | 271 | ||
| 268 | opacity: 0.5; | 272 | opacity: 0.5; |
| 269 | color: var(--SmartThemeBodyColor); | 273 | color: var(--SmartThemeBodyColor); |
| 270 | transition: opacity 0.3s; | 274 | transition: opacity var(--animation-duration-2x); |
| 271 | } | 275 | } |
| 272 | 276 | ||
| 273 | .switch_input_type_icon:hover { | 277 | .switch_input_type_icon:hover { |
| @@ -140,7 +140,7 @@ | |||
| 140 | <div data-preset-manager-import="novel" class="margin0 menu_button_icon menu_button" title="Import preset" data-i18n="[title]Import preset"> | 140 | <div data-preset-manager-import="novel" class="margin0 menu_button_icon menu_button" title="Import preset" data-i18n="[title]Import preset"> |
| 141 | <i class="fa-fw fa-solid fa-file-import"></i> | 141 | <i class="fa-fw fa-solid fa-file-import"></i> |
| 142 | </div> | 142 | </div> |
| 143 | <div data-preset-manager-export="novel" class="margin0 menu_button_icon menu_button" title="Export preset" data-i18n="[title]Export preset"> | 143 | <div data-preset-manager-export="novel" class="margin0 menu_button_icon menu_button" title="Export preset" data-i18n="[title]Export preset"> |
| 144 | <i class="fa-fw fa-solid fa-file-export"></i> | 144 | <i class="fa-fw fa-solid fa-file-export"></i> |
| 145 | </div> | 145 | </div> |
| 146 | <div data-preset-manager-delete="novel" class="margin0 menu_button_icon menu_button" title="Delete the preset" data-i18n="[title]Delete the preset"> | 146 | <div data-preset-manager-delete="novel" class="margin0 menu_button_icon menu_button" title="Delete the preset" data-i18n="[title]Delete the preset"> |
| @@ -663,7 +663,7 @@ | |||
| 663 | <div data-source="openrouter" class="range-block"> | 663 | <div data-source="openrouter" class="range-block"> |
| 664 | <div class="range-block-title" title="Allow compressing requests by removing messages from the middle of the prompt."> | 664 | <div class="range-block-title" title="Allow compressing requests by removing messages from the middle of the prompt."> |
| 665 | <span data-i18n="Middle-out Transform">Middle-out Transform</span> | 665 | <span data-i18n="Middle-out Transform">Middle-out Transform</span> |
| 666 | <a href="https://openrouter.ai/docs/transforms" target="_blank" rel="noreferrer noopener" class="note-link-span fa-solid fa-circle-question"></a> | 666 | <a href="https://openrouter.ai/docs/transforms" target="_blank" rel="noreferrer noopener" class="note-link-span fa-solid fa-circle-question"></a> |
| 667 | </div> | 667 | </div> |
| 668 | <div class="wide100p"> | 668 | <div class="wide100p"> |
| 669 | <select id="openrouter_middleout" class="text_pole"> | 669 | <select id="openrouter_middleout" class="text_pole"> |
| @@ -3301,16 +3301,16 @@ | |||
| 3301 | <span id="vertexai_service_account_info"></span> | 3301 | <span id="vertexai_service_account_info"></span> |
| 3302 | </div> | 3302 | </div> |
| 3303 | <textarea id="vertexai_service_account_json" class="text_pole textarea_compact" rows="4" placeholder='Paste your Service Account JSON content here, e.g.: | 3303 | <textarea id="vertexai_service_account_json" class="text_pole textarea_compact" rows="4" placeholder='Paste your Service Account JSON content here, e.g.: |
| 3304 | { | 3304 | { |
| 3305 | "type": "service_account", | 3305 | "type": "service_account", |
| 3306 | "project_id": "your-project-id", | 3306 | "project_id": "your-project-id", |
| 3307 | "private_key_id": "...", | 3307 | "private_key_id": "...", |
| 3308 | "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n", | 3308 | "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n", |
| 3309 | "client_email": "...", | 3309 | "client_email": "...", |
| 3310 | "client_id": "...", | 3310 | "client_id": "...", |
| 3311 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", | 3311 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", |
| 3312 | "token_uri": "https://oauth2.googleapis.com/token" | 3312 | "token_uri": "https://oauth2.googleapis.com/token" |
| 3313 | }'></textarea> | 3313 | }'></textarea> |
| 3314 | <div data-for="vertexai_service_account_json" class="neutral_warning" data-i18n="For privacy reasons, your Service Account JSON content will be hidden after you reload the page."> | 3314 | <div data-for="vertexai_service_account_json" class="neutral_warning" data-i18n="For privacy reasons, your Service Account JSON content will be hidden after you reload the page."> |
| 3315 | For privacy reasons, your Service Account JSON content will be hidden after you reload the page. | 3315 | For privacy reasons, your Service Account JSON content will be hidden after you reload the page. |
| 3316 | </div> | 3316 | </div> |
| @@ -3827,7 +3827,7 @@ | |||
| 3827 | <input id="instruct_bind_to_context" type="checkbox" style="display:none;" /> | 3827 | <input id="instruct_bind_to_context" type="checkbox" style="display:none;" /> |
| 3828 | <small><i class="fa-solid fa-link menu_button margin0"></i></small> | 3828 | <small><i class="fa-solid fa-link menu_button margin0"></i></small> |
| 3829 | </label> | 3829 | </label> |
| 3830 | <label id="instruct_enabled_label"for="instruct_enabled" class="checkbox_label flex1" title="Enable Instruct Mode" data-i18n="[title]instruct_enabled"> | 3830 | <label id="instruct_enabled_label" for="instruct_enabled" class="checkbox_label flex1" title="Enable Instruct Mode" data-i18n="[title]instruct_enabled"> |
| 3831 | <input id="instruct_enabled" type="checkbox" style="display:none;" /> | 3831 | <input id="instruct_enabled" type="checkbox" style="display:none;" /> |
| 3832 | <small><i class="fa-solid fa-power-off menu_button togglable margin0"></i></small> | 3832 | <small><i class="fa-solid fa-power-off menu_button togglable margin0"></i></small> |
| 3833 | </label> | 3833 | </label> |
| @@ -5286,7 +5286,7 @@ | |||
| 5286 | <div class="flex-container wide100p alignitemscenter spaceBetween flexNoGap"> | 5286 | <div class="flex-container wide100p alignitemscenter spaceBetween flexNoGap"> |
| 5287 | <div class="flex-container alignItemsBaseline wide100p"> | 5287 | <div class="flex-container alignItemsBaseline wide100p"> |
| 5288 | <div class="flex1 flex-container alignItemsBaseline"> | 5288 | <div class="flex1 flex-container alignItemsBaseline"> |
| 5289 | <h3 class="margin0" > | 5289 | <h3 class="margin0"> |
| 5290 | <span data-i18n="Persona Management">Persona Management</span> | 5290 | <span data-i18n="Persona Management">Persona Management</span> |
| 5291 | <a href="https://docs.sillytavern.app/usage/core-concepts/personas/" target="_blank"> | 5291 | <a href="https://docs.sillytavern.app/usage/core-concepts/personas/" target="_blank"> |
| 5292 | <span class="fa-solid fa-circle-question note-link-span"></span> | 5292 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| @@ -5457,10 +5457,12 @@ | |||
| 5457 | <div class="right_menu_button fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters" data-i18n="[title]Select/Create Characters"></div> | 5457 | <div class="right_menu_button fa-solid fa-list-ul" id="rm_button_characters" title="Select/Create Characters" data-i18n="[title]Select/Create Characters"></div> |
| 5458 | </div> | 5458 | </div> |
| 5459 | <div id="HotSwapWrapper" class="alignitemscenter flex-container margin0auto wide100p"> | 5459 | <div id="HotSwapWrapper" class="alignitemscenter flex-container margin0auto wide100p"> |
| 5460 | <div class="hotswap avatars_inline scroll-reset-container expander" data-i18n="[no_favs]Favorite characters to add them to HotSwaps" no_favs="Favorite characters to add them to HotSwaps"></div> | 5460 | <div class="hotswap avatars_inline scroll-reset-container expander" data-i18n="[no_favs]Favorite characters to add them to HotSwaps" no_favs="Favorite characters to add them to HotSwaps"> |
| 5461 | </div> | ||
| 5462 | <hr class="wide100p"> | ||
| 5461 | </div> | 5463 | </div> |
| 5462 | </div> | 5464 | </div> |
| 5463 | <hr> | 5465 | |
| 5464 | <!-- this div structure must be preserved until group peeking can adjust --> | 5466 | <!-- this div structure must be preserved until group peeking can adjust --> |
| 5465 | <div id="rm_PinAndTabs"> | 5467 | <div id="rm_PinAndTabs"> |
| 5466 | <div id="right-nav-panel-tabs" class=""> | 5468 | <div id="right-nav-panel-tabs" class=""> |
| @@ -5485,340 +5487,343 @@ | |||
| 5485 | </div> | 5487 | </div> |
| 5486 | </div> | 5488 | </div> |
| 5487 | <!-- end group peeking cope structure--> | 5489 | <!-- end group peeking cope structure--> |
| 5488 | <div name="Solo Char Create/Edit Panel" id="rm_ch_create_block" class="right_menu flex-container flexFlowColumn" style="display: none;"> | 5490 | |
| 5489 | <form id="form_create" action="javascript:void(null);" method="post" enctype="multipart/form-data"> | 5491 | <div class="scrollableInner"> |
| 5490 | <div id="avatar-and-name-block"> | 5492 | <div name="Solo Char Create/Edit Panel" id="rm_ch_create_block" class="right_menu flex-container flexFlowColumn" style="display: none;"> |
| 5491 | <div id="name_div"> | 5493 | <form id="form_create" action="javascript:void(null);" method="post" enctype="multipart/form-data"> |
| 5492 | <input id="character_name_pole" name="ch_name" class="text_pole" data-i18n="[placeholder]Name this character" placeholder="Name this character" value="" autocomplete="off"> | 5494 | <div id="avatar-and-name-block"> |
| 5493 | <div class="extension_token_counter"> | 5495 | <div id="name_div"> |
| 5494 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="character_name_pole" data-token-permanent="true">counting...</span> | 5496 | <input id="character_name_pole" name="ch_name" class="text_pole" data-i18n="[placeholder]Name this character" placeholder="Name this character" value="" autocomplete="off"> |
| 5495 | </div> | 5497 | <div class="extension_token_counter"> |
| 5496 | </div> | 5498 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="character_name_pole" data-token-permanent="true">counting...</span> |
| 5497 | <div class="flex-container flexFlowColumn expander flexNoGap"> | 5499 | </div> |
| 5498 | <div id="avatar_div" class="avatar_div buttons_block alignitemsflexstart justifySpaceBetween flexnowrap"> | 5500 | </div> |
| 5499 | <label id="avatar_div_div" class="add_avatar avatar" for="add_avatar_button" title="Click to select a new avatar for this character" data-i18n="[title]Click to select a new avatar for this character"> | 5501 | <div class="flex-container flexFlowColumn expander flexNoGap"> |
| 5500 | <img id="avatar_load_preview" src="img/ai4.png" alt="avatar"> | 5502 | <div id="avatar_div" class="avatar_div buttons_block alignitemsflexstart justifySpaceBetween flexnowrap"> |
| 5501 | <input hidden type="file" id="add_avatar_button" name="avatar" accept="image/*"> | 5503 | <label id="avatar_div_div" class="add_avatar avatar" for="add_avatar_button" title="Click to select a new avatar for this character" data-i18n="[title]Click to select a new avatar for this character"> |
| 5502 | </label> | 5504 | <img id="avatar_load_preview" src="img/ai4.png" alt="avatar"> |
| 5503 | <div class="flex-container" id="avatar_controls"> | 5505 | <input hidden type="file" id="add_avatar_button" name="avatar" accept="image/*"> |
| 5504 | <div class="form_create_bottom_buttons_block buttons_block"> | 5506 | </label> |
| 5505 | <div id="rm_button_back" class="menu_button fa-solid fa-left-long "></div> | 5507 | <div class="flex-container" id="avatar_controls"> |
| 5506 | <!-- <div id="renameCharButton" class="menu_button fa-solid fa-user-pen" title="Rename Character"></div> --> | 5508 | <div class="form_create_bottom_buttons_block buttons_block"> |
| 5507 | <div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> | 5509 | <div id="rm_button_back" class="menu_button fa-solid fa-left-long "></div> |
| 5508 | <input type="hidden" id="fav_checkbox" name="fav" /> | 5510 | <!-- <div id="renameCharButton" class="menu_button fa-solid fa-user-pen" title="Rename Character"></div> --> |
| 5509 | <div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions" data-i18n="[title]Advanced Definition"></div> | 5511 | <div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> |
| 5510 | <div id="world_button" class="menu_button fa-solid fa-globe" title="Character Lore Click to load Shift-click to open 'Link to World Info' popup" data-i18n="[title]world_button_title"></div> | 5512 | <input type="hidden" id="fav_checkbox" name="fav" /> |
| 5511 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Alt+Click to open the lorebook" data-i18n="[title]Chat Lore Alt+Click to open the lorebook"></div> | 5513 | <div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions" data-i18n="[title]Advanced Definition"></div> |
| 5512 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> | 5514 | <div id="world_button" class="menu_button fa-solid fa-globe" title="Character Lore Click to load Shift-click to open 'Link to World Info' popup" data-i18n="[title]world_button_title"></div> |
| 5513 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> | 5515 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Alt+Click to open the lorebook" data-i18n="[title]Chat Lore Alt+Click to open the lorebook"></div> |
| 5514 | <!-- <div id="set_chat_scenario" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> | 5516 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> |
| 5515 | <!-- <div id="set_character_world" class="menu_button fa-solid fa-globe" title="Set a character World Info / Lorebook"></div> --> | 5517 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> |
| 5516 | <div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character" data-i18n="[title]Duplicate Character"></div> | 5518 | <!-- <div id="set_chat_scenario" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> |
| 5517 | <label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character" data-i18n="[title]Create Character"> | 5519 | <!-- <div id="set_character_world" class="menu_button fa-solid fa-globe" title="Set a character World Info / Lorebook"></div> --> |
| 5518 | <input type="submit" id="create_button" name="create_button"> | 5520 | <div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character" data-i18n="[title]Duplicate Character"></div> |
| 5519 | </label> | 5521 | <label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character" data-i18n="[title]Create Character"> |
| 5520 | <div id="delete_button" class="menu_button fa-solid fa-skull red_button" title="Delete Character" data-i18n="[title]Delete Character"></div> | 5522 | <input type="submit" id="create_button" name="create_button"> |
| 5521 | </div> | 5523 | </label> |
| 5522 | <label class="flex1 height100p" for="char-management-dropdown"> | 5524 | <div id="delete_button" class="menu_button fa-solid fa-skull red_button" title="Delete Character" data-i18n="[title]Delete Character"></div> |
| 5523 | <select id="char-management-dropdown" class="text_pole"> | 5525 | </div> |
| 5524 | <option value="default" disabled selected data-i18n="More...">More...</option> | 5526 | <label class="flex1 height100p" for="char-management-dropdown"> |
| 5525 | <option id="set_character_world" data-i18n="Link to World Info"> | 5527 | <select id="char-management-dropdown" class="text_pole"> |
| 5526 | Link to World Info | 5528 | <option value="default" disabled selected data-i18n="More...">More...</option> |
| 5527 | </option> | 5529 | <option id="set_character_world" data-i18n="Link to World Info"> |
| 5528 | <option id="import_character_info" data-i18n="Import Card Lore"> | 5530 | Link to World Info |
| 5529 | Import Card Lore | ||
| 5530 | </option> | ||
| 5531 | <option id="set_chat_scenario" data-i18n="Scenario Override"> | ||
| 5532 | Scenario Override | ||
| 5533 | </option> | ||
| 5534 | <option id="convert_to_persona" data-i18n="Convert to Persona"> | ||
| 5535 | Convert to Persona | ||
| 5536 | </option> | ||
| 5537 | <option id="renameCharButton" data-i18n="Rename"> | ||
| 5538 | Rename | ||
| 5539 | </option> | ||
| 5540 | <option id="character_source" data-i18n="Link to Source"> | ||
| 5541 | Link to Source | ||
| 5542 | </option> | ||
| 5543 | <option id="replace_update" data-i18n="Replace / Update"> | ||
| 5544 | Replace / Update | ||
| 5545 | </option> | ||
| 5546 | <option id="import_tags" data-i18n="Import Tags"> | ||
| 5547 | Import Tags | ||
| 5548 | </option> | ||
| 5549 | <option id="set_as_assistant" data-i18n="Set / Unset as Welcome Page Assistant"> | ||
| 5550 | Set / Unset as Welcome Page Assistant | ||
| 5551 | </option> | ||
| 5552 | <!--<option id="dupe_button"> | ||
| 5553 | Duplicate | ||
| 5554 | </option> | 5531 | </option> |
| 5555 | <option id="export_button"> | 5532 | <option id="import_character_info" data-i18n="Import Card Lore"> |
| 5556 | Export | 5533 | Import Card Lore |
| 5557 | </option> | 5534 | </option> |
| 5558 | <option id="delete_button"> | 5535 | <option id="set_chat_scenario" data-i18n="Scenario Override"> |
| 5559 | Delete | 5536 | Scenario Override |
| 5560 | </option>--> | 5537 | </option> |
| 5561 | </select> | 5538 | <option id="convert_to_persona" data-i18n="Convert to Persona"> |
| 5562 | </label> | 5539 | Convert to Persona |
| 5540 | </option> | ||
| 5541 | <option id="renameCharButton" data-i18n="Rename"> | ||
| 5542 | Rename | ||
| 5543 | </option> | ||
| 5544 | <option id="character_source" data-i18n="Link to Source"> | ||
| 5545 | Link to Source | ||
| 5546 | </option> | ||
| 5547 | <option id="replace_update" data-i18n="Replace / Update"> | ||
| 5548 | Replace / Update | ||
| 5549 | </option> | ||
| 5550 | <option id="import_tags" data-i18n="Import Tags"> | ||
| 5551 | Import Tags | ||
| 5552 | </option> | ||
| 5553 | <option id="set_as_assistant" data-i18n="Set / Unset as Welcome Page Assistant"> | ||
| 5554 | Set / Unset as Welcome Page Assistant | ||
| 5555 | </option> | ||
| 5556 | <!--<option id="dupe_button"> | ||
| 5557 | Duplicate | ||
| 5558 | </option> | ||
| 5559 | <option id="export_button"> | ||
| 5560 | Export | ||
| 5561 | </option> | ||
| 5562 | <option id="delete_button"> | ||
| 5563 | Delete | ||
| 5564 | </option>--> | ||
| 5565 | </select> | ||
| 5566 | </label> | ||
| 5567 | </div> | ||
| 5563 | </div> | 5568 | </div> |
| 5564 | </div> | 5569 | <div id="tags_div"> |
| 5565 | <div id="tags_div"> | 5570 | <div class="tag_controls"> |
| 5566 | <div class="tag_controls"> | 5571 | <input id="tagInput" class="text_pole textarea_compact tag_input wide100p margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> |
| 5567 | <input id="tagInput" class="text_pole textarea_compact tag_input wide100p margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> | 5572 | <div class="tags_view menu_button fa-solid fa-tags" title="View all tags" data-i18n="[title]View all tags"></div> |
| 5568 | <div class="tags_view menu_button fa-solid fa-tags" title="View all tags" data-i18n="[title]View all tags"></div> | 5573 | </div> |
| 5574 | <div id="tagList" class="tags"></div> | ||
| 5569 | </div> | 5575 | </div> |
| 5570 | <div id="tagList" class="tags"></div> | ||
| 5571 | </div> | 5576 | </div> |
| 5572 | </div> | 5577 | </div> |
| 5573 | </div> | ||
| 5574 | <hr> | ||
| 5575 | <div id="spoiler_free_desc" class="flex-container flexFlowColumn flex1 flexNoGap"> | ||
| 5576 | <div id="creators_notes_div" class="title_restorable flexGap5"> | ||
| 5577 | <span class="flex1" data-i18n="Creator's Notes">Creator's Notes</span> | ||
| 5578 | <small id="creators_note_desc_hidden" data-i18n="Character details are hidden.">Character details are hidden.</small> | ||
| 5579 | <div id="creators_note_styles_button" class="margin0 menu_button fa-solid fa-palette fa-fw" title="Allow / Forbid the use of global styles for this character." data-i18n="[title]Allow / Forbid the use of global styles for this character."></div> | ||
| 5580 | <div id="spoiler_free_desc_button" class="margin0 menu_button fa-solid fa-eye fa-fw" title="Show / Hide Description and First Message" data-i18n="[title]Show / Hide Description and First Message"></div> | ||
| 5581 | </div> | ||
| 5582 | <div id="creator_notes_spoiler" class="flex1"></div> | ||
| 5583 | <!-- A button to show / hide description_div and description_textarea and first_message_div and firstmessage_textarea--> | ||
| 5584 | </div> | ||
| 5585 | <div id="descriptionWrapper" class="flex-container flexFlowColumn flex1"> | ||
| 5586 | <hr> | 5578 | <hr> |
| 5587 | <div id="description_div" class="title_restorable"> | 5579 | <div id="spoiler_free_desc" class="flex-container flexFlowColumn flex1 flexNoGap"> |
| 5588 | <div class="flex-container alignitemscenter"> | 5580 | <div id="creators_notes_div" class="title_restorable flexGap5"> |
| 5589 | <span data-i18n="Character Description" class="mdhotkey_location">Description</span> | 5581 | <span class="flex1" data-i18n="Creator's Notes">Creator's Notes</span> |
| 5590 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="description_textarea" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | 5582 | <small id="creators_note_desc_hidden" data-i18n="Character details are hidden.">Character details are hidden.</small> |
| 5591 | <a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#character-description" class="notes-link" target="_blank"> | 5583 | <div id="creators_note_styles_button" class="margin0 menu_button fa-solid fa-palette fa-fw" title="Allow / Forbid the use of global styles for this character." data-i18n="[title]Allow / Forbid the use of global styles for this character."></div> |
| 5592 | <span class="fa-solid fa-circle-question note-link-span"></span> | 5584 | <div id="spoiler_free_desc_button" class="margin0 menu_button fa-solid fa-eye fa-fw" title="Show / Hide Description and First Message" data-i18n="[title]Show / Hide Description and First Message"></div> |
| 5593 | </a> | ||
| 5594 | </div> | 5585 | </div> |
| 5595 | <div id="character_open_media_overrides" class="menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this character." data-i18n="[title]Click to allow/forbid the use of external media for this character."> | 5586 | <div id="creator_notes_spoiler" class="flex1"></div> |
| 5596 | <i id="character_media_allowed_icon" class="fa-solid fa-fw fa-link"></i> | 5587 | <!-- A button to show / hide description_div and description_textarea and first_message_div and firstmessage_textarea--> |
| 5597 | <i id="character_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i> | ||
| 5598 | <span data-i18n="Ext. Media"> | ||
| 5599 | Ext. Media | ||
| 5600 | </span> | ||
| 5601 | </div> | ||
| 5602 | </div> | ||
| 5603 | <textarea id="description_textarea" class="mdHotkeys" data-i18n="[placeholder]Describe your character's physical and mental traits here." placeholder="Describe your character's physical and mental traits here." name="description" placeholder=""></textarea> | ||
| 5604 | <div class="extension_token_counter"> | ||
| 5605 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="description_textarea" data-token-permanent="true">counting...</span> | ||
| 5606 | </div> | 5588 | </div> |
| 5607 | </div> | 5589 | <div id="descriptionWrapper" class="flex-container flexFlowColumn flex1"> |
| 5608 | <div id="firstMessageWrapper" class="flex-container flexFlowColumn flex1"> | 5590 | <hr> |
| 5609 | <div id="first_message_div" class="title_restorable"> | 5591 | <div id="description_div" class="title_restorable"> |
| 5610 | <div class="flex-container alignitemscenter flex1"> | 5592 | <div class="flex-container alignitemscenter"> |
| 5611 | <span data-i18n="First message" class="mdhotkey_location">First message</span> | 5593 | <span data-i18n="Character Description" class="mdhotkey_location">Description</span> |
| 5612 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="firstmessage_textarea" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | 5594 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="description_textarea" title="Expand the editor" data-i18n="[title]Expand the editor"></i> |
| 5613 | <a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#first-message" class="notes-link" target="_blank"> | 5595 | <a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#character-description" class="notes-link" target="_blank"> |
| 5614 | <span class="fa-solid fa-circle-question note-link-span"></span> | 5596 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 5615 | </a> | 5597 | </a> |
| 5598 | </div> | ||
| 5599 | <div id="character_open_media_overrides" class="menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this character." data-i18n="[title]Click to allow/forbid the use of external media for this character."> | ||
| 5600 | <i id="character_media_allowed_icon" class="fa-solid fa-fw fa-link"></i> | ||
| 5601 | <i id="character_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i> | ||
| 5602 | <span data-i18n="Ext. Media"> | ||
| 5603 | Ext. Media | ||
| 5604 | </span> | ||
| 5605 | </div> | ||
| 5616 | </div> | 5606 | </div> |
| 5617 | <div class="menu_button menu_button_icon open_alternate_greetings margin0" title="Click to set additional greeting messages" data-i18n="[title]Click to set additional greeting messages"> | 5607 | <textarea id="description_textarea" class="mdHotkeys" data-i18n="[placeholder]Describe your character's physical and mental traits here." placeholder="Describe your character's physical and mental traits here." name="description" placeholder=""></textarea> |
| 5618 | <span data-i18n="Alt. Greetings"> | 5608 | <div class="extension_token_counter"> |
| 5619 | Alt. Greetings | 5609 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="description_textarea" data-token-permanent="true">counting...</span> |
| 5620 | </span> | ||
| 5621 | </div> | 5610 | </div> |
| 5622 | </div> | 5611 | </div> |
| 5623 | <textarea class="mdHotkeys" id="firstmessage_textarea" data-i18n="[placeholder]This will be the first message from the character that starts every chat." placeholder="This will be the first message from the character that starts every chat." name="first_mes" placeholder=""></textarea> | 5612 | <div id="firstMessageWrapper" class="flex-container flexFlowColumn flex1"> |
| 5624 | <div class="extension_token_counter"> | 5613 | <div id="first_message_div" class="title_restorable"> |
| 5625 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="firstmessage_textarea">counting...</span> | 5614 | <div class="flex-container alignitemscenter flex1"> |
| 5626 | </div> | 5615 | <span data-i18n="First message" class="mdhotkey_location">First message</span> |
| 5627 | </div> | 5616 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="firstmessage_textarea" title="Expand the editor" data-i18n="[title]Expand the editor"></i> |
| 5628 | <!-- these divs are invisible and used for server communication purposes --> | 5617 | <a href="https://docs.sillytavern.app/usage/core-concepts/characterdesign/#first-message" class="notes-link" target="_blank"> |
| 5629 | <div id="hidden-divs"> | 5618 | <span class="fa-solid fa-circle-question note-link-span"></span> |
| 5630 | <input id="character_json_data" name="json_data" type="hidden"> | 5619 | </a> |
| 5631 | <input id="avatar_url_pole" name="avatar_url" type="hidden"> | 5620 | </div> |
| 5632 | <input id="selected_chat_pole" name="chat" type="hidden"> | 5621 | <div class="menu_button menu_button_icon open_alternate_greetings margin0" title="Click to set additional greeting messages" data-i18n="[title]Click to set additional greeting messages"> |
| 5633 | <input id="create_date_pole" name="create_date" type="hidden"> | 5622 | <span data-i18n="Alt. Greetings"> |
| 5634 | <input id="last_mes_pole" name="last_mes" type="hidden"> | 5623 | Alt. Greetings |
| 5635 | <input id="character_world" name="world" type="hidden"> | 5624 | </span> |
| 5636 | </div> | ||
| 5637 | <!-- now back to normal divs for display purposes--> | ||
| 5638 | </form> | ||
| 5639 | </div> | ||
| 5640 | <div name="Group Chat Edit Panel" id="rm_group_chats_block" class="right_menu flex-container flexNoGap"> | ||
| 5641 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 5642 | <div id="groupControlsToggle" class="inline-drawer-toggle inline-drawer-header"> | ||
| 5643 | <span> | ||
| 5644 | <span data-i18n="Group Controls">Group Controls</span> | ||
| 5645 | <a href="https://docs.sillytavern.app/usage/core-concepts/groupchats/" class="notes-link" target="_blank"> | ||
| 5646 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 5647 | </a> | ||
| 5648 | </span> | ||
| 5649 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 5650 | </div> | ||
| 5651 | <div class="inline-drawer-content"> | ||
| 5652 | <div id="group-metadata-controls" class="marginTopBot5"> | ||
| 5653 | <div class="flex-container wide100p"> | ||
| 5654 | <input id="rm_group_chat_name" class="text_pole flex1" type="text" name="chat_name" data-i18n="[placeholder]Chat Name (Optional)" placeholder="Chat Name (Optional)" /> | ||
| 5655 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore" data-i18n="[title]Chat Lore"></div> | ||
| 5656 | </div> | ||
| 5657 | <div id="group_tags_div" class="wide100p"> | ||
| 5658 | <div class="tag_controls"> | ||
| 5659 | <input id="groupTagInput" class="text_pole textarea_compact tag_input flex1 margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> | ||
| 5660 | <div class="tags_view menu_button fa-solid fa-tags margin0" title="View all tags" data-i18n="[title]View all tags"></div> | ||
| 5661 | </div> | 5625 | </div> |
| 5662 | <div id="groupTagList" class="tags paddingTopBot5"></div> | ||
| 5663 | </div> | 5626 | </div> |
| 5664 | <div id="rm_group_top_bar" class="flex-container alignitemscenter spaceBetween width100p fontsize80p"> | 5627 | <textarea class="mdHotkeys" id="firstmessage_textarea" data-i18n="[placeholder]This will be the first message from the character that starts every chat." placeholder="This will be the first message from the character that starts every chat." name="first_mes" placeholder=""></textarea> |
| 5665 | <div> | 5628 | <div class="extension_token_counter"> |
| 5666 | <label class="add_avatar avatar flex-container justifyCenter" for="group_avatar_button" title="Click to select a new avatar for this group" data-i18n="[title]Click to select a new avatar for this group"> | 5629 | <span data-i18n="extension_token_counter">Tokens:</span> <span data-token-counter="firstmessage_textarea">counting...</span> |
| 5667 | <div id="group_avatar_preview"> | 5630 | </div> |
| 5668 | <div class="avatar"> | 5631 | </div> |
| 5669 | <img src="img/ai4.png" alt="avatar"> | 5632 | <!-- these divs are invisible and used for server communication purposes --> |
| 5670 | </div> | 5633 | <div id="hidden-divs"> |
| 5671 | </div> | 5634 | <input id="character_json_data" name="json_data" type="hidden"> |
| 5672 | <input hidden type="file" id="group_avatar_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp"> | 5635 | <input id="avatar_url_pole" name="avatar_url" type="hidden"> |
| 5673 | </label> | 5636 | <input id="selected_chat_pole" name="chat" type="hidden"> |
| 5637 | <input id="create_date_pole" name="create_date" type="hidden"> | ||
| 5638 | <input id="last_mes_pole" name="last_mes" type="hidden"> | ||
| 5639 | <input id="character_world" name="world" type="hidden"> | ||
| 5640 | </div> | ||
| 5641 | <!-- now back to normal divs for display purposes--> | ||
| 5642 | </form> | ||
| 5643 | </div> | ||
| 5644 | <div name="Group Chat Edit Panel" id="rm_group_chats_block" class="right_menu flex-container flexNoGap"> | ||
| 5645 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 5646 | <div id="groupControlsToggle" class="inline-drawer-toggle inline-drawer-header"> | ||
| 5647 | <span> | ||
| 5648 | <span data-i18n="Group Controls">Group Controls</span> | ||
| 5649 | <a href="https://docs.sillytavern.app/usage/core-concepts/groupchats/" class="notes-link" target="_blank"> | ||
| 5650 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 5651 | </a> | ||
| 5652 | </span> | ||
| 5653 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 5654 | </div> | ||
| 5655 | <div class="inline-drawer-content"> | ||
| 5656 | <div id="group-metadata-controls" class="marginTopBot5"> | ||
| 5657 | <div class="flex-container wide100p"> | ||
| 5658 | <input id="rm_group_chat_name" class="text_pole flex1" type="text" name="chat_name" data-i18n="[placeholder]Chat Name (Optional)" placeholder="Chat Name (Optional)" /> | ||
| 5659 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore" data-i18n="[title]Chat Lore"></div> | ||
| 5674 | </div> | 5660 | </div> |
| 5675 | <div name="GroupStragegyAndOrder" id="rm_group_buttons" class="flex-container paddingLeftRight5 flex2"> | 5661 | <div id="group_tags_div" class="wide100p"> |
| 5676 | <div class="flex1 flexGap5"> | 5662 | <div class="tag_controls"> |
| 5677 | <label for="rm_group_activation_strategy" class="flexnowrap width100p whitespacenowrap"> | 5663 | <input id="groupTagInput" class="text_pole textarea_compact tag_input flex1 margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> |
| 5678 | <span data-i18n="Group reply strategy">Group reply strategy</span> | 5664 | <div class="tags_view menu_button fa-solid fa-tags margin0" title="View all tags" data-i18n="[title]View all tags"></div> |
| 5679 | </label> | ||
| 5680 | <select id="rm_group_activation_strategy"> | ||
| 5681 | <option value="2" data-i18n="Manual">Manual</option> | ||
| 5682 | <option value="0" data-i18n="Natural order">Natural order</option> | ||
| 5683 | <option value="1" data-i18n="List order">List order</option> | ||
| 5684 | <option value="3" data-i18n="Pooled order">Pooled order</option> | ||
| 5685 | </select> | ||
| 5686 | </div> | ||
| 5687 | <div class="flex1 flexGap5"> | ||
| 5688 | <label for="rm_group_generation_mode" class="flexnowrap width100p whitespacenowrap"> | ||
| 5689 | <span data-i18n="Group generation handling mode">Group generation handling mode</span> | ||
| 5690 | </label> | ||
| 5691 | <select id="rm_group_generation_mode"> | ||
| 5692 | <option value="0" data-i18n="Swap character cards">Swap character cards</option> | ||
| 5693 | <option value="1" data-i18n="Join character cards (exclude muted)">Join character cards (exclude muted)</option> | ||
| 5694 | <option value="2" data-i18n="Join character cards (include muted)">Join character cards (include muted)</option> | ||
| 5695 | </select> | ||
| 5696 | </div> | ||
| 5697 | <div class="flex1 flexGap5" title="Inserted before each part of the joined fields." data-i18n="[title]Inserted before each part of the joined fields."> | ||
| 5698 | <label for="rm_group_generation_mode_join_prefix" class="flexnowrap width100p whitespacenowrap"> | ||
| 5699 | <span data-i18n="Join Prefix">Join Prefix</span> | ||
| 5700 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]When 'Join character cards' is selected, all respective fields of the characters are being joined together.This means that in the story string for example all character descriptions will be joined to one big text.If you want those fields to be separated, you can define a prefix or suffix here.This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)" title="When 'Join character cards' is selected, all respective fields of the characters are being joined together. This means that in the story string for example all character descriptions will be joined to one big text. If you want those fields to be separated, you can define a prefix or suffix here. This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)"> | ||
| 5701 | </div> | ||
| 5702 | </label> | ||
| 5703 | <textarea id="rm_group_generation_mode_join_prefix" class="text_pole wide100p textarea_compact autoSetHeight" placeholder="—" rows="1"></textarea> | ||
| 5704 | </div> | 5665 | </div> |
| 5705 | <div class="flex1 flexGap5" title="Inserted after each part of the joined fields." data-i18n="[title]Inserted after each part of the joined fields."> | 5666 | <div id="groupTagList" class="tags paddingTopBot5"></div> |
| 5706 | <label for="rm_group_generation_mode_join_suffix" class="flexnowrap width100p whitespacenowrap"> | 5667 | </div> |
| 5707 | <span data-i18n="Join Suffix">Join Suffix</span> | 5668 | <div id="rm_group_top_bar" class="flex-container alignitemscenter spaceBetween width100p fontsize80p"> |
| 5708 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]When 'Join character cards' is selected, all respective fields of the characters are being joined together.This means that in the story string for example all character descriptions will be joined to one big text.If you want those fields to be separated, you can define a prefix or suffix here.This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)" title="When 'Join character cards' is selected, all respective fields of the characters are being joined together. This means that in the story string for example all character descriptions will be joined to one big text. If you want those fields to be separated, you can define a prefix or suffix here. This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)"> | 5669 | <div> |
| 5670 | <label class="add_avatar avatar flex-container justifyCenter" for="group_avatar_button" title="Click to select a new avatar for this group" data-i18n="[title]Click to select a new avatar for this group"> | ||
| 5671 | <div id="group_avatar_preview"> | ||
| 5672 | <div class="avatar"> | ||
| 5673 | <img src="img/ai4.png" alt="avatar"> | ||
| 5674 | </div> | ||
| 5709 | </div> | 5675 | </div> |
| 5676 | <input hidden type="file" id="group_avatar_button" name="avatar" accept="image/png, image/jpeg, image/jpg, image/gif, image/bmp"> | ||
| 5710 | </label> | 5677 | </label> |
| 5711 | <textarea id="rm_group_generation_mode_join_suffix" class="text_pole wide100p textarea_compact autoSetHeight" placeholder="—" rows="1"></textarea> | ||
| 5712 | </div> | 5678 | </div> |
| 5713 | </div> | 5679 | <div name="GroupStragegyAndOrder" id="rm_group_buttons" class="flex-container paddingLeftRight5 flex2"> |
| 5714 | <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1"> | 5680 | <div class="flex1 flexGap5"> |
| 5715 | <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-left-long"></div> | 5681 | <label for="rm_group_activation_strategy" class="flexnowrap width100p whitespacenowrap"> |
| 5716 | <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-scroll" title="Set a group chat scenario" data-i18n="[title]Set a group chat scenario"></div> | 5682 | <span data-i18n="Group reply strategy">Group reply strategy</span> |
| 5717 | <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> | 5683 | </label> |
| 5718 | <input id="rm_group_fav" type="hidden" /> | 5684 | <select id="rm_group_activation_strategy"> |
| 5719 | <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group."> | 5685 | <option value="2" data-i18n="Manual">Manual</option> |
| 5720 | <i id="group_media_allowed_icon" class="fa-solid fa-fw fa-link"></i> | 5686 | <option value="0" data-i18n="Natural order">Natural order</option> |
| 5721 | <i id="group_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i> | 5687 | <option value="1" data-i18n="List order">List order</option> |
| 5688 | <option value="3" data-i18n="Pooled order">Pooled order</option> | ||
| 5689 | </select> | ||
| 5690 | </div> | ||
| 5691 | <div class="flex1 flexGap5"> | ||
| 5692 | <label for="rm_group_generation_mode" class="flexnowrap width100p whitespacenowrap"> | ||
| 5693 | <span data-i18n="Group generation handling mode">Group generation handling mode</span> | ||
| 5694 | </label> | ||
| 5695 | <select id="rm_group_generation_mode"> | ||
| 5696 | <option value="0" data-i18n="Swap character cards">Swap character cards</option> | ||
| 5697 | <option value="1" data-i18n="Join character cards (exclude muted)">Join character cards (exclude muted)</option> | ||
| 5698 | <option value="2" data-i18n="Join character cards (include muted)">Join character cards (include muted)</option> | ||
| 5699 | </select> | ||
| 5700 | </div> | ||
| 5701 | <div class="flex1 flexGap5" title="Inserted before each part of the joined fields." data-i18n="[title]Inserted before each part of the joined fields."> | ||
| 5702 | <label for="rm_group_generation_mode_join_prefix" class="flexnowrap width100p whitespacenowrap"> | ||
| 5703 | <span data-i18n="Join Prefix">Join Prefix</span> | ||
| 5704 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]When 'Join character cards' is selected, all respective fields of the characters are being joined together.This means that in the story string for example all character descriptions will be joined to one big text.If you want those fields to be separated, you can define a prefix or suffix here.This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)" title="When 'Join character cards' is selected, all respective fields of the characters are being joined together. This means that in the story string for example all character descriptions will be joined to one big text. If you want those fields to be separated, you can define a prefix or suffix here. This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)"> | ||
| 5705 | </div> | ||
| 5706 | </label> | ||
| 5707 | <textarea id="rm_group_generation_mode_join_prefix" class="text_pole wide100p textarea_compact autoSetHeight" placeholder="—" rows="1"></textarea> | ||
| 5708 | </div> | ||
| 5709 | <div class="flex1 flexGap5" title="Inserted after each part of the joined fields." data-i18n="[title]Inserted after each part of the joined fields."> | ||
| 5710 | <label for="rm_group_generation_mode_join_suffix" class="flexnowrap width100p whitespacenowrap"> | ||
| 5711 | <span data-i18n="Join Suffix">Join Suffix</span> | ||
| 5712 | <div class="fa-solid fa-circle-info opacity50p" data-i18n="[title]When 'Join character cards' is selected, all respective fields of the characters are being joined together.This means that in the story string for example all character descriptions will be joined to one big text.If you want those fields to be separated, you can define a prefix or suffix here.This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)" title="When 'Join character cards' is selected, all respective fields of the characters are being joined together. This means that in the story string for example all character descriptions will be joined to one big text. If you want those fields to be separated, you can define a prefix or suffix here. This value supports normal macros and will also replace {{char}} with the relevant char's name and <FIELDNAME> with the name of the part (e.g.: description, personality, scenario, etc.)"> | ||
| 5713 | </div> | ||
| 5714 | </label> | ||
| 5715 | <textarea id="rm_group_generation_mode_join_suffix" class="text_pole wide100p textarea_compact autoSetHeight" placeholder="—" rows="1"></textarea> | ||
| 5716 | </div> | ||
| 5722 | </div> | 5717 | </div> |
| 5723 | <div id="rm_group_submit" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-check" title="Create" data-i18n="[title]Create"></div> | 5718 | <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1"> |
| 5724 | <div id="rm_group_restore_avatar" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-images" title="Restore collage avatar" data-i18n="[title]Restore collage avatar"></div> | 5719 | <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-left-long"></div> |
| 5725 | <div id="rm_group_delete" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-trash-can" title="Delete" data-i18n="[title]Delete"></div> | 5720 | <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-scroll" title="Set a group chat scenario" data-i18n="[title]Set a group chat scenario"></div> |
| 5726 | <div class="flex1"> | 5721 | <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> |
| 5727 | <label class="checkbox_label whitespacenowrap"> | 5722 | <input id="rm_group_fav" type="hidden" /> |
| 5728 | <input id="rm_group_allow_self_responses" type="checkbox" /> | 5723 | <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group."> |
| 5729 | <span data-i18n="Allow self responses">Allow self responses</span> | 5724 | <i id="group_media_allowed_icon" class="fa-solid fa-fw fa-link"></i> |
| 5730 | </label> | 5725 | <i id="group_media_forbidden_icon" class="fa-solid fa-fw fa-link-slash"></i> |
| 5731 | <label id="rm_group_automode_label" class="checkbox_label whitespacenowrap"> | 5726 | </div> |
| 5732 | <input id="rm_group_automode" type="checkbox" /> | 5727 | <div id="rm_group_submit" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-check" title="Create" data-i18n="[title]Create"></div> |
| 5733 | <span data-i18n="Auto Mode">Auto Mode</span> | 5728 | <div id="rm_group_restore_avatar" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-images" title="Restore collage avatar" data-i18n="[title]Restore collage avatar"></div> |
| 5734 | <input id="rm_group_automode_delay" class="text_pole textarea_compact widthUnset" type="number" min="1" max="999" step="1" value="5" title="Auto Mode delay" data-i18n="[title]Auto Mode delay" /> | 5729 | <div id="rm_group_delete" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-trash-can" title="Delete" data-i18n="[title]Delete"></div> |
| 5735 | </label> | 5730 | <div class="flex1"> |
| 5736 | <label id="rm_group_hidemutedsprites_label" class="checkbox_label whitespacenowrap"> | 5731 | <label class="checkbox_label whitespacenowrap"> |
| 5737 | <input id="rm_group_hidemutedsprites" type="checkbox" /> | 5732 | <input id="rm_group_allow_self_responses" type="checkbox" /> |
| 5738 | <span data-i18n="Hide Muted Member Sprites">Hide Muted Member Sprites</span> | 5733 | <span data-i18n="Allow self responses">Allow self responses</span> |
| 5739 | </label> | 5734 | </label> |
| 5735 | <label id="rm_group_automode_label" class="checkbox_label whitespacenowrap"> | ||
| 5736 | <input id="rm_group_automode" type="checkbox" /> | ||
| 5737 | <span data-i18n="Auto Mode">Auto Mode</span> | ||
| 5738 | <input id="rm_group_automode_delay" class="text_pole textarea_compact widthUnset" type="number" min="1" max="999" step="1" value="5" title="Auto Mode delay" data-i18n="[title]Auto Mode delay" /> | ||
| 5739 | </label> | ||
| 5740 | <label id="rm_group_hidemutedsprites_label" class="checkbox_label whitespacenowrap"> | ||
| 5741 | <input id="rm_group_hidemutedsprites" type="checkbox" /> | ||
| 5742 | <span data-i18n="Hide Muted Member Sprites">Hide Muted Member Sprites</span> | ||
| 5743 | </label> | ||
| 5744 | </div> | ||
| 5740 | </div> | 5745 | </div> |
| 5741 | </div> | 5746 | </div> |
| 5742 | </div> | 5747 | </div> |
| 5743 | </div> | 5748 | </div> |
| 5744 | </div> | 5749 | </div> |
| 5745 | </div> | 5750 | <div class="inline-drawer wide100p flexFlowColumn"> |
| 5746 | <div class="inline-drawer wide100p flexFlowColumn"> | 5751 | <div id="groupCurrentMemberListToggle" class="inline-drawer-toggle inline-drawer-header"> |
| 5747 | <div id="groupCurrentMemberListToggle" class="inline-drawer-toggle inline-drawer-header"> | 5752 | <span data-i18n="Current Members">Current Members </span><i id="groupCurrentMemberPopoutButton" class="fa-solid fa-window-restore menu_button"></i> |
| 5748 | <span data-i18n="Current Members">Current Members </span><i id="groupCurrentMemberPopoutButton" class="fa-solid fa-window-restore menu_button"></i> | 5753 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> |
| 5749 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 5750 | </div> | ||
| 5751 | <div class="inline-drawer-content"> | ||
| 5752 | <div id="currentGroupMembers" name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1"> | ||
| 5753 | <div id="rm_group_members_pagination" class="rm_group_members_pagination group_pagination"></div> | ||
| 5754 | <div id="rm_group_members" class="rm_group_members overflowYAuto flex-container" group_empty_text="Group is empty." data-i18n="[group_empty_text]Group is empty."></div> | ||
| 5755 | </div> | 5754 | </div> |
| 5756 | </div> | 5755 | <div class="inline-drawer-content"> |
| 5757 | </div> | 5756 | <div id="currentGroupMembers" name="Current Group Members" class="flex-container flexFlowColumn overflowYAuto flex1"> |
| 5758 | <div class="inline-drawer wide100p flexFlowColumn"> | 5757 | <div id="rm_group_members_pagination" class="rm_group_members_pagination group_pagination"></div> |
| 5759 | <div id="groupAddMemberListToggle" class="inline-drawer-toggle inline-drawer-header"> | 5758 | <div id="rm_group_members" class="rm_group_members overflowYAuto flex-container" group_empty_text="Group is empty." data-i18n="[group_empty_text]Group is empty."></div> |
| 5760 | <span data-i18n="Add Members">Add Members</span> | ||
| 5761 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 5762 | </div> | ||
| 5763 | <div class="inline-drawer-content"> | ||
| 5764 | <div name="Unadded Char List" class="flex-container flexFlowColumn overflowYAuto flex1"> | ||
| 5765 | <div id="rm_group_add_members_header"> | ||
| 5766 | <input id="rm_group_filter" class="text_pole margin0" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." /> | ||
| 5767 | </div> | 5759 | </div> |
| 5768 | <div class="rm_tag_controls"> | 5760 | </div> |
| 5769 | <div class="tags rm_tag_filter"></div> | 5761 | </div> |
| 5762 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 5763 | <div id="groupAddMemberListToggle" class="inline-drawer-toggle inline-drawer-header"> | ||
| 5764 | <span data-i18n="Add Members">Add Members</span> | ||
| 5765 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 5766 | </div> | ||
| 5767 | <div class="inline-drawer-content"> | ||
| 5768 | <div name="Unadded Char List" class="flex-container flexFlowColumn overflowYAuto flex1"> | ||
| 5769 | <div id="rm_group_add_members_header"> | ||
| 5770 | <input id="rm_group_filter" class="text_pole margin0" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." /> | ||
| 5771 | </div> | ||
| 5772 | <div class="rm_tag_controls"> | ||
| 5773 | <div class="tags rm_tag_filter"></div> | ||
| 5774 | </div> | ||
| 5775 | <div id="rm_group_add_members_pagination" class="group_pagination"></div> | ||
| 5776 | <div id="rm_group_add_members" class="overflowYAuto flex-container" no_characters_text="No characters available" data-i18n="[no_characters_text]No characters available"></div> | ||
| 5770 | </div> | 5777 | </div> |
| 5771 | <div id="rm_group_add_members_pagination" class="group_pagination"></div> | ||
| 5772 | <div id="rm_group_add_members" class="overflowYAuto flex-container" no_characters_text="No characters available" data-i18n="[no_characters_text]No characters available"></div> | ||
| 5773 | </div> | 5778 | </div> |
| 5774 | </div> | 5779 | </div> |
| 5775 | </div> | 5780 | </div> |
| 5776 | </div> | 5781 | <div id="rm_character_import" class="right_menu" style="display: none;"> |
| 5777 | <div id="rm_character_import" class="right_menu" style="display: none;"> | 5782 | <form id="form_import" action="javascript:void(null);" method="post" enctype="multipart/form-data"> |
| 5778 | <form id="form_import" action="javascript:void(null);" method="post" enctype="multipart/form-data"> | 5783 | <input multiple type="file" id="character_import_file" accept=".json, image/png, .yaml, .yml, .charx" name="avatar"> |
| 5779 | <input multiple type="file" id="character_import_file" accept=".json, image/png, .yaml, .yml, .charx" name="avatar"> | 5784 | <input id="character_import_file_type" name="file_type" class="text_pole" value="" autocomplete="off"> |
| 5780 | <input id="character_import_file_type" name="file_type" class="text_pole" value="" autocomplete="off"> | ||
| 5781 | </form> | ||
| 5782 | <input type="file" id="character_replace_file" accept=".json, image/png, .yaml, .yml, .charx" name="replace_avatar" hidden> | ||
| 5783 | </div> | ||
| 5784 | <div name="Character List Panel" id="rm_characters_block" class="right_menu"> | ||
| 5785 | <div id="charListFixedTop"> | ||
| 5786 | <form id="form_character_search_form" action="javascript:void(null);"> | ||
| 5787 | <div id="rm_button_create" title="Create New Character" data-i18n="[title]Create New Character" class="menu_button fa-solid fa-user-plus "></div> | ||
| 5788 | <div id="character_import_button" title="Import Character from File" data-i18n="[title]Import Character from File" class="menu_button fa-solid fa-file-import faSmallFontSquareFix"></div> | ||
| 5789 | <div id="external_import_button" title="Import content from external URL" data-i18n="[title]Import content from external URL" class="menu_button fa-solid fa-cloud-arrow-down faSmallFontSquareFix"></div> | ||
| 5790 | <div id="rm_button_group_chats" title="Create New Chat Group" data-i18n="[title]Create New Chat Group" class="menu_button fa-solid fa-users-gear "></div> | ||
| 5791 | <input id="character_search_bar" class="text_pole width100p" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." /> | ||
| 5792 | <select id="character_sort_order" title="Characters sorting order" data-i18n="[title]Characters sorting order"> | ||
| 5793 | <option data-field="search" data-order="desc" data-i18n="Search" hidden>Search</option> | ||
| 5794 | <option data-field="name" data-order="asc" data-i18n="A-Z">A-Z</option> | ||
| 5795 | <option data-field="name" data-order="desc" data-i18n="Z-A">Z-A</option> | ||
| 5796 | <option data-field="create_date" data-order="desc" data-i18n="Newest">Newest</option> | ||
| 5797 | <option data-field="create_date" data-order="asc" data-i18n="Oldest">Oldest</option> | ||
| 5798 | <option data-field="fav" data-order="desc" data-rule="boolean" data-i18n="Favorites">Favorites</option> | ||
| 5799 | <option data-field="date_last_chat" data-order="desc" data-i18n="Recent">Recent</option> | ||
| 5800 | <option data-field="chat_size" data-order="desc" data-i18n="Most chats">Most chats</option> | ||
| 5801 | <option data-field="chat_size" data-order="asc" data-i18n="Least chats">Least chats</option> | ||
| 5802 | <option data-field="data_size" data-order="desc" data-i18n="Most tokens">Most tokens</option> | ||
| 5803 | <option data-field="data_size" data-order="asc" data-i18n="Least tokens">Least tokens</option> | ||
| 5804 | <option data-field="name" data-order="random" data-i18n="Random">Random</option> | ||
| 5805 | </select> | ||
| 5806 | </form> | 5785 | </form> |
| 5807 | <div class="rm_tag_controls"> | 5786 | <input type="file" id="character_replace_file" accept=".json, image/png, .yaml, .yml, .charx" name="replace_avatar" hidden> |
| 5808 | <div class="tags rm_tag_filter"></div> | ||
| 5809 | <div class="tags rm_tag_bogus_drilldown"></div> | ||
| 5810 | </div> | ||
| 5811 | <hr> | ||
| 5812 | </div> | 5787 | </div> |
| 5788 | <div name="Character List Panel" id="rm_characters_block" class="right_menu"> | ||
| 5789 | <div id="charListFixedTop"> | ||
| 5790 | <form id="form_character_search_form" action="javascript:void(null);"> | ||
| 5791 | <div id="rm_button_create" title="Create New Character" data-i18n="[title]Create New Character" class="menu_button fa-solid fa-user-plus "></div> | ||
| 5792 | <div id="character_import_button" title="Import Character from File" data-i18n="[title]Import Character from File" class="menu_button fa-solid fa-file-import faSmallFontSquareFix"></div> | ||
| 5793 | <div id="external_import_button" title="Import content from external URL" data-i18n="[title]Import content from external URL" class="menu_button fa-solid fa-cloud-arrow-down faSmallFontSquareFix"></div> | ||
| 5794 | <div id="rm_button_group_chats" title="Create New Chat Group" data-i18n="[title]Create New Chat Group" class="menu_button fa-solid fa-users-gear "></div> | ||
| 5795 | <input id="character_search_bar" class="text_pole width100p" type="search" data-i18n="[placeholder]Search..." placeholder="Search..." /> | ||
| 5796 | <select id="character_sort_order" title="Characters sorting order" data-i18n="[title]Characters sorting order"> | ||
| 5797 | <option data-field="search" data-order="desc" data-i18n="Search" hidden>Search</option> | ||
| 5798 | <option data-field="name" data-order="asc" data-i18n="A-Z">A-Z</option> | ||
| 5799 | <option data-field="name" data-order="desc" data-i18n="Z-A">Z-A</option> | ||
| 5800 | <option data-field="create_date" data-order="desc" data-i18n="Newest">Newest</option> | ||
| 5801 | <option data-field="create_date" data-order="asc" data-i18n="Oldest">Oldest</option> | ||
| 5802 | <option data-field="fav" data-order="desc" data-rule="boolean" data-i18n="Favorites">Favorites</option> | ||
| 5803 | <option data-field="date_last_chat" data-order="desc" data-i18n="Recent">Recent</option> | ||
| 5804 | <option data-field="chat_size" data-order="desc" data-i18n="Most chats">Most chats</option> | ||
| 5805 | <option data-field="chat_size" data-order="asc" data-i18n="Least chats">Least chats</option> | ||
| 5806 | <option data-field="data_size" data-order="desc" data-i18n="Most tokens">Most tokens</option> | ||
| 5807 | <option data-field="data_size" data-order="asc" data-i18n="Least tokens">Least tokens</option> | ||
| 5808 | <option data-field="name" data-order="random" data-i18n="Random">Random</option> | ||
| 5809 | </select> | ||
| 5810 | </form> | ||
| 5811 | <div class="rm_tag_controls"> | ||
| 5812 | <div class="tags rm_tag_filter"></div> | ||
| 5813 | <div class="tags rm_tag_bogus_drilldown"></div> | ||
| 5814 | </div> | ||
| 5815 | <hr> | ||
| 5816 | </div> | ||
| 5813 | 5817 | ||
| 5814 | <div id="rm_print_characters_pagination"> | 5818 | <div id="rm_print_characters_pagination"> |
| 5815 | <i id="charListGridToggle" class="fa-solid fa-table-cells-large menu_button" title="Toggle character grid view" data-i18n="[title]Toggle character grid view"></i> | 5819 | <i id="charListGridToggle" class="fa-solid fa-table-cells-large menu_button" title="Toggle character grid view" data-i18n="[title]Toggle character grid view"></i> |
| 5816 | <i id="bulkEditButton" class="fa-solid fa-edit menu_button bulkEditButton" title="Bulk edit characters Click to toggle characters Shift + Click to select/deselect a range of characters Right-click for actions" data-i18n="[title]Bulk_edit_characters"></i> | 5820 | <i id="bulkEditButton" class="fa-solid fa-edit menu_button bulkEditButton" title="Bulk edit characters Click to toggle characters Shift + Click to select/deselect a range of characters Right-click for actions" data-i18n="[title]Bulk_edit_characters"></i> |
| 5817 | <div id="bulkSelectedCount" class="bulkEditOptionElement paginationjs-nav"></div> | 5821 | <div id="bulkSelectedCount" class="bulkEditOptionElement paginationjs-nav"></div> |
| 5818 | <i id="bulkSelectAllButton" class="fa-solid fa-check-double menu_button bulkEditOptionElement bulkSelectAllButton" title="Bulk select all characters" data-i18n="[title]Bulk select all characters" style="display: none;"></i> | 5822 | <i id="bulkSelectAllButton" class="fa-solid fa-check-double menu_button bulkEditOptionElement bulkSelectAllButton" title="Bulk select all characters" data-i18n="[title]Bulk select all characters" style="display: none;"></i> |
| 5819 | <i id="bulkDeleteButton" class="fa-solid fa-trash menu_button bulkEditOptionElement bulkDeleteButton" title="Bulk delete characters" data-i18n="[title]Bulk delete characters" style="display: none;"></i> | 5823 | <i id="bulkDeleteButton" class="fa-solid fa-trash menu_button bulkEditOptionElement bulkDeleteButton" title="Bulk delete characters" data-i18n="[title]Bulk delete characters" style="display: none;"></i> |
| 5824 | </div> | ||
| 5825 | <div id="rm_print_characters_block" class="flexFlowColumn"></div> | ||
| 5820 | </div> | 5826 | </div> |
| 5821 | <div id="rm_print_characters_block" class="flexFlowColumn"></div> | ||
| 5822 | </div> | 5827 | </div> |
| 5823 | </nav> | 5828 | </nav> |
| 5824 | </div> | 5829 | </div> |
| @@ -6195,6 +6200,298 @@ | |||
| 6195 | </div> | 6200 | </div> |
| 6196 | </div> | 6201 | </div> |
| 6197 | <div id="entry_edit_template" class="template_element"> | 6202 | <div id="entry_edit_template" class="template_element"> |
| 6203 | <div class="world_entry_edit"> | ||
| 6204 | <div class="flex-container wide100p alignitemscenter"> | ||
| 6205 | <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter"> | ||
| 6206 | <div class="world_entry_form_control keyprimary flex1"> | ||
| 6207 | <small class="displayNone"> | ||
| 6208 | <span data-i18n="Comma separated (required)"> | ||
| 6209 | Comma separated (required) | ||
| 6210 | </span> | ||
| 6211 | </small> | ||
| 6212 | <small class="textAlignCenter" data-i18n="Primary Keywords">Primary Keywords</small> | ||
| 6213 | <select class="keyprimaryselect keyselect select2_multi_sameline" name="key" data-i18n="[placeholder]Keywords or Regexes" placeholder="Keywords or Regexes" multiple="multiple"></select> | ||
| 6214 | <textarea class="text_pole keyprimarytextpole mobile" name="key" rows="1" data-i18n="[placeholder]Comma separated list" placeholder="Comma separated list" style="display: none;"></textarea> | ||
| 6215 | <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode"> | ||
| 6216 | ⌨️ | ||
| 6217 | </button> | ||
| 6218 | </div> | ||
| 6219 | <div class="world_entry_form_control"> | ||
| 6220 | <small class="textAlignCenter" data-i18n="Logic">Logic</small> | ||
| 6221 | <select name="entryLogicType" class="text_pole widthFitContent margin0"> | ||
| 6222 | <option value="0" data-i18n="AND ANY">AND ANY</option> | ||
| 6223 | <option value="3" data-i18n="AND ALL">AND ALL</option> | ||
| 6224 | <option value="1" data-i18n="NOT ALL">NOT ALL</option> | ||
| 6225 | <option value="2" data-i18n="NOT ANY">NOT ANY</option> | ||
| 6226 | </select> | ||
| 6227 | </div> | ||
| 6228 | <div class="world_entry_form_control keysecondary flex1"> | ||
| 6229 | <small class="displayNone"> | ||
| 6230 | <span data-i18n="(ignored if empty)"> | ||
| 6231 | (ignored if empty) | ||
| 6232 | </span> | ||
| 6233 | </small> | ||
| 6234 | <small class="textAlignCenter" data-i18n="Optional Filter">Optional Filter</small> | ||
| 6235 | <select class="keysecondaryselect keyselect select2_multi_sameline" name="keysecondary" data-i18n="[placeholder]Keywords or Regexes (ignored if empty)" placeholder="Keywords or Regexes (ignored if empty)" multiple="multiple"></select> | ||
| 6236 | <textarea class="text_pole keysecondarytextpole mobile" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated list (ignored if empty)" placeholder="Comma separated list (ignored if empty)" style="display: none;"></textarea> | ||
| 6237 | <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode"> | ||
| 6238 | ⌨️ | ||
| 6239 | </button> | ||
| 6240 | </div> | ||
| 6241 | </div> | ||
| 6242 | <div name="perEntryOverridesBlock" class="flex-container wide100p alignitemscenter"> | ||
| 6243 | <div class="world_entry_form_control flex1"> | ||
| 6244 | <small class="textAlignCenter" data-i18n="Scan Depth">Scan Depth</small> | ||
| 6245 | <input class="text_pole margin0" name="scanDepth" type="number" placeholder="Use global setting" data-i18n="[placeholder]Use global setting" max="1000"> | ||
| 6246 | </div> | ||
| 6247 | <div class="world_entry_form_control flex1"> | ||
| 6248 | <small class="textAlignCenter" data-i18n="Case-Sensitive">Case-Sensitive</small> | ||
| 6249 | <select name="caseSensitive" class="text_pole widthNatural margin0"> | ||
| 6250 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6251 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6252 | <option value="false" data-i18n="No">No</option> | ||
| 6253 | </select> | ||
| 6254 | </div> | ||
| 6255 | <div class="world_entry_form_control flex1"> | ||
| 6256 | <small class="textAlignCenter" data-i18n="Whole Words">Whole Words</small> | ||
| 6257 | <select name="matchWholeWords" class="text_pole widthNatural margin0"> | ||
| 6258 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6259 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6260 | <option value="false" data-i18n="No">No</option> | ||
| 6261 | </select> | ||
| 6262 | </div> | ||
| 6263 | <div class="world_entry_form_control flex1"> | ||
| 6264 | <small class="textAlignCenter" data-i18n="Group Scoring">Group Scoring</small> | ||
| 6265 | <select name="useGroupScoring" class="text_pole widthNatural margin0"> | ||
| 6266 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6267 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6268 | <option value="false" data-i18n="No">No</option> | ||
| 6269 | </select> | ||
| 6270 | </div> | ||
| 6271 | <div class="world_entry_form_control flex1" title="Can be used to automatically activate Quick Replies" data-i18n="[title]Can be used to automatically activate Quick Replies"> | ||
| 6272 | <small class="textAlignCenter" data-i18n="Automation ID">Automation ID</small> | ||
| 6273 | <input class="text_pole margin0" name="automationId" type="text" placeholder="( None )" data-i18n="[placeholder]( None )"> | ||
| 6274 | </div> | ||
| 6275 | <div class="world_entry_form_control flex1" title="Defines delay levels for recursive scans. Initially, only the first level (smallest number) will match. Once no matches are found, the next level becomes eligible for matching. This repeats until all levels are checked. Tied to the "Delay until recursion" setting." data-i18n="[title]delay_until_recursion_level"> | ||
| 6276 | <small class="textAlignCenter"> | ||
| 6277 | <span data-i18n="Recursion Level">Recursion Level</span> | ||
| 6278 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6279 | </small> | ||
| 6280 | <input class="text_pole margin0" name="delayUntilRecursionLevel" type="text" placeholder="1"> | ||
| 6281 | </div> | ||
| 6282 | </div> | ||
| 6283 | <div name="contentAndCharFilterBlock" class="world_entry_thin_controls flex2"> | ||
| 6284 | <div class="world_entry_form_control flex1"> | ||
| 6285 | <label for="content "> | ||
| 6286 | <small> | ||
| 6287 | <span class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween"> | ||
| 6288 | <span class="alignitemscenter flex-container"> | ||
| 6289 | <span data-i18n="Content" class="mdhotkey_location"> | ||
| 6290 | Content | ||
| 6291 | </span> | ||
| 6292 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 6293 | </span> | ||
| 6294 | <span> | ||
| 6295 | (<span data-i18n="extension_token_counter">Tokens:</span> <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>) | ||
| 6296 | <span class="world_entry_form_uid_value" data-first-run="true"></span> | ||
| 6297 | </span> | ||
| 6298 | <div> | ||
| 6299 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6300 | <input type="checkbox" name="excludeRecursion" /> | ||
| 6301 | <span data-i18n="Non-recursable (will not be activated by another)"> | ||
| 6302 | Non-recursable (will not be activated by another) | ||
| 6303 | </span> | ||
| 6304 | </label> | ||
| 6305 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6306 | <input type="checkbox" name="preventRecursion" /> | ||
| 6307 | <span data-i18n="Prevent further recursion (this entry will not activate others)"> | ||
| 6308 | Prevent further recursion (will not activate others) | ||
| 6309 | </span> | ||
| 6310 | </label> | ||
| 6311 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6312 | <input type="checkbox" name="delay_until_recursion" /> | ||
| 6313 | <span data-i18n="Delay until recursion (can only be activated on recursive checking)"> | ||
| 6314 | Delay until recursion (can only be activated on recursive checking) | ||
| 6315 | </span> | ||
| 6316 | </label> | ||
| 6317 | </div> | ||
| 6318 | </span> | ||
| 6319 | </small> | ||
| 6320 | <small class="displayNone"> | ||
| 6321 | <span data-i18n="What this keyword should mean to the AI, sent verbatim"> | ||
| 6322 | What this keyword should mean to the AI, sent verbatim | ||
| 6323 | </span> | ||
| 6324 | </small> | ||
| 6325 | </label> | ||
| 6326 | <textarea class="text_pole mdHotkeys" name="content" rows="8" data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim" placeholder="What this keyword should mean to the AI, sent verbatim"></textarea> | ||
| 6327 | </div> | ||
| 6328 | </div> | ||
| 6329 | <div class="world_entry_thin_controls commentContainer"> | ||
| 6330 | </div> | ||
| 6331 | </div> | ||
| 6332 | <div class="flex-container wide100p flexGap10"> | ||
| 6333 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> | ||
| 6334 | <div class="flex-container justifySpaceBetween"> | ||
| 6335 | <small for="group"> | ||
| 6336 | <span data-i18n="Inclusion Group">Inclusion Group</span> | ||
| 6337 | <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered. Supports multiple comma-separated groups. Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group"> | ||
| 6338 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 6339 | </a> | ||
| 6340 | </small> | ||
| 6341 | <label class="checkbox_label flexNoGap margin-r5" for="groupOverride"> | ||
| 6342 | <input type="checkbox" name="groupOverride" /> | ||
| 6343 | <span> | ||
| 6344 | <small title="Prioritize this entry: When checked, this entry is prioritized out of all selections. If multiple are prioritized, the one with the highest 'Order' is chosen. " data-i18n="[title]Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen."> | ||
| 6345 | <span data-i18n="Prioritize">Prioritize</span> | ||
| 6346 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6347 | </small> | ||
| 6348 | </span> | ||
| 6349 | </label> | ||
| 6350 | </div> | ||
| 6351 | <div class="range-block-range"> | ||
| 6352 | <input type="text" class="text_pole margin0" name="group" rows="1" data-i18n="[placeholder]Only one entry with the same label will be activated" placeholder="Only one entry with the same label will be activated"> | ||
| 6353 | </div> | ||
| 6354 | </div> | ||
| 6355 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]A relative likelihood of entry activation within the group" title="A relative likelihood of entry activation within the group"> | ||
| 6356 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6357 | <small for="groupWeight" data-i18n="Group Weight"> | ||
| 6358 | Group Weight | ||
| 6359 | </small> | ||
| 6360 | </div> | ||
| 6361 | <div class="range-block-range"> | ||
| 6362 | <input type="number" class="text_pole margin0" name="groupWeight" rows="1" placeholder="100" min="1" max="999999"> | ||
| 6363 | </div> | ||
| 6364 | </div> | ||
| 6365 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Sticky entries will stay active for N messages after being triggered." title="Sticky entries will stay active for N messages after being triggered."> | ||
| 6366 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6367 | <small class="flex-container alignItemsBaseline" for="sticky"> | ||
| 6368 | <span data-i18n="Sticky"> | ||
| 6369 | Sticky | ||
| 6370 | </span> | ||
| 6371 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6372 | </small> | ||
| 6373 | </div> | ||
| 6374 | <div class="range-block-range"> | ||
| 6375 | <input class="text_pole margin0" name="sticky" type="number" data-i18n="[placeholder]Non-sticky" placeholder="Non-sticky" min="0" max="999999"> | ||
| 6376 | </div> | ||
| 6377 | </div> | ||
| 6378 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a cooldown can't be activated N messages after being triggered." title="Entries with a cooldown can't be activated N messages after being triggered."> | ||
| 6379 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6380 | <small class="flex-container alignItemsBaseline" for="cooldown"> | ||
| 6381 | <span data-i18n="Cooldown"> | ||
| 6382 | Cooldown | ||
| 6383 | </span> | ||
| 6384 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6385 | </small> | ||
| 6386 | </div> | ||
| 6387 | <div class="range-block-range"> | ||
| 6388 | <input class="text_pole margin0" name="cooldown" type="number" data-i18n="[placeholder]No cooldown" placeholder="No cooldown" min="0" max="999999"> | ||
| 6389 | </div> | ||
| 6390 | </div> | ||
| 6391 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a delay can't be activated until there are N messages present in the chat." title="Entries with a delay can't be activated until there are N messages present in the chat."> | ||
| 6392 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6393 | <small class="flex-container alignItemsBaseline" for="delay"> | ||
| 6394 | <span data-i18n="Delay"> | ||
| 6395 | Delay | ||
| 6396 | </span> | ||
| 6397 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6398 | </small> | ||
| 6399 | </div> | ||
| 6400 | <div class="range-block-range"> | ||
| 6401 | <input class="text_pole margin0" name="delay" type="number" data-i18n="[placeholder]No delay" placeholder="No delay" min="0" max="999999"> | ||
| 6402 | </div> | ||
| 6403 | </div> | ||
| 6404 | </div> | ||
| 6405 | <div class="flex-container wide100p flexGap10"> | ||
| 6406 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> | ||
| 6407 | <div class="flex-container justifySpaceBetween"> | ||
| 6408 | <small for="characterFilter" data-i18n="Filter to Characters or Tags"> | ||
| 6409 | Filter to Characters or Tags | ||
| 6410 | </small> | ||
| 6411 | <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion"> | ||
| 6412 | <input type="checkbox" name="character_exclusion" /> | ||
| 6413 | <span> | ||
| 6414 | <small title="Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry" data-i18n="[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry"> | ||
| 6415 | <span data-i18n="Exclude">Exclude</span> | ||
| 6416 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6417 | </small> | ||
| 6418 | </span> | ||
| 6419 | </label> | ||
| 6420 | </div> | ||
| 6421 | <div class="range-block-range"> | ||
| 6422 | <select name="characterFilter" class="select2_multi_sameline" multiple> | ||
| 6423 | <option value="" data-i18n="-- Characters not found --"> | ||
| 6424 | -- Characters not found -- | ||
| 6425 | </option> | ||
| 6426 | </select> | ||
| 6427 | </div> | ||
| 6428 | </div> | ||
| 6429 | </div> | ||
| 6430 | <div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal"> | ||
| 6431 | <div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text"> | ||
| 6432 | <label class="checkbox flex-container"> | ||
| 6433 | <input type="checkbox" name="selective" /> | ||
| 6434 | <span data-i18n="Selective">Selective</span> | ||
| 6435 | </label> | ||
| 6436 | <label class="checkbox flex-container"> | ||
| 6437 | <input type="checkbox" name="useProbability" /> | ||
| 6438 | <span data-i18n="Use Probability">Use Probability</span> | ||
| 6439 | </label> | ||
| 6440 | <label class="checkbox flex-container"> | ||
| 6441 | <input type="checkbox" name="addMemo"> | ||
| 6442 | <span data-i18n="Add Memo">Add Memo</span> | ||
| 6443 | </label> | ||
| 6444 | </div> | ||
| 6445 | </div> | ||
| 6446 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 6447 | <div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable"> | ||
| 6448 | <strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong> | ||
| 6449 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 6450 | </div> | ||
| 6451 | <div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px"> | ||
| 6452 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6453 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6454 | <input type="checkbox" name="matchCharacterDescription" /> | ||
| 6455 | <span data-i18n="Character Description"> | ||
| 6456 | Character Description | ||
| 6457 | </span> | ||
| 6458 | </label> | ||
| 6459 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6460 | <input type="checkbox" name="matchCharacterPersonality" /> | ||
| 6461 | <span data-i18n="Character Personality"> | ||
| 6462 | Character Personality | ||
| 6463 | </span> | ||
| 6464 | </label> | ||
| 6465 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6466 | <input type="checkbox" name="matchScenario" /> | ||
| 6467 | <span data-i18n="Scenario"> | ||
| 6468 | Scenario | ||
| 6469 | </span> | ||
| 6470 | </label> | ||
| 6471 | </small> | ||
| 6472 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6473 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6474 | <input type="checkbox" name="matchPersonaDescription" /> | ||
| 6475 | <span data-i18n="Persona Description"> | ||
| 6476 | Persona Description | ||
| 6477 | </span> | ||
| 6478 | </label> | ||
| 6479 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6480 | <input type="checkbox" name="matchCharacterDepthPrompt" /> | ||
| 6481 | <span data-i18n="Character's Note"> | ||
| 6482 | Character's Note | ||
| 6483 | </span> | ||
| 6484 | </label> | ||
| 6485 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6486 | <input type="checkbox" name="matchCreatorNotes" /> | ||
| 6487 | <span data-i18n="Creator's Notes"> | ||
| 6488 | Creator's Notes | ||
| 6489 | </span> | ||
| 6490 | </label> | ||
| 6491 | </small> | ||
| 6492 | </div> | ||
| 6493 | </div> | ||
| 6494 | </div> | ||
| 6198 | <div class="world_entry"> | 6495 | <div class="world_entry"> |
| 6199 | <form class="world_entry_form wi-card-entry"> | 6496 | <form class="world_entry_form wi-card-entry"> |
| 6200 | <div class="inline-drawer wide100p"> | 6497 | <div class="inline-drawer wide100p"> |
| @@ -6267,297 +6564,8 @@ | |||
| 6267 | <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> | 6564 | <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> |
| 6268 | <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> | 6565 | <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> |
| 6269 | </div> | 6566 | </div> |
| 6270 | <div class="inline-drawer-content flex-container paddingBottom5px wide100p"> | 6567 | <div class="inline-drawer-content inline-drawer-outlet flex-container paddingBottom5px wide100p "> |
| 6271 | <div class="flex-container wide100p alignitemscenter"> | 6568 | <!-- Outlet for world_entry_edit --> |
| 6272 | <div name="keywordsAndLogicBlock" class="flex-container wide100p alignitemscenter"> | ||
| 6273 | <div class="world_entry_form_control keyprimary flex1"> | ||
| 6274 | <small class="displayNone"> | ||
| 6275 | <span data-i18n="Comma separated (required)"> | ||
| 6276 | Comma separated (required) | ||
| 6277 | </span> | ||
| 6278 | </small> | ||
| 6279 | <small class="textAlignCenter" data-i18n="Primary Keywords">Primary Keywords</small> | ||
| 6280 | <select class="keyprimaryselect keyselect select2_multi_sameline" name="key" data-i18n="[placeholder]Keywords or Regexes" placeholder="Keywords or Regexes" multiple="multiple"></select> | ||
| 6281 | <textarea class="text_pole keyprimarytextpole mobile" name="key" rows="1" data-i18n="[placeholder]Comma separated list" placeholder="Comma separated list" style="display: none;"></textarea> | ||
| 6282 | <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode"> | ||
| 6283 | ⌨️ | ||
| 6284 | </button> | ||
| 6285 | </div> | ||
| 6286 | <div class="world_entry_form_control"> | ||
| 6287 | <small class="textAlignCenter" data-i18n="Logic">Logic</small> | ||
| 6288 | <select name="entryLogicType" class="text_pole widthFitContent margin0"> | ||
| 6289 | <option value="0" data-i18n="AND ANY">AND ANY</option> | ||
| 6290 | <option value="3" data-i18n="AND ALL">AND ALL</option> | ||
| 6291 | <option value="1" data-i18n="NOT ALL">NOT ALL</option> | ||
| 6292 | <option value="2" data-i18n="NOT ANY">NOT ANY</option> | ||
| 6293 | </select> | ||
| 6294 | </div> | ||
| 6295 | <div class="world_entry_form_control keysecondary flex1"> | ||
| 6296 | <small class="displayNone"> | ||
| 6297 | <span data-i18n="(ignored if empty)"> | ||
| 6298 | (ignored if empty) | ||
| 6299 | </span> | ||
| 6300 | </small> | ||
| 6301 | <small class="textAlignCenter" data-i18n="Optional Filter">Optional Filter</small> | ||
| 6302 | <select class="keysecondaryselect keyselect select2_multi_sameline" name="keysecondary" data-i18n="[placeholder]Keywords or Regexes (ignored if empty)" placeholder="Keywords or Regexes (ignored if empty)" multiple="multiple"></select> | ||
| 6303 | <textarea class="text_pole keysecondarytextpole mobile" name="keysecondary" rows="1" data-i18n="[placeholder]Comma separated list (ignored if empty)" placeholder="Comma separated list (ignored if empty)" style="display: none;"></textarea> | ||
| 6304 | <button type="button" class="switch_input_type_icon" tabindex="-1" title="Switch to plaintext mode" data-i18n="[title]Switch to plaintext mode" data-icon-on="✨" data-icon-off="⌨️" data-tooltip-on="Switch to fancy mode" data-tooltip-off="Switch to plaintext mode"> | ||
| 6305 | ⌨️ | ||
| 6306 | </button> | ||
| 6307 | </div> | ||
| 6308 | </div> | ||
| 6309 | <div name="perEntryOverridesBlock" class="flex-container wide100p alignitemscenter"> | ||
| 6310 | <div class="world_entry_form_control flex1"> | ||
| 6311 | <small class="textAlignCenter" data-i18n="Scan Depth">Scan Depth</small> | ||
| 6312 | <input class="text_pole margin0" name="scanDepth" type="number" placeholder="Use global setting" data-i18n="[placeholder]Use global setting" max="1000"> | ||
| 6313 | </div> | ||
| 6314 | <div class="world_entry_form_control flex1"> | ||
| 6315 | <small class="textAlignCenter" data-i18n="Case-Sensitive">Case-Sensitive</small> | ||
| 6316 | <select name="caseSensitive" class="text_pole widthNatural margin0"> | ||
| 6317 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6318 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6319 | <option value="false" data-i18n="No">No</option> | ||
| 6320 | </select> | ||
| 6321 | </div> | ||
| 6322 | <div class="world_entry_form_control flex1"> | ||
| 6323 | <small class="textAlignCenter" data-i18n="Whole Words">Whole Words</small> | ||
| 6324 | <select name="matchWholeWords" class="text_pole widthNatural margin0"> | ||
| 6325 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6326 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6327 | <option value="false" data-i18n="No">No</option> | ||
| 6328 | </select> | ||
| 6329 | </div> | ||
| 6330 | <div class="world_entry_form_control flex1"> | ||
| 6331 | <small class="textAlignCenter" data-i18n="Group Scoring">Group Scoring</small> | ||
| 6332 | <select name="useGroupScoring" class="text_pole widthNatural margin0"> | ||
| 6333 | <option value="null" data-i18n="Use global">Use global</option> | ||
| 6334 | <option value="true" data-i18n="Yes">Yes</option> | ||
| 6335 | <option value="false" data-i18n="No">No</option> | ||
| 6336 | </select> | ||
| 6337 | </div> | ||
| 6338 | <div class="world_entry_form_control flex1" title="Can be used to automatically activate Quick Replies" data-i18n="[title]Can be used to automatically activate Quick Replies"> | ||
| 6339 | <small class="textAlignCenter" data-i18n="Automation ID">Automation ID</small> | ||
| 6340 | <input class="text_pole margin0" name="automationId" type="text" placeholder="( None )" data-i18n="[placeholder]( None )"> | ||
| 6341 | </div> | ||
| 6342 | <div class="world_entry_form_control flex1" title="Defines delay levels for recursive scans. Initially, only the first level (smallest number) will match. Once no matches are found, the next level becomes eligible for matching. This repeats until all levels are checked. Tied to the "Delay until recursion" setting." data-i18n="[title]delay_until_recursion_level"> | ||
| 6343 | <small class="textAlignCenter"> | ||
| 6344 | <span data-i18n="Recursion Level">Recursion Level</span> | ||
| 6345 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6346 | </small> | ||
| 6347 | <input class="text_pole margin0" name="delayUntilRecursionLevel" type="text" placeholder="1"> | ||
| 6348 | </div> | ||
| 6349 | </div> | ||
| 6350 | <div name="contentAndCharFilterBlock" class="world_entry_thin_controls flex2"> | ||
| 6351 | <div class="world_entry_form_control flex1"> | ||
| 6352 | <label for="content "> | ||
| 6353 | <small> | ||
| 6354 | <span class="alignitemscenter flex-container flexnowrap wide100p justifySpaceBetween"> | ||
| 6355 | <span class="alignitemscenter flex-container"> | ||
| 6356 | <span data-i18n="Content" class="mdhotkey_location"> | ||
| 6357 | Content | ||
| 6358 | </span> | ||
| 6359 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 6360 | </span> | ||
| 6361 | <span> | ||
| 6362 | (<span data-i18n="extension_token_counter">Tokens:</span> <span class="world_entry_form_token_counter" data-first-run="true">counting...</span>) | ||
| 6363 | <span class="world_entry_form_uid_value" data-first-run="true"></span> | ||
| 6364 | </span> | ||
| 6365 | <div> | ||
| 6366 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6367 | <input type="checkbox" name="exclude_recursion" /> | ||
| 6368 | <span data-i18n="Non-recursable (will not be activated by another)"> | ||
| 6369 | Non-recursable (will not be activated by another) | ||
| 6370 | </span> | ||
| 6371 | </label> | ||
| 6372 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6373 | <input type="checkbox" name="prevent_recursion" /> | ||
| 6374 | <span data-i18n="Prevent further recursion (this entry will not activate others)"> | ||
| 6375 | Prevent further recursion (will not activate others) | ||
| 6376 | </span> | ||
| 6377 | </label> | ||
| 6378 | <label class="checkbox flex-container alignitemscenter flexNoGap"> | ||
| 6379 | <input type="checkbox" name="delay_until_recursion" /> | ||
| 6380 | <span data-i18n="Delay until recursion (can only be activated on recursive checking)"> | ||
| 6381 | Delay until recursion (can only be activated on recursive checking) | ||
| 6382 | </span> | ||
| 6383 | </label> | ||
| 6384 | </div> | ||
| 6385 | </span> | ||
| 6386 | </small> | ||
| 6387 | <small class="displayNone"> | ||
| 6388 | <span data-i18n="What this keyword should mean to the AI, sent verbatim"> | ||
| 6389 | What this keyword should mean to the AI, sent verbatim | ||
| 6390 | </span> | ||
| 6391 | </small> | ||
| 6392 | </label> | ||
| 6393 | <textarea class="text_pole mdHotkeys" name="content" rows="8" data-i18n="[placeholder]What this keyword should mean to the AI, sent verbatim" placeholder="What this keyword should mean to the AI, sent verbatim"></textarea> | ||
| 6394 | </div> | ||
| 6395 | </div> | ||
| 6396 | <div class="world_entry_thin_controls commentContainer"> | ||
| 6397 | </div> | ||
| 6398 | </div> | ||
| 6399 | <div class="flex-container wide100p flexGap10"> | ||
| 6400 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> | ||
| 6401 | <div class="flex-container justifySpaceBetween"> | ||
| 6402 | <small for="group"> | ||
| 6403 | <span data-i18n="Inclusion Group">Inclusion Group</span> | ||
| 6404 | <a href="https://docs.sillytavern.app/usage/core-concepts/worldinfo/#inclusion-group" class="notes-link" target="_blank" title="Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered. Supports multiple comma-separated groups. Documentation: World Info - Inclusion Group" data-i18n="[title]Inclusion Groups ensure only one entry from a group is activated at a time, if multiple are triggered.Documentation: World Info - Inclusion Group"> | ||
| 6405 | <span class="fa-solid fa-circle-question note-link-span"></span> | ||
| 6406 | </a> | ||
| 6407 | </small> | ||
| 6408 | <label class="checkbox_label flexNoGap margin-r5" for="groupOverride"> | ||
| 6409 | <input type="checkbox" name="groupOverride" /> | ||
| 6410 | <span> | ||
| 6411 | <small title="Prioritize this entry: When checked, this entry is prioritized out of all selections. If multiple are prioritized, the one with the highest 'Order' is chosen. " data-i18n="[title]Prioritize this entry: When checked, this entry is prioritized out of all selections.If multiple are prioritized, the one with the highest 'Order' is chosen."> | ||
| 6412 | <span data-i18n="Prioritize">Prioritize</span> | ||
| 6413 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6414 | </small> | ||
| 6415 | </span> | ||
| 6416 | </label> | ||
| 6417 | </div> | ||
| 6418 | <div class="range-block-range"> | ||
| 6419 | <input type="text" class="text_pole margin0" name="group" rows="1" data-i18n="[placeholder]Only one entry with the same label will be activated" placeholder="Only one entry with the same label will be activated"> | ||
| 6420 | </div> | ||
| 6421 | </div> | ||
| 6422 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]A relative likelihood of entry activation within the group" title="A relative likelihood of entry activation within the group"> | ||
| 6423 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6424 | <small for="groupWeight" data-i18n="Group Weight"> | ||
| 6425 | Group Weight | ||
| 6426 | </small> | ||
| 6427 | </div> | ||
| 6428 | <div class="range-block-range"> | ||
| 6429 | <input type="number" class="text_pole margin0" name="groupWeight" rows="1" placeholder="100" min="1" max="999999"> | ||
| 6430 | </div> | ||
| 6431 | </div> | ||
| 6432 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Sticky entries will stay active for N messages after being triggered." title="Sticky entries will stay active for N messages after being triggered."> | ||
| 6433 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6434 | <small class="flex-container alignItemsBaseline" for="sticky"> | ||
| 6435 | <span data-i18n="Sticky"> | ||
| 6436 | Sticky | ||
| 6437 | </span> | ||
| 6438 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6439 | </small> | ||
| 6440 | </div> | ||
| 6441 | <div class="range-block-range"> | ||
| 6442 | <input class="text_pole margin0" name="sticky" type="number" data-i18n="[placeholder]Non-sticky" placeholder="Non-sticky" min="0" max="999999"> | ||
| 6443 | </div> | ||
| 6444 | </div> | ||
| 6445 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a cooldown can't be activated N messages after being triggered." title="Entries with a cooldown can't be activated N messages after being triggered."> | ||
| 6446 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6447 | <small class="flex-container alignItemsBaseline" for="cooldown"> | ||
| 6448 | <span data-i18n="Cooldown"> | ||
| 6449 | Cooldown | ||
| 6450 | </span> | ||
| 6451 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6452 | </small> | ||
| 6453 | </div> | ||
| 6454 | <div class="range-block-range"> | ||
| 6455 | <input class="text_pole margin0" name="cooldown" type="number" data-i18n="[placeholder]No cooldown" placeholder="No cooldown" min="0" max="999999"> | ||
| 6456 | </div> | ||
| 6457 | </div> | ||
| 6458 | <div class="flex2 flex-container flexFlowColumn flexNoGap" data-i18n="[title]Entries with a delay can't be activated until there are N messages present in the chat." title="Entries with a delay can't be activated until there are N messages present in the chat."> | ||
| 6459 | <div class="flex-container justifySpaceBetween marginBot5"> | ||
| 6460 | <small class="flex-container alignItemsBaseline" for="delay"> | ||
| 6461 | <span data-i18n="Delay"> | ||
| 6462 | Delay | ||
| 6463 | </span> | ||
| 6464 | <i class="fa-solid fa-comments fa-xs"></i> | ||
| 6465 | </small> | ||
| 6466 | </div> | ||
| 6467 | <div class="range-block-range"> | ||
| 6468 | <input class="text_pole margin0" name="delay" type="number" data-i18n="[placeholder]No delay" placeholder="No delay" min="0" max="999999"> | ||
| 6469 | </div> | ||
| 6470 | </div> | ||
| 6471 | </div> | ||
| 6472 | <div class="flex-container wide100p flexGap10"> | ||
| 6473 | <div class="flex4 flex-container flexFlowColumn flexNoGap"> | ||
| 6474 | <div class="flex-container justifySpaceBetween"> | ||
| 6475 | <small for="characterFilter" data-i18n="Filter to Characters or Tags"> | ||
| 6476 | Filter to Characters or Tags | ||
| 6477 | </small> | ||
| 6478 | <label class="checkbox_label flexNoGap margin-r5" for="character_exclusion"> | ||
| 6479 | <input type="checkbox" name="character_exclusion" /> | ||
| 6480 | <span> | ||
| 6481 | <small title="Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry" data-i18n="[title]Switch the Character/Tags filter around to exclude the listed characters and tags from matching for this entry"> | ||
| 6482 | <span data-i18n="Exclude">Exclude</span> | ||
| 6483 | <div class="fa-solid fa-circle-info opacity50p"></div> | ||
| 6484 | </small> | ||
| 6485 | </span> | ||
| 6486 | </label> | ||
| 6487 | </div> | ||
| 6488 | <div class="range-block-range"> | ||
| 6489 | <select name="characterFilter" class="select2_multi_sameline" multiple> | ||
| 6490 | <option value="" data-i18n="-- Characters not found --"> | ||
| 6491 | -- Characters not found -- | ||
| 6492 | </option> | ||
| 6493 | </select> | ||
| 6494 | </div> | ||
| 6495 | </div> | ||
| 6496 | </div> | ||
| 6497 | <div name="WIEntryBottomControls" class="flex-container flex1 justifySpaceBetween world_entry_form_horizontal"> | ||
| 6498 | <div class="flex-container flexFlowColumn flexNoGap wi-enter-footer-text "> | ||
| 6499 | <label class="checkbox flex-container"> | ||
| 6500 | <input type="checkbox" name="selective" /> | ||
| 6501 | <span data-i18n="Selective">Selective</span> | ||
| 6502 | </label> | ||
| 6503 | <label class="checkbox flex-container"> | ||
| 6504 | <input type="checkbox" name="useProbability" /> | ||
| 6505 | <span data-i18n="Use Probability">Use Probability</span> | ||
| 6506 | </label> | ||
| 6507 | <label class="checkbox flex-container"> | ||
| 6508 | <input type="checkbox" name="addMemo"> | ||
| 6509 | <span data-i18n="Add Memo">Add Memo</span> | ||
| 6510 | </label> | ||
| 6511 | </div> | ||
| 6512 | </div> | ||
| 6513 | <div class="inline-drawer wide100p flexFlowColumn"> | ||
| 6514 | <div class="inline-drawer-toggle inline-drawer-header inline-drawer-header-pointer userSettingsInnerExpandable"> | ||
| 6515 | <strong data-i18n="Additional Matching Sources">Additional Matching Sources</strong> | ||
| 6516 | <div class="fa-solid fa-circle-chevron-down inline-drawer-icon down"></div> | ||
| 6517 | </div> | ||
| 6518 | <div class="inline-drawer-content flex-container flexFlowRow flexGap10 paddingBottom5px"> | ||
| 6519 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6520 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6521 | <input type="checkbox" name="matchCharacterDescription" /> | ||
| 6522 | <span data-i18n="Character Description"> | ||
| 6523 | Character Description | ||
| 6524 | </span> | ||
| 6525 | </label> | ||
| 6526 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6527 | <input type="checkbox" name="matchCharacterPersonality" /> | ||
| 6528 | <span data-i18n="Character Personality"> | ||
| 6529 | Character Personality | ||
| 6530 | </span> | ||
| 6531 | </label> | ||
| 6532 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6533 | <input type="checkbox" name="matchScenario" /> | ||
| 6534 | <span data-i18n="Scenario"> | ||
| 6535 | Scenario | ||
| 6536 | </span> | ||
| 6537 | </label> | ||
| 6538 | </small> | ||
| 6539 | <small class="flex-container flex1 flexFlowColumn"> | ||
| 6540 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6541 | <input type="checkbox" name="matchPersonaDescription" /> | ||
| 6542 | <span data-i18n="Persona Description"> | ||
| 6543 | Persona Description | ||
| 6544 | </span> | ||
| 6545 | </label> | ||
| 6546 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6547 | <input type="checkbox" name="matchCharacterDepthPrompt" /> | ||
| 6548 | <span data-i18n="Character's Note"> | ||
| 6549 | Character's Note | ||
| 6550 | </span> | ||
| 6551 | </label> | ||
| 6552 | <label class="checkbox flex-container alignItemsCenter flexNoGap"> | ||
| 6553 | <input type="checkbox" name="matchCreatorNotes" /> | ||
| 6554 | <span data-i18n="Creator's Notes"> | ||
| 6555 | Creator's Notes | ||
| 6556 | </span> | ||
| 6557 | </label> | ||
| 6558 | </small> | ||
| 6559 | </div> | ||
| 6560 | </div> | ||
| 6561 | </div> | 6569 | </div> |
| 6562 | </div> | 6570 | </div> |
| 6563 | </form> | 6571 | </form> |
| @@ -10,7 +10,6 @@ import { | |||
| 10 | SVGInject, | 10 | SVGInject, |
| 11 | Popper, | 11 | Popper, |
| 12 | initLibraryShims, | 12 | initLibraryShims, |
| 13 | slideToggle, | ||
| 14 | default as libs, | 13 | default as libs, |
| 15 | } from './lib.js'; | 14 | } from './lib.js'; |
| 16 | 15 | ||
| @@ -10320,86 +10319,43 @@ function doDrawerOpenClick() { | |||
| 10320 | /** | 10319 | /** |
| 10321 | * Event handler to open or close a navbar drawer when a navbar icon is clicked. | 10320 | * Event handler to open or close a navbar drawer when a navbar icon is clicked. |
| 10322 | * Handles click events on .drawer-toggle elements. | 10321 | * Handles click events on .drawer-toggle elements. |
| 10323 | * @returns {void} | 10322 | * @returns {Promise<void>} |
| 10324 | */ | 10323 | */ |
| 10325 | function doNavbarIconClick() { | 10324 | export async function doNavbarIconClick() { |
| 10326 | const icon = $(this).find('.drawer-icon'); | 10325 | const icon = $(this).find('.drawer-icon'); |
| 10327 | const drawer = $(this).parent().find('.drawer-content'); | 10326 | const drawer = $(this).parent().find('.drawer-content'); |
| 10328 | if (drawer.hasClass('resizing')) { return; } | ||
| 10329 | const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer'); | 10327 | const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer'); |
| 10330 | const targetDrawerID = $(this).parent().find('.drawer-content').attr('id'); | 10328 | const targetDrawerID = $(this).parent().find('.drawer-content').attr('id'); |
| 10331 | const pinnedDrawerClicked = drawer.hasClass('pinnedOpen'); | 10329 | |
| 10332 | 10330 | if (!drawerWasOpenAlready) { | |
| 10333 | if (!drawerWasOpenAlready) { //to open the drawer | 10331 | const $openDrawers = $('.openDrawer:not(.pinnedOpen)'); |
| 10334 | $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => { | 10332 | const $openIcons = $('.openIcon:not(.drawerPinnedOpen)'); |
| 10335 | slideToggle(el, { | 10333 | for (const iconEl of $openIcons) { |
| 10336 | ...getSlideToggleOptions(), | 10334 | $(iconEl).toggleClass('closedIcon openIcon'); |
| 10337 | onAnimationEnd: function (el) { | 10335 | } |
| 10338 | el.closest('.drawer-content').classList.remove('resizing'); | 10336 | for (const el of $openDrawers) { |
| 10339 | }, | 10337 | $(el).toggleClass('closedDrawer openDrawer'); |
| 10340 | }); | 10338 | } |
| 10341 | }); | 10339 | if ($openDrawers.length) { |
| 10342 | $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon'); | 10340 | await delay(animation_duration); |
| 10343 | $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer'); | 10341 | } |
| 10344 | icon.toggleClass('openIcon closedIcon'); | 10342 | icon.toggleClass('openIcon closedIcon'); |
| 10345 | drawer.toggleClass('openDrawer closedDrawer'); | 10343 | drawer.toggleClass('openDrawer closedDrawer'); |
| 10346 | 10344 | ||
| 10347 | //console.log(targetDrawerID); | ||
| 10348 | if (targetDrawerID === 'right-nav-panel') { | 10345 | if (targetDrawerID === 'right-nav-panel') { |
| 10349 | $(this).closest('.drawer').find('.drawer-content').addClass('resizing').each((_, el) => { | 10346 | favsToHotswap(); |
| 10350 | slideToggle(el, { | 10347 | $('#rm_print_characters_block').trigger('scroll'); |
| 10351 | ...getSlideToggleOptions(), | ||
| 10352 | elementDisplayStyle: 'flex', | ||
| 10353 | onAnimationEnd: function (el) { | ||
| 10354 | el.closest('.drawer-content').classList.remove('resizing'); | ||
| 10355 | favsToHotswap(); | ||
| 10356 | $('#rm_print_characters_block').trigger('scroll'); | ||
| 10357 | }, | ||
| 10358 | }); | ||
| 10359 | }); | ||
| 10360 | } else { | ||
| 10361 | $(this).closest('.drawer').find('.drawer-content').addClass('resizing').each((_, el) => { | ||
| 10362 | slideToggle(el, { | ||
| 10363 | ...getSlideToggleOptions(), | ||
| 10364 | onAnimationEnd: function (el) { | ||
| 10365 | el.closest('.drawer-content').classList.remove('resizing'); | ||
| 10366 | }, | ||
| 10367 | }); | ||
| 10368 | }); | ||
| 10369 | } | 10348 | } |
| 10370 | 10349 | ||
| 10371 | // Set the height of "autoSetHeight" textareas within the drawer to their scroll height | 10350 | // Set the height of "autoSetHeight" textareas within the drawer to their scroll height |
| 10372 | if (!CSS.supports('field-sizing', 'content')) { | 10351 | if (!CSS.supports('field-sizing', 'content')) { |
| 10373 | $(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight').each(async function () { | 10352 | const textareas = $(this).closest('.drawer').find('.drawer-content textarea.autoSetHeight'); |
| 10374 | await resetScrollHeight($(this)); | 10353 | for (const textarea of textareas) { |
| 10375 | return; | 10354 | await resetScrollHeight($(textarea)); |
| 10376 | }); | 10355 | } |
| 10377 | } | 10356 | } |
| 10378 | 10357 | } else if (drawerWasOpenAlready) { | |
| 10379 | } else if (drawerWasOpenAlready) { //to close manually | ||
| 10380 | icon.toggleClass('closedIcon openIcon'); | 10358 | icon.toggleClass('closedIcon openIcon'); |
| 10381 | |||
| 10382 | if (pinnedDrawerClicked) { | ||
| 10383 | $(drawer).addClass('resizing').each((_, el) => { | ||
| 10384 | slideToggle(el, { | ||
| 10385 | ...getSlideToggleOptions(), | ||
| 10386 | onAnimationEnd: function (el) { | ||
| 10387 | el.classList.remove('resizing'); | ||
| 10388 | }, | ||
| 10389 | }); | ||
| 10390 | }); | ||
| 10391 | } | ||
| 10392 | else { | ||
| 10393 | $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => { | ||
| 10394 | slideToggle(el, { | ||
| 10395 | ...getSlideToggleOptions(), | ||
| 10396 | onAnimationEnd: function (el) { | ||
| 10397 | el.closest('.drawer-content').classList.remove('resizing'); | ||
| 10398 | }, | ||
| 10399 | }); | ||
| 10400 | }); | ||
| 10401 | } | ||
| 10402 | |||
| 10403 | drawer.toggleClass('closedDrawer openDrawer'); | 10359 | drawer.toggleClass('closedDrawer openDrawer'); |
| 10404 | } | 10360 | } |
| 10405 | } | 10361 | } |
| @@ -12028,8 +11984,8 @@ jQuery(async function () { | |||
| 12028 | 11984 | ||
| 12029 | $('.drawer-toggle').on('click', doNavbarIconClick); | 11985 | $('.drawer-toggle').on('click', doNavbarIconClick); |
| 12030 | 11986 | ||
| 12031 | $('html').on('touchstart mousedown', function (e) { | 11987 | $('html').on('touchstart mousedown', async function (e) { |
| 12032 | var clickTarget = $(e.target); | 11988 | const clickTarget = $(e.target); |
| 12033 | 11989 | ||
| 12034 | if (isExportPopupOpen | 11990 | if (isExportPopupOpen |
| 12035 | && clickTarget.closest('#export_button').length == 0 | 11991 | && clickTarget.closest('#export_button').length == 0 |
| @@ -12050,28 +12006,21 @@ jQuery(async function () { | |||
| 12050 | '#toast-container', | 12006 | '#toast-container', |
| 12051 | '.select2-results', | 12007 | '.select2-results', |
| 12052 | ]; | 12008 | ]; |
| 12009 | |||
| 12053 | for (const id of forbiddenTargets) { | 12010 | for (const id of forbiddenTargets) { |
| 12054 | if (clickTarget.closest(id).length > 0) { | 12011 | if (clickTarget.closest(id).length > 0) { |
| 12055 | return; | 12012 | return; |
| 12056 | } | 12013 | } |
| 12057 | } | 12014 | } |
| 12058 | 12015 | ||
| 12059 | var targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length; | 12016 | // This autocloses open drawers that are not pinned if a click happens inside the app which does not target them. |
| 12060 | if (clickTarget.hasClass('drawer-icon') == false && !clickTarget.hasClass('openDrawer')) { | 12017 | const targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length; |
| 12061 | if ($('.openDrawer').length !== 0) { | 12018 | if (!clickTarget.hasClass('drawer-icon') && !clickTarget.hasClass('openDrawer')) { |
| 12062 | if (targetParentHasOpenDrawer === 0) { | 12019 | const $openDrawers = $('.openDrawer').not('.pinnedOpen'); |
| 12063 | //console.log($('.openDrawer').not('.pinnedOpen').length); | 12020 | if ($openDrawers.length && targetParentHasOpenDrawer === 0) { |
| 12064 | $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => { | 12021 | // Toggle icon and drawer classes |
| 12065 | slideToggle(el, { | 12022 | $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon'); |
| 12066 | ...getSlideToggleOptions(), | 12023 | $openDrawers.toggleClass('closedDrawer openDrawer'); |
| 12067 | onAnimationEnd: (el) => { | ||
| 12068 | el.closest('.drawer-content').classList.remove('resizing'); | ||
| 12069 | }, | ||
| 12070 | }); | ||
| 12071 | }); | ||
| 12072 | $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon'); | ||
| 12073 | $('.openDrawer').not('.pinnedOpen').toggleClass('closedDrawer openDrawer'); | ||
| 12074 | } | ||
| 12075 | } | 12024 | } |
| 12076 | } | 12025 | } |
| 12077 | }); | 12026 | }); |
| @@ -12085,6 +12034,7 @@ jQuery(async function () { | |||
| 12085 | const drawerContent = drawer.find('>.inline-drawer-content'); | 12034 | const drawerContent = drawer.find('>.inline-drawer-content'); |
| 12086 | icon.toggleClass('down up'); | 12035 | icon.toggleClass('down up'); |
| 12087 | icon.toggleClass('fa-circle-chevron-down fa-circle-chevron-up'); | 12036 | icon.toggleClass('fa-circle-chevron-down fa-circle-chevron-up'); |
| 12037 | drawer.trigger('inline-drawer-toggle'); | ||
| 12088 | drawerContent.stop().slideToggle({ | 12038 | drawerContent.stop().slideToggle({ |
| 12089 | complete: () => { | 12039 | complete: () => { |
| 12090 | $(this).css('height', ''); | 12040 | $(this).css('height', ''); |
| @@ -12181,7 +12131,7 @@ jQuery(async function () { | |||
| 12181 | if (!(e.target instanceof HTMLElement)) return; | 12131 | if (!(e.target instanceof HTMLElement)) return; |
| 12182 | if (e.target.matches('#OpenAllWIEntries')) { | 12132 | if (e.target.matches('#OpenAllWIEntries')) { |
| 12183 | document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => { | 12133 | document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => { |
| 12184 | toggleDrawer(drawer, true); | 12134 | delay(0).then(() => toggleDrawer(drawer, true)); |
| 12185 | }); | 12135 | }); |
| 12186 | } else if (e.target.matches('#CloseAllWIEntries')) { | 12136 | } else if (e.target.matches('#CloseAllWIEntries')) { |
| 12187 | document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => { | 12137 | document.querySelectorAll('#world_popup_entries_list .inline-drawer').forEach((/** @type {HTMLElement} */ drawer) => { |
| @@ -1,4 +1,4 @@ | |||
| 1 | import { DOMPurify, Bowser, slideToggle } from '../lib.js'; | 1 | import { DOMPurify, Bowser } from '../lib.js'; |
| 2 | 2 | ||
| 3 | import { | 3 | import { |
| 4 | characters, | 4 | characters, |
| @@ -19,7 +19,7 @@ import { | |||
| 19 | menu_type, | 19 | menu_type, |
| 20 | substituteParams, | 20 | substituteParams, |
| 21 | sendTextareaMessage, | 21 | sendTextareaMessage, |
| 22 | getSlideToggleOptions, | 22 | doNavbarIconClick, |
| 23 | } from '../script.js'; | 23 | } from '../script.js'; |
| 24 | 24 | ||
| 25 | import { | 25 | import { |
| @@ -473,54 +473,72 @@ const saveUserInputDebounced = debounce(saveUserInput); | |||
| 473 | 473 | ||
| 474 | // Make the DIV element draggable: | 474 | // Make the DIV element draggable: |
| 475 | 475 | ||
| 476 | export function dragElement(elmnt) { | 476 | /** |
| 477 | var isHeaderBeingDragged = false; | 477 | * Make the given element draggable. This is used for Moving UI. |
| 478 | var isMouseDown = false; | 478 | * @param {JQuery} $elmnt - The element to make draggable. |
| 479 | */ | ||
| 480 | export function dragElement($elmnt) { | ||
| 481 | let actionType = null; // "drag" or "resize" | ||
| 482 | let isMouseDown = false; | ||
| 479 | 483 | ||
| 480 | var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; | 484 | let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; |
| 481 | var height, width, top, left, right, bottom, | 485 | let height, width, top, left, right, bottom, |
| 482 | maxX, maxY, winHeight, winWidth, | 486 | maxX, maxY, winHeight, winWidth, |
| 483 | topbar, topBarFirstX, topBarLastY; | 487 | topbar, topBarFirstX, topBarLastY; |
| 484 | 488 | ||
| 485 | var elmntName = elmnt.attr('id'); | 489 | const elmntName = $elmnt.attr('id'); |
| 486 | console.debug(`dragElement called for ${elmntName}`); | ||
| 487 | const elmntNameEscaped = $.escapeSelector(elmntName); | 490 | const elmntNameEscaped = $.escapeSelector(elmntName); |
| 488 | const elmntHeader = $(`#${elmntNameEscaped}header`); | 491 | const $elmntHeader = $(`#${elmntNameEscaped}header`); |
| 489 | 492 | ||
| 490 | if (elmntHeader.length) { | 493 | // Helper: Save position/size to state and emit events |
| 491 | elmntHeader.off('mousedown').on('mousedown', (e) => { //listener for drag handle repositioning | 494 | function savePositionAndSize() { |
| 492 | isHeaderBeingDragged = true; | 495 | if (!power_user.movingUIState[elmntName]) power_user.movingUIState[elmntName] = {}; |
| 493 | isMouseDown = true; | 496 | power_user.movingUIState[elmntName].top = top; |
| 494 | observer.observe(elmnt.get(0), { attributes: true, attributeFilter: ['style'] }); | 497 | power_user.movingUIState[elmntName].left = left; |
| 495 | dragMouseDown(e); | 498 | power_user.movingUIState[elmntName].right = right; |
| 496 | }); | 499 | power_user.movingUIState[elmntName].bottom = bottom; |
| 497 | $(elmnt).off('mousedown').on('mousedown', () => { //listener for resize | 500 | power_user.movingUIState[elmntName].margin = 'unset'; |
| 498 | isMouseDown = true; | 501 | if (actionType === 'resize') { |
| 499 | observer.observe(elmnt.get(0), { attributes: true, attributeFilter: ['style'] }); | 502 | power_user.movingUIState[elmntName].width = width; |
| 500 | }); | 503 | power_user.movingUIState[elmntName].height = height; |
| 504 | eventSource.emit('resizeUI', elmntName); | ||
| 505 | } | ||
| 506 | saveSettingsDebounced(); | ||
| 501 | } | 507 | } |
| 502 | 508 | ||
| 509 | // Helper: Clamp element within viewport | ||
| 510 | function clampToViewport() { | ||
| 511 | if (top <= 0) $elmnt.css('top', '0px'); | ||
| 512 | else if (maxY >= winHeight) $elmnt.css('top', winHeight - maxY + top - 1 + 'px'); | ||
| 513 | if (left <= 0) $elmnt.css('left', '0px'); | ||
| 514 | else if (maxX >= winWidth) $elmnt.css('left', winWidth - maxX + left - 1 + 'px'); | ||
| 515 | } | ||
| 516 | |||
| 517 | // Observer for style changes (position/size) | ||
| 503 | const observer = new MutationObserver((mutations) => { | 518 | const observer = new MutationObserver((mutations) => { |
| 504 | const target = mutations[0].target; | 519 | const $target = $(mutations[0].target); |
| 505 | if (!$(target).is(':visible') //abort if element is invisible | 520 | if ( |
| 506 | || $(target).hasClass('resizing') //being auto-resized by other JS code | 521 | !$target.is(':visible') || |
| 507 | || Number((String(target.height).replace('px', ''))) < 50 //too short | 522 | $target.hasClass('resizing') || |
| 508 | || Number((String(target.width).replace('px', ''))) < 50 //too narrow | 523 | $target.height() < 50 || |
| 509 | || power_user.movingUI === false // if MUI is not turned on | 524 | $target.width() < 50 || |
| 510 | || isMobile() // if it's a mobile screen | 525 | power_user.movingUI === false || |
| 526 | isMobile() || | ||
| 527 | !isMouseDown | ||
| 511 | ) { | 528 | ) { |
| 529 | observer.disconnect(); | ||
| 512 | return; | 530 | return; |
| 513 | } | 531 | } |
| 514 | 532 | ||
| 515 | const style = getComputedStyle(target); | 533 | const style = getComputedStyle($target[0]); |
| 516 | height = parseInt(style.height); | 534 | height = parseInt(style.height); |
| 517 | width = parseInt(style.width); | 535 | width = parseInt(style.width); |
| 518 | top = parseInt(style.top); | 536 | top = parseInt(style.top); |
| 519 | left = parseInt(style.left); | 537 | left = parseInt(style.left); |
| 520 | right = parseInt(style.right); | 538 | right = parseInt(style.right); |
| 521 | bottom = parseInt(style.bottom); | 539 | bottom = parseInt(style.bottom); |
| 522 | maxX = parseInt(width + left); | 540 | maxX = width + left; |
| 523 | maxY = parseInt(height + top); | 541 | maxY = height + top; |
| 524 | winWidth = window.innerWidth; | 542 | winWidth = window.innerWidth; |
| 525 | winHeight = window.innerHeight; | 543 | winHeight = window.innerHeight; |
| 526 | 544 | ||
| @@ -529,182 +547,119 @@ export function dragElement(elmnt) { | |||
| 529 | topBarFirstX = parseInt(topbarstyle.marginInline); | 547 | topBarFirstX = parseInt(topbarstyle.marginInline); |
| 530 | topBarLastY = parseInt(topbarstyle.height); | 548 | topBarLastY = parseInt(topbarstyle.height); |
| 531 | 549 | ||
| 532 | //prepare an empty poweruser object for the item being altered if we don't have one already | 550 | // Prepare state object if missing |
| 533 | if (!power_user.movingUIState[elmntName]) { | 551 | if (!power_user.movingUIState[elmntName]) power_user.movingUIState[elmntName] = {}; |
| 534 | console.debug(`adding config property for ${elmntName}`); | ||
| 535 | power_user.movingUIState[elmntName] = {}; | ||
| 536 | } | ||
| 537 | 552 | ||
| 538 | //handle resizing | 553 | if (actionType === 'resize') { |
| 539 | if (!isHeaderBeingDragged && isMouseDown) { //if user is dragging the resize handle (not in header) | ||
| 540 | let imgHeight, imgWidth, imageAspectRatio; | ||
| 541 | let containerAspectRatio = height / width; | 554 | let containerAspectRatio = height / width; |
| 542 | 555 | if ($elmnt.attr('id').startsWith('zoomFor_')) { | |
| 543 | //force aspect ratio for zoomed avatars | 556 | const zoomedAvatarImage = $elmnt.find('.zoomed_avatar_img'); |
| 544 | if ($(elmnt).attr('id').startsWith('zoomFor_')) { | 557 | const imgHeight = zoomedAvatarImage.height(); |
| 545 | let zoomedAvatarImage = $(elmnt).find('.zoomed_avatar_img'); | 558 | const imgWidth = zoomedAvatarImage.width(); |
| 546 | imgHeight = zoomedAvatarImage.height(); | 559 | const imageAspectRatio = imgHeight / imgWidth; |
| 547 | imgWidth = zoomedAvatarImage.width(); | ||
| 548 | imageAspectRatio = imgHeight / imgWidth; | ||
| 549 | |||
| 550 | // Maintain aspect ratio | ||
| 551 | if (containerAspectRatio !== imageAspectRatio) { | 560 | if (containerAspectRatio !== imageAspectRatio) { |
| 552 | elmnt.css('width', elmnt.width()); | 561 | $elmnt.css('width', $elmnt.width()); |
| 553 | elmnt.css('height', elmnt.width() * imageAspectRatio); | 562 | $elmnt.css('height', $elmnt.width() * imageAspectRatio); |
| 554 | } | 563 | } |
| 555 | 564 | if (top + $elmnt.height() >= winHeight) { | |
| 556 | // Prevent resizing offscreen | 565 | $elmnt.css('height', winHeight - top - 1 + 'px'); |
| 557 | if (top + elmnt.height() >= winHeight) { | 566 | $elmnt.css('width', (winHeight - top - 1) / imageAspectRatio + 'px'); |
| 558 | elmnt.css('height', winHeight - top - 1 + 'px'); | ||
| 559 | elmnt.css('width', (winHeight - top - 1) / imageAspectRatio + 'px'); | ||
| 560 | } | 567 | } |
| 561 | 568 | if (left + $elmnt.width() >= winWidth) { | |
| 562 | if (left + elmnt.width() >= winWidth) { | 569 | $elmnt.css('width', winWidth - left - 1 + 'px'); |
| 563 | elmnt.css('width', winWidth - left - 1 + 'px'); | 570 | $elmnt.css('height', (winWidth - left - 1) * imageAspectRatio + 'px'); |
| 564 | elmnt.css('height', (winWidth - left - 1) * imageAspectRatio + 'px'); | ||
| 565 | } | ||
| 566 | } else { //prevent divs that are not zoomedAvatars from resizing offscreen | ||
| 567 | |||
| 568 | if (top + elmnt.height() >= winHeight) { | ||
| 569 | elmnt.css('height', winHeight - top - 1 + 'px'); | ||
| 570 | } | ||
| 571 | |||
| 572 | if (left + elmnt.width() >= winWidth) { | ||
| 573 | elmnt.css('width', winWidth - left - 1 + 'px'); | ||
| 574 | } | 571 | } |
| 572 | } else { | ||
| 573 | if (top + $elmnt.height() >= winHeight) $elmnt.css('height', winHeight - top - 1 + 'px'); | ||
| 574 | if (left + $elmnt.width() >= winWidth) $elmnt.css('width', winWidth - left - 1 + 'px'); | ||
| 575 | } | 575 | } |
| 576 | |||
| 577 | //prevent resizing from top left into the top bar | ||
| 578 | if (top < topBarLastY && maxX >= topBarFirstX && left <= topBarFirstX) { | 576 | if (top < topBarLastY && maxX >= topBarFirstX && left <= topBarFirstX) { |
| 579 | elmnt.css('width', width - 1 + 'px'); | 577 | $elmnt.css('width', width - 1 + 'px'); |
| 580 | } | 578 | } |
| 581 | 579 | $elmnt.css({ left, top }); | |
| 582 | //set css to prevent weird resize behavior (does not save) | 580 | $elmnt.off('mouseup').on('mouseup', () => { |
| 583 | elmnt.css('left', left); | 581 | if ( |
| 584 | elmnt.css('top', top); | 582 | power_user.movingUIState[elmntName].width === $elmnt.width() && |
| 585 | 583 | power_user.movingUIState[elmntName].height === $elmnt.height() | |
| 586 | //set a listener for mouseup to save new width/height | 584 | ) return; |
| 587 | $(window).off('mouseup').on('mouseup', () => { | 585 | savePositionAndSize(); |
| 588 | console.log(`Saving ${elmntName} Height/Width`); | 586 | observer.disconnect(); |
| 589 | // check if the height or width actually changed | ||
| 590 | if (power_user.movingUIState[elmntName].width === elmnt.width() && power_user.movingUIState[elmntName].height === elmnt.height()) { | ||
| 591 | console.log('no change detected, aborting save'); | ||
| 592 | return; | ||
| 593 | } | ||
| 594 | |||
| 595 | power_user.movingUIState[elmntName].width = width; | ||
| 596 | power_user.movingUIState[elmntName].height = height; | ||
| 597 | eventSource.emit('resizeUI', elmntName); | ||
| 598 | saveSettingsDebounced(); | ||
| 599 | imgHeight = null; | ||
| 600 | imgWidth = null; | ||
| 601 | height = null; | ||
| 602 | width = null; | ||
| 603 | |||
| 604 | containerAspectRatio = null; | ||
| 605 | imageAspectRatio = null; | ||
| 606 | $(window).off('mouseup'); | ||
| 607 | }); | 587 | }); |
| 588 | } else if (actionType === 'drag') { | ||
| 589 | clampToViewport(); | ||
| 608 | } | 590 | } |
| 609 | 591 | ||
| 610 | //only record position changes if header is being dragged | 592 | // Always update position in state |
| 611 | power_user.movingUIState[elmntName].top = top; | 593 | savePositionAndSize(); |
| 612 | power_user.movingUIState[elmntName].left = left; | ||
| 613 | power_user.movingUIState[elmntName].right = right; | ||
| 614 | power_user.movingUIState[elmntName].bottom = bottom; | ||
| 615 | power_user.movingUIState[elmntName].margin = 'unset'; | ||
| 616 | |||
| 617 | //handle dragging hit detection to prevent dragging offscreen | ||
| 618 | if (isHeaderBeingDragged && isMouseDown) { | ||
| 619 | |||
| 620 | if (top <= 0) { | ||
| 621 | elmnt.css('top', '0px'); | ||
| 622 | } else if (maxY >= winHeight) { | ||
| 623 | elmnt.css('top', winHeight - maxY + top - 1 + 'px'); | ||
| 624 | } | ||
| 625 | |||
| 626 | if (left <= 0) { | ||
| 627 | elmnt.css('left', '0px'); | ||
| 628 | } else if (maxX >= winWidth) { | ||
| 629 | elmnt.css('left', winWidth - maxX + left - 1 + 'px'); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | // Check if the element header exists and set the reposition listener on the grabber in the header | ||
| 634 | if (elmntHeader.length) { | ||
| 635 | elmntHeader.off('mousedown').on('mousedown', (e) => { | ||
| 636 | dragMouseDown(e); | ||
| 637 | }); | ||
| 638 | } else { //if no header, put the listener on the elmnt itself. | ||
| 639 | elmnt.off('mousedown').on('mousedown', dragMouseDown); | ||
| 640 | } | ||
| 641 | }); | 594 | }); |
| 642 | 595 | ||
| 596 | // Mouse event handlers | ||
| 643 | function dragMouseDown(e) { | 597 | function dragMouseDown(e) { |
| 644 | |||
| 645 | if (e) { | 598 | if (e) { |
| 646 | isHeaderBeingDragged = true; | 599 | actionType = 'drag'; |
| 600 | isMouseDown = true; | ||
| 647 | e.preventDefault(); | 601 | e.preventDefault(); |
| 648 | pos3 = e.clientX; //mouse X at click | 602 | pos3 = e.clientX; |
| 649 | pos4 = e.clientY; //mouse Y at click | 603 | pos4 = e.clientY; |
| 650 | } | 604 | } |
| 651 | $(document).on('mouseup', closeDragElement); | 605 | $(document).on('mouseup', closeDragElement); |
| 652 | $(document).on('mousemove', elementDrag); | 606 | $(document).on('mousemove', elementDrag); |
| 653 | } | 607 | } |
| 654 | 608 | ||
| 655 | function elementDrag(e) { | 609 | function elementDrag(e) { |
| 656 | if (!power_user.movingUIState[elmntName]) { | 610 | if (!power_user.movingUIState[elmntName]) power_user.movingUIState[elmntName] = {}; |
| 657 | power_user.movingUIState[elmntName] = {}; | ||
| 658 | } | ||
| 659 | |||
| 660 | e = e || window.event; | ||
| 661 | e.preventDefault(); | 611 | e.preventDefault(); |
| 662 | 612 | pos1 = pos3 - e.clientX; | |
| 663 | pos1 = pos3 - e.clientX; //X change amt (-1 or 1) | 613 | pos2 = pos4 - e.clientY; |
| 664 | pos2 = pos4 - e.clientY; //Y change amt (-1 or 1) | 614 | pos3 = e.clientX; |
| 665 | pos3 = e.clientX; //new mouse X | 615 | pos4 = e.clientY; |
| 666 | pos4 = e.clientY; //new mouse Y | 616 | $elmnt.attr('data-dragged', 'true'); |
| 667 | 617 | $elmnt.css('left', ($elmnt.offset().left - pos1) + 'px'); | |
| 668 | elmnt.attr('data-dragged', 'true'); | 618 | $elmnt.css('top', ($elmnt.offset().top - pos2) + 'px'); |
| 669 | 619 | $elmnt.css('margin', 'unset'); | |
| 670 | //first set css to computed values to avoid CSS NaN results from 'auto', etc | 620 | $elmnt.css('height', height); |
| 671 | elmnt.css('left', (elmnt.offset().left) + 'px'); | 621 | $elmnt.css('width', width); |
| 672 | elmnt.css('top', (elmnt.offset().top) + 'px'); | ||
| 673 | |||
| 674 | //then update element position styles to account for drag changes | ||
| 675 | elmnt.css('margin', 'unset'); | ||
| 676 | elmnt.css('left', (elmnt.offset().left - pos1) + 'px'); | ||
| 677 | elmnt.css('top', (elmnt.offset().top - pos2) + 'px'); | ||
| 678 | /* elmnt.css('right', ((winWidth - maxX) + 'px')); | ||
| 679 | elmnt.css('bottom', ((winHeight - maxY) + 'px')); */ | ||
| 680 | |||
| 681 | // Height/Width here are for visuals only, and are not saved to settings. | ||
| 682 | // This is required because some divs do hot have a set width/height | ||
| 683 | // and will default to shrink to min value of 100px set in CSS file | ||
| 684 | elmnt.css('height', height); | ||
| 685 | elmnt.css('width', width); | ||
| 686 | return; | ||
| 687 | } | 622 | } |
| 688 | 623 | ||
| 689 | function closeDragElement() { | 624 | function closeDragElement() { |
| 690 | console.debug('drag finished'); | ||
| 691 | isHeaderBeingDragged = false; | ||
| 692 | isMouseDown = false; | 625 | isMouseDown = false; |
| 626 | actionType = null; | ||
| 693 | $(document).off('mouseup', closeDragElement); | 627 | $(document).off('mouseup', closeDragElement); |
| 694 | $(document).off('mousemove', elementDrag); | 628 | $(document).off('mousemove', elementDrag); |
| 695 | $('body').css('overflow', ''); | 629 | $elmnt.attr('data-dragged', 'false'); |
| 696 | // Clear the "data-dragged" attribute | ||
| 697 | elmnt.attr('data-dragged', 'false'); | ||
| 698 | observer.disconnect(); | 630 | observer.disconnect(); |
| 699 | console.debug(`Saving ${elmntName} UI position`); | 631 | savePositionAndSize(); |
| 700 | saveSettingsDebounced(); | 632 | } |
| 701 | top = null; | 633 | |
| 702 | left = null; | 634 | // Setup event listeners |
| 703 | right = null; | 635 | if ($elmntHeader.length) { |
| 704 | bottom = null; | 636 | $elmntHeader.off('mousedown').on('mousedown', (e) => { |
| 705 | maxX = null; | 637 | if ($(e.target).hasClass('drag-grabber')) { |
| 706 | maxY = null; | 638 | actionType = 'drag'; |
| 639 | isMouseDown = true; | ||
| 640 | observer.observe($elmnt[0], { attributes: true, attributeFilter: ['style'] }); | ||
| 641 | dragMouseDown(e); | ||
| 642 | } | ||
| 643 | }); | ||
| 707 | } | 644 | } |
| 645 | |||
| 646 | $elmnt.off('mousedown').on('mousedown', (e) => { | ||
| 647 | const rect = $elmnt[0].getBoundingClientRect(); | ||
| 648 | const resizeMargin = 16; | ||
| 649 | const isNearRight = e.clientX > rect.right - resizeMargin; | ||
| 650 | const isNearBottom = e.clientY > rect.bottom - resizeMargin; | ||
| 651 | if (isNearRight && isNearBottom) { | ||
| 652 | actionType = 'resize'; | ||
| 653 | isMouseDown = true; | ||
| 654 | observer.observe($elmnt[0], { attributes: true, attributeFilter: ['style'] }); | ||
| 655 | } | ||
| 656 | }); | ||
| 657 | |||
| 658 | $elmnt.off('mouseup').on('mouseup', () => { | ||
| 659 | isMouseDown = false; | ||
| 660 | actionType = null; | ||
| 661 | observer.disconnect(); | ||
| 662 | }); | ||
| 708 | } | 663 | } |
| 709 | 664 | ||
| 710 | export async function initMovingUI() { | 665 | export async function initMovingUI() { |
| @@ -775,9 +730,8 @@ export function initRossMods() { | |||
| 775 | $(RightNavDrawerIcon).removeClass('drawerPinnedOpen'); | 730 | $(RightNavDrawerIcon).removeClass('drawerPinnedOpen'); |
| 776 | 731 | ||
| 777 | if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { | 732 | if ($(RightNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { |
| 778 | slideToggle(RightNavPanel, getSlideToggleOptions()); | 733 | const toggle = $('#unimportantYes'); |
| 779 | $(RightNavDrawerIcon).toggleClass('closedIcon openIcon'); | 734 | doNavbarIconClick.call(toggle); |
| 780 | $(RightNavPanel).toggleClass('openDrawer closedDrawer'); | ||
| 781 | } | 735 | } |
| 782 | } | 736 | } |
| 783 | }); | 737 | }); |
| @@ -793,14 +747,13 @@ export function initRossMods() { | |||
| 793 | $(LeftNavDrawerIcon).removeClass('drawerPinnedOpen'); | 747 | $(LeftNavDrawerIcon).removeClass('drawerPinnedOpen'); |
| 794 | 748 | ||
| 795 | if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { | 749 | if ($(LeftNavPanel).hasClass('openDrawer') && $('.openDrawer').length > 1) { |
| 796 | slideToggle(LeftNavPanel, getSlideToggleOptions()); | 750 | const toggle = $('#ai-config-button>.drawer-toggle'); |
| 797 | $(LeftNavDrawerIcon).toggleClass('closedIcon openIcon'); | 751 | doNavbarIconClick.call(toggle); |
| 798 | $(LeftNavPanel).toggleClass('openDrawer closedDrawer'); | ||
| 799 | } | 752 | } |
| 800 | } | 753 | } |
| 801 | }); | 754 | }); |
| 802 | 755 | ||
| 803 | $(WIPanelPin).on('click', function () { | 756 | $(WIPanelPin).on('click', async function () { |
| 804 | accountStorage.setItem('WINavLockOn', $(WIPanelPin).prop('checked')); | 757 | accountStorage.setItem('WINavLockOn', $(WIPanelPin).prop('checked')); |
| 805 | if ($(WIPanelPin).prop('checked') == true) { | 758 | if ($(WIPanelPin).prop('checked') == true) { |
| 806 | console.debug('adding pin class to WI'); | 759 | console.debug('adding pin class to WI'); |
| @@ -813,9 +766,8 @@ export function initRossMods() { | |||
| 813 | 766 | ||
| 814 | if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) { | 767 | if ($(WorldInfo).hasClass('openDrawer') && $('.openDrawer').length > 1) { |
| 815 | console.debug('closing WI after lock removal'); | 768 | console.debug('closing WI after lock removal'); |
| 816 | slideToggle(WorldInfo, getSlideToggleOptions()); | 769 | const toggle = $('#WI-SP-button>.drawer-toggle'); |
| 817 | $(WIDrawerIcon).toggleClass('closedIcon openIcon'); | 770 | doNavbarIconClick.call(toggle); |
| 818 | $(WorldInfo).toggleClass('openDrawer closedDrawer'); | ||
| 819 | } | 771 | } |
| 820 | } | 772 | } |
| 821 | }); | 773 | }); |
| @@ -1,9 +1,11 @@ | |||
| 1 | import { | 1 | import { |
| 2 | MAX_INJECTION_DEPTH, | ||
| 2 | animation_duration, | 3 | animation_duration, |
| 3 | chat_metadata, | 4 | chat_metadata, |
| 4 | eventSource, | 5 | eventSource, |
| 5 | event_types, | 6 | event_types, |
| 6 | extension_prompt_roles, | 7 | extension_prompt_roles, |
| 8 | extension_prompt_types, | ||
| 7 | saveSettingsDebounced, | 9 | saveSettingsDebounced, |
| 8 | this_chid, | 10 | this_chid, |
| 9 | } from '../script.js'; | 11 | } from '../script.js'; |
| @@ -347,7 +349,7 @@ export function setFloatingPrompt() { | |||
| 347 | } | 349 | } |
| 348 | 350 | ||
| 349 | if (lastMessageNumber <= 0 || chat_metadata[metadata_keys.interval] <= 0) { | 351 | if (lastMessageNumber <= 0 || chat_metadata[metadata_keys.interval] <= 0) { |
| 350 | context.setExtensionPrompt(MODULE_NAME, ''); | 352 | context.setExtensionPrompt(MODULE_NAME, '', extension_prompt_types.NONE, MAX_INJECTION_DEPTH); |
| 351 | $('#extension_floating_counter').text('(disabled)'); | 353 | $('#extension_floating_counter').text('(disabled)'); |
| 352 | shouldWIAddPrompt = false; | 354 | shouldWIAddPrompt = false; |
| 353 | return; | 355 | return; |
| @@ -380,7 +382,7 @@ export function setFloatingPrompt() { | |||
| 380 | } | 382 | } |
| 381 | context.setExtensionPrompt( | 383 | context.setExtensionPrompt( |
| 382 | MODULE_NAME, | 384 | MODULE_NAME, |
| 383 | prompt, | 385 | String(prompt), |
| 384 | chat_metadata[metadata_keys.position], | 386 | chat_metadata[metadata_keys.position], |
| 385 | chat_metadata[metadata_keys.depth], | 387 | chat_metadata[metadata_keys.depth], |
| 386 | extension_settings.note.allowWIScan, | 388 | extension_settings.note.allowWIScan, |
| @@ -396,37 +398,38 @@ function onANMenuItemClick() { | |||
| 396 | } | 398 | } |
| 397 | 399 | ||
| 398 | //show AN if it's hidden | 400 | //show AN if it's hidden |
| 399 | if ($('#floatingPrompt').css('display') !== 'flex') { | 401 | const $ANcontainer = $('#floatingPrompt'); |
| 400 | $('#floatingPrompt').addClass('resizing'); | 402 | if ($ANcontainer.css('display') !== 'flex') { |
| 401 | $('#floatingPrompt').css('display', 'flex'); | 403 | $ANcontainer.addClass('resizing'); |
| 402 | $('#floatingPrompt').css('opacity', 0.0); | 404 | $ANcontainer.css('display', 'flex'); |
| 403 | $('#floatingPrompt').transition({ | 405 | $ANcontainer.css('opacity', 0.0); |
| 406 | $ANcontainer.transition({ | ||
| 404 | opacity: 1.0, | 407 | opacity: 1.0, |
| 405 | duration: animation_duration, | 408 | duration: animation_duration, |
| 406 | }, async function () { | 409 | }, async function () { |
| 407 | await delay(50); | 410 | await delay(50); |
| 408 | $('#floatingPrompt').removeClass('resizing'); | 411 | $ANcontainer.removeClass('resizing'); |
| 409 | }); | 412 | }); |
| 410 | 413 | ||
| 411 | //auto-open the main AN inline drawer | 414 | //auto-open the main AN inline drawer |
| 412 | if ($('#ANBlockToggle') | 415 | if ($('#ANBlockToggle') |
| 413 | .siblings('.inline-drawer-content') | 416 | .siblings('.inline-drawer-content') |
| 414 | .css('display') !== 'block') { | 417 | .css('display') !== 'block') { |
| 415 | $('#floatingPrompt').addClass('resizing'); | 418 | $ANcontainer.addClass('resizing'); |
| 416 | $('#ANBlockToggle').click(); | 419 | $('#ANBlockToggle').trigger('click'); |
| 417 | } | 420 | } |
| 418 | } else { | 421 | } else { |
| 419 | //hide AN if it's already displayed | 422 | //hide AN if it's already displayed |
| 420 | $('#floatingPrompt').addClass('resizing'); | 423 | $ANcontainer.addClass('resizing'); |
| 421 | $('#floatingPrompt').transition({ | 424 | $ANcontainer.transition({ |
| 422 | opacity: 0.0, | 425 | opacity: 0.0, |
| 423 | duration: animation_duration, | 426 | duration: animation_duration, |
| 424 | }, async function () { | 427 | }, async function () { |
| 425 | await delay(50); | 428 | await delay(50); |
| 426 | $('#floatingPrompt').removeClass('resizing'); | 429 | $ANcontainer.removeClass('resizing'); |
| 427 | }); | 430 | }); |
| 428 | setTimeout(function () { | 431 | setTimeout(function () { |
| 429 | $('#floatingPrompt').hide(); | 432 | $ANcontainer.hide(); |
| 430 | }, animation_duration); | 433 | }, animation_duration); |
| 431 | } | 434 | } |
| 432 | 435 | ||
| @@ -65,7 +65,7 @@ | |||
| 65 | .asset-download-button-text { | 65 | .asset-download-button-text { |
| 66 | font: bold 20px "Quicksand", san-serif; | 66 | font: bold 20px "Quicksand", san-serif; |
| 67 | color: #ffffff; | 67 | color: #ffffff; |
| 68 | transition: all 0.2s; | 68 | transition: all var(--animation-duration-2x); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | .asset-download-button-loading .asset-download-button-text { | 71 | .asset-download-button-loading .asset-download-button-text { |
| @@ -4,6 +4,8 @@ import { | |||
| 4 | characters, | 4 | characters, |
| 5 | getRequestHeaders, | 5 | getRequestHeaders, |
| 6 | event_types, | 6 | event_types, |
| 7 | animation_duration, | ||
| 8 | animation_easing, | ||
| 7 | } from '../../../script.js'; | 9 | } from '../../../script.js'; |
| 8 | import { groups, selected_group } from '../../group-chats.js'; | 10 | import { groups, selected_group } from '../../group-chats.js'; |
| 9 | import { loadFileToDocument, delay, getBase64Async, getSanitizedFilename } from '../../utils.js'; | 11 | import { loadFileToDocument, delay, getBase64Async, getSanitizedFilename } from '../../utils.js'; |
| @@ -32,7 +34,15 @@ let galleryMaxRows = 3; | |||
| 32 | $('#movingDivs').on('click', '.dragClose', function () { | 34 | $('#movingDivs').on('click', '.dragClose', function () { |
| 33 | const relatedId = $(this).data('related-id'); | 35 | const relatedId = $(this).data('related-id'); |
| 34 | if (!relatedId) return; | 36 | if (!relatedId) return; |
| 35 | $(`#movingDivs > .draggable[id="${relatedId}"]`).remove(); | 37 | const relatedElement = $(`#movingDivs > .draggable[id="${relatedId}"]`); |
| 38 | relatedElement.transition({ | ||
| 39 | opacity: 0, | ||
| 40 | duration: animation_duration, | ||
| 41 | easing: animation_easing, | ||
| 42 | complete: () => { | ||
| 43 | relatedElement.remove(); | ||
| 44 | }, | ||
| 45 | }); | ||
| 36 | }); | 46 | }); |
| 37 | 47 | ||
| 38 | const CUSTOM_GALLERY_REMOVED_EVENT = 'galleryRemoved'; | 48 | const CUSTOM_GALLERY_REMOVED_EVENT = 'galleryRemoved'; |
| @@ -373,7 +383,7 @@ async function makeMovable(url) { | |||
| 373 | const id = 'gallery'; | 383 | const id = 'gallery'; |
| 374 | const template = $('#generic_draggable_template').html(); | 384 | const template = $('#generic_draggable_template').html(); |
| 375 | const newElement = $(template); | 385 | const newElement = $(template); |
| 376 | newElement.css('background-color', 'var(--SmartThemeBlurTintColor)'); | 386 | newElement.css({ 'background-color': 'var(--SmartThemeBlurTintColor)', 'opacity': 0 }); |
| 377 | newElement.attr('forChar', id); | 387 | newElement.attr('forChar', id); |
| 378 | newElement.attr('id', id); | 388 | newElement.attr('id', id); |
| 379 | newElement.find('.drag-grabber').attr('id', `${id}header`); | 389 | newElement.find('.drag-grabber').attr('id', `${id}header`); |
| @@ -505,6 +515,11 @@ async function makeMovable(url) { | |||
| 505 | loadMovingUIState(); | 515 | loadMovingUIState(); |
| 506 | $(`.draggable[forChar="${id}"]`).css('display', 'block'); | 516 | $(`.draggable[forChar="${id}"]`).css('display', 'block'); |
| 507 | dragElement(newElement); | 517 | dragElement(newElement); |
| 518 | newElement.transition({ | ||
| 519 | opacity: 1, | ||
| 520 | duration: animation_duration, | ||
| 521 | easing: animation_easing, | ||
| 522 | }); | ||
| 508 | 523 | ||
| 509 | $(`.draggable[forChar="${id}"] img`).on('dragstart', (e) => { | 524 | $(`.draggable[forChar="${id}"] img`).on('dragstart', (e) => { |
| 510 | console.log('saw drag on avatar!'); | 525 | console.log('saw drag on avatar!'); |
| @@ -16,6 +16,7 @@ import { | |||
| 16 | getMaxContextSize, | 16 | getMaxContextSize, |
| 17 | setExtensionPrompt, | 17 | setExtensionPrompt, |
| 18 | streamingProcessor, | 18 | streamingProcessor, |
| 19 | animation_easing, | ||
| 19 | } from '../../../script.js'; | 20 | } from '../../../script.js'; |
| 20 | import { is_group_generating, selected_group } from '../../group-chats.js'; | 21 | import { is_group_generating, selected_group } from '../../group-chats.js'; |
| 21 | import { loadMovingUIState } from '../../power-user.js'; | 22 | import { loadMovingUIState } from '../../power-user.js'; |
| @@ -972,6 +973,7 @@ function doPopout(e) { | |||
| 972 | </div>`; | 973 | </div>`; |
| 973 | const newElement = $(template); | 974 | const newElement = $(template); |
| 974 | newElement.attr('id', 'summaryExtensionPopout') | 975 | newElement.attr('id', 'summaryExtensionPopout') |
| 976 | .css('opacity', 0) | ||
| 975 | .removeClass('zoomed_avatar') | 977 | .removeClass('zoomed_avatar') |
| 976 | .addClass('draggable') | 978 | .addClass('draggable') |
| 977 | .empty(); | 979 | .empty(); |
| @@ -980,13 +982,13 @@ function doPopout(e) { | |||
| 980 | originalElement.html('<div class="flex-container alignitemscenter justifyCenter wide100p"><small>Currently popped out</small></div>'); | 982 | originalElement.html('<div class="flex-container alignitemscenter justifyCenter wide100p"><small>Currently popped out</small></div>'); |
| 981 | newElement.append(controlBarHtml).append(originalHTMLClone); | 983 | newElement.append(controlBarHtml).append(originalHTMLClone); |
| 982 | $('body').append(newElement); | 984 | $('body').append(newElement); |
| 985 | newElement.transition({ opacity: 1, duration: animation_duration, easing: animation_easing }); | ||
| 983 | $('#summaryExtensionDrawerContents').addClass('scrollableInnerFull'); | 986 | $('#summaryExtensionDrawerContents').addClass('scrollableInnerFull'); |
| 984 | setMemoryContext(prevSummaryBoxContents, false); //paste prev summary box contents into popout box | 987 | setMemoryContext(prevSummaryBoxContents, false); //paste prev summary box contents into popout box |
| 985 | setupListeners(); | 988 | setupListeners(); |
| 986 | loadSettings(); | 989 | loadSettings(); |
| 987 | loadMovingUIState(); | 990 | loadMovingUIState(); |
| 988 | 991 | ||
| 989 | $('#summaryExtensionPopout').fadeIn(animation_duration); | ||
| 990 | dragElement(newElement); | 992 | dragElement(newElement); |
| 991 | 993 | ||
| 992 | //setup listener for close button to restore extensions menu | 994 | //setup listener for close button to restore extensions menu |
| @@ -18,7 +18,7 @@ | |||
| 18 | #qr--bar { | 18 | #qr--bar { |
| 19 | outline: none; | 19 | outline: none; |
| 20 | margin: 0; | 20 | margin: 0; |
| 21 | transition: 0.3s; | 21 | transition: var(--animation-duration-2x); |
| 22 | opacity: 0.7; | 22 | opacity: 0.7; |
| 23 | display: flex; | 23 | display: flex; |
| 24 | align-items: center; | 24 | align-items: center; |
| @@ -34,14 +34,12 @@ | |||
| 34 | right: 0.25em; | 34 | right: 0.25em; |
| 35 | top: 0; | 35 | top: 0; |
| 36 | } | 36 | } |
| 37 | |||
| 38 | /*hide QR popout for mobile*/ | 37 | /*hide QR popout for mobile*/ |
| 39 | @media screen and (max-width: 1000px) { | 38 | @media screen and (max-width: 1000px) { |
| 40 | #qr--bar > #qr--popoutTrigger { | 39 | #qr--bar > #qr--popoutTrigger { |
| 41 | display:none; | 40 | display: none; |
| 42 | } | 41 | } |
| 43 | } | 42 | } |
| 44 | |||
| 45 | #qr--bar.popoutVisible { | 43 | #qr--bar.popoutVisible { |
| 46 | padding-right: 2.5em; | 44 | padding-right: 2.5em; |
| 47 | } | 45 | } |
| @@ -61,9 +59,8 @@ | |||
| 61 | aspect-ratio: 1 / 1; | 59 | aspect-ratio: 1 / 1; |
| 62 | font-size: 20px; | 60 | font-size: 20px; |
| 63 | opacity: 0.5; | 61 | opacity: 0.5; |
| 64 | transition: all 250ms; | 62 | transition: all var(--animation-duration-2x); |
| 65 | } | 63 | } |
| 66 | |||
| 67 | #qr--popout > .qr--body { | 64 | #qr--popout > .qr--body { |
| 68 | overflow-y: auto; | 65 | overflow-y: auto; |
| 69 | } | 66 | } |
| @@ -124,7 +121,7 @@ | |||
| 124 | padding: 3px 5px; | 121 | padding: 3px 5px; |
| 125 | margin: 3px 0; | 122 | margin: 3px 0; |
| 126 | cursor: pointer; | 123 | cursor: pointer; |
| 127 | transition: 0.3s; | 124 | transition: var(--animation-duration-2x); |
| 128 | display: flex; | 125 | display: flex; |
| 129 | align-items: center; | 126 | align-items: center; |
| 130 | justify-content: center; | 127 | justify-content: center; |
| @@ -175,7 +172,7 @@ | |||
| 175 | overflow: visible; | 172 | overflow: visible; |
| 176 | } | 173 | } |
| 177 | .ctx-menu .ctx-item .qr--hidden { | 174 | .ctx-menu .ctx-item .qr--hidden { |
| 178 | display: none; | 175 | display: none; |
| 179 | } | 176 | } |
| 180 | .list-group .list-group-item.ctx-header { | 177 | .list-group .list-group-item.ctx-header { |
| 181 | font-weight: bold; | 178 | font-weight: bold; |
| @@ -248,7 +245,7 @@ | |||
| 248 | display: flex; | 245 | display: flex; |
| 249 | align-items: center; | 246 | align-items: center; |
| 250 | opacity: 0; | 247 | opacity: 0; |
| 251 | transition: 100ms; | 248 | transition: var(--animation-duration); |
| 252 | margin: -2px 0 -11px 0; | 249 | margin: -2px 0 -11px 0; |
| 253 | position: relative; | 250 | position: relative; |
| 254 | } | 251 | } |
| @@ -461,7 +458,7 @@ | |||
| 461 | cursor: not-allowed; | 458 | cursor: not-allowed; |
| 462 | opacity: 0.5; | 459 | opacity: 0.5; |
| 463 | pointer-events: none; | 460 | pointer-events: none; |
| 464 | transition: 200ms; | 461 | transition: var(--animation-duration-2x); |
| 465 | border-color: transparent; | 462 | border-color: transparent; |
| 466 | } | 463 | } |
| 467 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor.qr--isExecuting.qr--isPaused #qr--modal-debugButtons .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { | 464 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor.qr--isExecuting.qr--isPaused #qr--modal-debugButtons .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { |
| @@ -492,7 +489,7 @@ | |||
| 492 | width: 6px; | 489 | width: 6px; |
| 493 | background-color: var(--SmartThemeBorderColor); | 490 | background-color: var(--SmartThemeBorderColor); |
| 494 | border: 2px solid var(--SmartThemeBlurTintColor); | 491 | border: 2px solid var(--SmartThemeBlurTintColor); |
| 495 | transition: border-color 200ms, background-color 200ms; | 492 | transition: border-color var(--animation-duration-2x), background-color var(--animation-duration-2x); |
| 496 | cursor: w-resize; | 493 | cursor: w-resize; |
| 497 | } | 494 | } |
| 498 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor.qr--isExecuting #qr--resizeHandle:hover { | 495 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor.qr--isExecuting #qr--resizeHandle:hover { |
| @@ -574,7 +571,7 @@ | |||
| 574 | gap: 1em; | 571 | gap: 1em; |
| 575 | text-align: left; | 572 | text-align: left; |
| 576 | opacity: 0.75; | 573 | opacity: 0.75; |
| 577 | transition: 200ms; | 574 | transition: var(--animation-duration-2x); |
| 578 | cursor: pointer; | 575 | cursor: pointer; |
| 579 | } | 576 | } |
| 580 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--labels > label .qr--modal-switcherList .qr--modal-switcherItem:hover, | 577 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor > #qr--main > .qr--labels > label .qr--modal-switcherList .qr--modal-switcherItem:hover, |
| @@ -736,7 +733,7 @@ | |||
| 736 | display: flex; | 733 | display: flex; |
| 737 | } | 734 | } |
| 738 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeButtons #qr--modal-execute { | 735 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeButtons #qr--modal-execute { |
| 739 | transition: 200ms; | 736 | transition: var(--animation-duration-2x); |
| 740 | filter: grayscale(0); | 737 | filter: grayscale(0); |
| 741 | } | 738 | } |
| 742 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeButtons #qr--modal-execute.qr--busy { | 739 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeButtons #qr--modal-execute.qr--busy { |
| @@ -825,7 +822,7 @@ | |||
| 825 | position: absolute; | 822 | position: absolute; |
| 826 | inset: 0; | 823 | inset: 0; |
| 827 | right: calc(100% - var(--prog) * 1%); | 824 | right: calc(100% - var(--prog) * 1%); |
| 828 | transition: 200ms; | 825 | transition: var(--animation-duration-2x); |
| 829 | } | 826 | } |
| 830 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeProgress.qr--paused:after { | 827 | .popup:has(#qr--modalEditor) .popup-content > #qr--modalEditor #qr--modal-executeProgress.qr--paused:after { |
| 831 | animation-name: qr--progressPulse; | 828 | animation-name: qr--progressPulse; |
| @@ -1053,7 +1050,7 @@ | |||
| 1053 | white-space: pre; | 1050 | white-space: pre; |
| 1054 | font-weight: normal; | 1051 | font-weight: normal; |
| 1055 | box-shadow: 0 0 0; | 1052 | box-shadow: 0 0 0; |
| 1056 | transition: 200ms; | 1053 | transition: var(--animation-duration-2x); |
| 1057 | } | 1054 | } |
| 1058 | .popup:has(.qr--transferModal) .popup-button-ok:after { | 1055 | .popup:has(.qr--transferModal) .popup-button-ok:after { |
| 1059 | content: 'Transfer'; | 1056 | content: 'Transfer'; |
| @@ -1068,7 +1065,7 @@ | |||
| 1068 | white-space: pre; | 1065 | white-space: pre; |
| 1069 | font-weight: normal; | 1066 | font-weight: normal; |
| 1070 | box-shadow: 0 0 0; | 1067 | box-shadow: 0 0 0; |
| 1071 | transition: 200ms; | 1068 | transition: var(--animation-duration-2x); |
| 1072 | } | 1069 | } |
| 1073 | .popup:has(.qr--transferModal) .qr--copy:after { | 1070 | .popup:has(.qr--transferModal) .qr--copy:after { |
| 1074 | content: 'Copy'; | 1071 | content: 'Copy'; |
| @@ -1,11 +1,16 @@ | |||
| 1 | @keyframes qr--success { | 1 | @keyframes qr--success { |
| 2 | 0%, 100% { | 2 | |
| 3 | 0%, | ||
| 4 | 100% { | ||
| 3 | color: var(--SmartThemeBodyColor); | 5 | color: var(--SmartThemeBodyColor); |
| 4 | } | 6 | } |
| 5 | 25%, 75% { | 7 | |
| 8 | 25%, | ||
| 9 | 75% { | ||
| 6 | color: rgb(81, 163, 81); | 10 | color: rgb(81, 163, 81); |
| 7 | } | 11 | } |
| 8 | } | 12 | } |
| 13 | |||
| 9 | &.qr--success { | 14 | &.qr--success { |
| 10 | animation-name: qr--success; | 15 | animation-name: qr--success; |
| 11 | animation-duration: 3s; | 16 | animation-duration: 3s; |
| @@ -13,10 +18,11 @@ | |||
| 13 | animation-delay: 0s; | 18 | animation-delay: 0s; |
| 14 | animation-iteration-count: 1; | 19 | animation-iteration-count: 1; |
| 15 | } | 20 | } |
| 21 | |||
| 16 | #qr--bar { | 22 | #qr--bar { |
| 17 | outline: none; | 23 | outline: none; |
| 18 | margin: 0; | 24 | margin: 0; |
| 19 | transition: 0.3s; | 25 | transition: var(--animation-duration-2x); |
| 20 | opacity: 0.7; | 26 | opacity: 0.7; |
| 21 | display: flex; | 27 | display: flex; |
| 22 | align-items: center; | 28 | align-items: center; |
| @@ -33,6 +39,14 @@ | |||
| 33 | top: 0; | 39 | top: 0; |
| 34 | } | 40 | } |
| 35 | } | 41 | } |
| 42 | |||
| 43 | /*hide QR popout for mobile*/ | ||
| 44 | @media screen and (max-width: 1000px) { | ||
| 45 | #qr--bar>#qr--popoutTrigger { | ||
| 46 | display: none; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 36 | #qr--bar.popoutVisible { | 50 | #qr--bar.popoutVisible { |
| 37 | padding-right: 2.5em; | 51 | padding-right: 2.5em; |
| 38 | } | 52 | } |
| @@ -54,7 +68,7 @@ | |||
| 54 | aspect-ratio: 1 / 1; | 68 | aspect-ratio: 1 / 1; |
| 55 | font-size: 20px; | 69 | font-size: 20px; |
| 56 | opacity: 0.5; | 70 | opacity: 0.5; |
| 57 | transition: all 250ms; | 71 | transition: all var(--animation-duration-2x); |
| 58 | } | 72 | } |
| 59 | } | 73 | } |
| 60 | } | 74 | } |
| @@ -68,17 +82,21 @@ | |||
| 68 | #qr--popout>.qr--body { | 82 | #qr--popout>.qr--body { |
| 69 | >.qr--buttons { | 83 | >.qr--buttons { |
| 70 | --qr--color: transparent; | 84 | --qr--color: transparent; |
| 85 | |||
| 71 | &.qr--color { | 86 | &.qr--color { |
| 72 | background-color: var(--qr--color); | 87 | background-color: var(--qr--color); |
| 73 | } | 88 | } |
| 89 | |||
| 74 | &.qr--borderColor { | 90 | &.qr--borderColor { |
| 75 | background-color: transparent; | 91 | background-color: transparent; |
| 76 | border-left: 5px solid var(--qr--color); | 92 | border-left: 5px solid var(--qr--color); |
| 77 | border-right: 5px solid var(--qr--color); | 93 | border-right: 5px solid var(--qr--color); |
| 78 | } | 94 | } |
| 95 | |||
| 79 | &:has(.qr--buttons.qr--color) { | 96 | &:has(.qr--buttons.qr--color) { |
| 80 | margin: 5px; | 97 | margin: 5px; |
| 81 | } | 98 | } |
| 99 | |||
| 82 | margin: 0; | 100 | margin: 0; |
| 83 | padding: 0; | 101 | padding: 0; |
| 84 | display: flex; | 102 | display: flex; |
| @@ -89,6 +107,7 @@ | |||
| 89 | 107 | ||
| 90 | >.qr--buttons { | 108 | >.qr--buttons { |
| 91 | display: contents; | 109 | display: contents; |
| 110 | |||
| 92 | &.qr--color { | 111 | &.qr--color { |
| 93 | .qr--button:before { | 112 | .qr--button:before { |
| 94 | content: ''; | 113 | content: ''; |
| @@ -97,11 +116,14 @@ | |||
| 97 | inset: -5px; | 116 | inset: -5px; |
| 98 | z-index: -1; | 117 | z-index: -1; |
| 99 | } | 118 | } |
| 119 | |||
| 100 | &.qr--borderColor { | 120 | &.qr--borderColor { |
| 101 | .qr--button:before { | 121 | .qr--button:before { |
| 102 | display: none; | 122 | display: none; |
| 103 | } | 123 | } |
| 104 | &:before, &:after { | 124 | |
| 125 | &:before, | ||
| 126 | &:after { | ||
| 105 | content: ''; | 127 | content: ''; |
| 106 | width: 5px; | 128 | width: 5px; |
| 107 | background-color: var(--qr--color); | 129 | background-color: var(--qr--color); |
| @@ -118,7 +140,7 @@ | |||
| 118 | padding: 3px 5px; | 140 | padding: 3px 5px; |
| 119 | margin: 3px 0; | 141 | margin: 3px 0; |
| 120 | cursor: pointer; | 142 | cursor: pointer; |
| 121 | transition: 0.3s; | 143 | transition: var(--animation-duration-2x); |
| 122 | display: flex; | 144 | display: flex; |
| 123 | align-items: center; | 145 | align-items: center; |
| 124 | justify-content: center; | 146 | justify-content: center; |
| @@ -132,6 +154,7 @@ | |||
| 132 | .qr--hidden { | 154 | .qr--hidden { |
| 133 | display: none; | 155 | display: none; |
| 134 | } | 156 | } |
| 157 | |||
| 135 | .qr--button-icon { | 158 | .qr--button-icon { |
| 136 | margin: 0 0.5em; | 159 | margin: 0 0.5em; |
| 137 | } | 160 | } |
| @@ -274,18 +297,22 @@ | |||
| 274 | display: flex; | 297 | display: flex; |
| 275 | align-items: center; | 298 | align-items: center; |
| 276 | opacity: 0; | 299 | opacity: 0; |
| 277 | transition: 100ms; | 300 | transition: var(--animation-duration); |
| 278 | margin: -2px 0 -11px 0; | 301 | margin: -2px 0 -11px 0; |
| 279 | position: relative; | 302 | position: relative; |
| 303 | |||
| 280 | .qr--actions { | 304 | .qr--actions { |
| 281 | display: flex; | 305 | display: flex; |
| 282 | gap: 0.25em; | 306 | gap: 0.25em; |
| 283 | flex: 0 0 auto; | 307 | flex: 0 0 auto; |
| 308 | |||
| 284 | .qr--action { | 309 | .qr--action { |
| 285 | margin: 0; | 310 | margin: 0; |
| 286 | } | 311 | } |
| 287 | } | 312 | } |
| 288 | &:before, &:after { | 313 | |
| 314 | &:before, | ||
| 315 | &:after { | ||
| 289 | content: ""; | 316 | content: ""; |
| 290 | display: block; | 317 | display: block; |
| 291 | flex: 1 1 auto; | 318 | flex: 1 1 auto; |
| @@ -293,10 +320,13 @@ | |||
| 293 | margin: 0 1em; | 320 | margin: 0 1em; |
| 294 | height: 0; | 321 | height: 0; |
| 295 | } | 322 | } |
| 296 | &:hover, &:focus-within { | 323 | |
| 324 | &:hover, | ||
| 325 | &:focus-within { | ||
| 297 | opacity: 1; | 326 | opacity: 1; |
| 298 | } | 327 | } |
| 299 | } | 328 | } |
| 329 | |||
| 300 | >.qr--set-item .qr--content { | 330 | >.qr--set-item .qr--content { |
| 301 | display: flex; | 331 | display: flex; |
| 302 | flex-direction: row; | 332 | flex-direction: row; |
| @@ -336,9 +366,11 @@ | |||
| 336 | display: flex; | 366 | display: flex; |
| 337 | align-items: center; | 367 | align-items: center; |
| 338 | gap: 0.5em; | 368 | gap: 0.5em; |
| 369 | |||
| 339 | .qr--set-itemIcon:not(.fa-solid) { | 370 | .qr--set-itemIcon:not(.fa-solid) { |
| 340 | display: none; | 371 | display: none; |
| 341 | } | 372 | } |
| 373 | |||
| 342 | .qr--set-itemLabel { | 374 | .qr--set-itemLabel { |
| 343 | min-width: 24px; | 375 | min-width: 24px; |
| 344 | } | 376 | } |
| @@ -384,15 +416,16 @@ | |||
| 384 | align-items: baseline; | 416 | align-items: baseline; |
| 385 | } | 417 | } |
| 386 | } | 418 | } |
| 387 | >#qr--autoExec { | ||
| 388 | .checkbox_label { | ||
| 389 | text-wrap: nowrap; | ||
| 390 | 419 | ||
| 391 | .fa-fw { | 420 | >#qr--autoExec { |
| 392 | margin-right: 2px; | 421 | .checkbox_label { |
| 393 | } | 422 | text-wrap: nowrap; |
| 423 | |||
| 424 | .fa-fw { | ||
| 425 | margin-right: 2px; | ||
| 394 | } | 426 | } |
| 395 | } | 427 | } |
| 428 | } | ||
| 396 | } | 429 | } |
| 397 | 430 | ||
| 398 | 431 | ||
| @@ -433,65 +466,75 @@ | |||
| 433 | bottom: unset; | 466 | bottom: unset; |
| 434 | margin: unset; | 467 | margin: unset; |
| 435 | padding: 0; | 468 | padding: 0; |
| 469 | |||
| 436 | &::backdrop { | 470 | &::backdrop { |
| 437 | backdrop-filter: unset; | 471 | backdrop-filter: unset; |
| 438 | background-color: transparent; | 472 | background-color: transparent; |
| 439 | } | 473 | } |
| 474 | |||
| 440 | .popup-body { | 475 | .popup-body { |
| 441 | flex: 0 0 auto; | 476 | flex: 0 0 auto; |
| 442 | height: min-content; | 477 | height: min-content; |
| 443 | width: min-content; | 478 | width: min-content; |
| 444 | } | 479 | } |
| 480 | |||
| 445 | .popup-content { | 481 | .popup-content { |
| 446 | flex: 0 0 auto; | 482 | flex: 0 0 auto; |
| 447 | margin-top: 0; | 483 | margin-top: 0; |
| 448 | 484 | ||
| 449 | > #qr--modalEditor { | 485 | >#qr--modalEditor { |
| 450 | max-height: 50vh; | 486 | max-height: 50vh; |
| 451 | > #qr--main, | 487 | |
| 452 | > #qr--resizeHandle, | 488 | >#qr--main, |
| 453 | > #qr--qrOptions > h3, | 489 | >#qr--resizeHandle, |
| 454 | > #qr--qrOptions > #qr--modal-executeButtons, | 490 | >#qr--qrOptions>h3, |
| 455 | > #qr--qrOptions > #qr--modal-executeProgress | 491 | >#qr--qrOptions>#qr--modal-executeButtons, |
| 456 | { | 492 | >#qr--qrOptions>#qr--modal-executeProgress { |
| 457 | display: none; | 493 | display: none; |
| 458 | } | 494 | } |
| 495 | |||
| 459 | #qr--qrOptions { | 496 | #qr--qrOptions { |
| 460 | width: auto; | 497 | width: auto; |
| 461 | } | 498 | } |
| 499 | |||
| 462 | #qr--modal-debugButtons .qr--modal-debugButton#qr--modal-maximize { | 500 | #qr--modal-debugButtons .qr--modal-debugButton#qr--modal-maximize { |
| 463 | display: flex; | 501 | display: flex; |
| 464 | } | 502 | } |
| 503 | |||
| 465 | #qr--modal-debugButtons .qr--modal-debugButton#qr--modal-minimize { | 504 | #qr--modal-debugButtons .qr--modal-debugButton#qr--modal-minimize { |
| 466 | display: none; | 505 | display: none; |
| 467 | } | 506 | } |
| 507 | |||
| 468 | #qr--modal-debugState { | 508 | #qr--modal-debugState { |
| 469 | padding-top: 0; | 509 | padding-top: 0; |
| 470 | } | 510 | } |
| 471 | } | 511 | } |
| 472 | } | 512 | } |
| 473 | } | 513 | } |
| 474 | &:has(.qr--isExecuting) { | 514 | |
| 475 | .popup-controls { | 515 | &:has(.qr--isExecuting) { |
| 476 | display: none; | 516 | .popup-controls { |
| 477 | } | 517 | display: none; |
| 478 | 518 | } | |
| 479 | .qr--highlight { | 519 | |
| 480 | position: absolute; | 520 | .qr--highlight { |
| 481 | z-index: 50000; | 521 | position: absolute; |
| 482 | pointer-events: none; | 522 | z-index: 50000; |
| 483 | background-color: rgb(47 150 180 / 0.5); | 523 | pointer-events: none; |
| 484 | &.qr--unresolved { | 524 | background-color: rgb(47 150 180 / 0.5); |
| 485 | background-color: rgb(255 255 0 / 0.5); | 525 | |
| 486 | } | 526 | &.qr--unresolved { |
| 487 | } | 527 | background-color: rgb(255 255 0 / 0.5); |
| 488 | .qr--highlight-secondary { | 528 | } |
| 489 | position: absolute; | 529 | } |
| 490 | z-index: 50000; | 530 | |
| 491 | pointer-events: none; | 531 | .qr--highlight-secondary { |
| 492 | border: 3px solid red; | 532 | position: absolute; |
| 493 | } | 533 | z-index: 50000; |
| 494 | } | 534 | pointer-events: none; |
| 535 | border: 3px solid red; | ||
| 536 | } | ||
| 537 | } | ||
| 495 | 538 | ||
| 496 | .popup-content { | 539 | .popup-content { |
| 497 | display: flex; | 540 | display: flex; |
| @@ -504,36 +547,41 @@ | |||
| 504 | gap: 1em; | 547 | gap: 1em; |
| 505 | overflow: hidden; | 548 | overflow: hidden; |
| 506 | 549 | ||
| 507 | &.qr--isExecuting { | 550 | &.qr--isExecuting { |
| 508 | #qr--main > h3:first-child, | 551 | |
| 509 | #qr--main > .qr--labels, | 552 | #qr--main>h3:first-child, |
| 510 | #qr--main > .qr--modal-messageContainer > .qr--modal-editorSettings, | 553 | #qr--main>.qr--labels, |
| 511 | #qr--qrOptions > h3:first-child, | 554 | #qr--main>.qr--modal-messageContainer>.qr--modal-editorSettings, |
| 512 | #qr--qrOptions > #qr--ctxEditor, | 555 | #qr--qrOptions>h3:first-child, |
| 513 | #qr--qrOptions > .qr--ctxEditorActions, | 556 | #qr--qrOptions>#qr--ctxEditor, |
| 514 | #qr--qrOptions > .qr--ctxEditorActions + h3, | 557 | #qr--qrOptions>.qr--ctxEditorActions, |
| 515 | #qr--qrOptions > .qr--ctxEditorActions + h3 + div | 558 | #qr--qrOptions>.qr--ctxEditorActions+h3, |
| 516 | { | 559 | #qr--qrOptions>.qr--ctxEditorActions+h3+div { |
| 517 | display: none; | 560 | display: none; |
| 518 | } | 561 | } |
| 519 | #qr--main > .qr--modal-messageContainer > #qr--modal-messageHolder > #qr--modal-message { | 562 | |
| 520 | visibility: hidden; | 563 | #qr--main>.qr--modal-messageContainer>#qr--modal-messageHolder>#qr--modal-message { |
| 521 | } | 564 | visibility: hidden; |
| 522 | #qr--modal-debugButtons { | 565 | } |
| 523 | display: flex; | 566 | |
| 567 | #qr--modal-debugButtons { | ||
| 568 | display: flex; | ||
| 569 | |||
| 524 | .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { | 570 | .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { |
| 525 | cursor: not-allowed; | 571 | cursor: not-allowed; |
| 526 | opacity: 0.5; | 572 | opacity: 0.5; |
| 527 | pointer-events: none; | 573 | pointer-events: none; |
| 528 | transition: 200ms; | 574 | transition: var(--animation-duration-2x); |
| 529 | border-color: transparent; | 575 | border-color: transparent; |
| 530 | } | 576 | } |
| 531 | } | 577 | } |
| 578 | |||
| 532 | &.qr--isPaused #qr--modal-debugButtons { | 579 | &.qr--isPaused #qr--modal-debugButtons { |
| 533 | .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { | 580 | .menu_button:not(#qr--modal-minimize, #qr--modal-maximize) { |
| 534 | cursor: pointer; | 581 | cursor: pointer; |
| 535 | opacity: 1; | 582 | opacity: 1; |
| 536 | pointer-events: all; | 583 | pointer-events: all; |
| 584 | |||
| 537 | &#qr--modal-resume { | 585 | &#qr--modal-resume { |
| 538 | animation-name: qr--debugPulse; | 586 | animation-name: qr--debugPulse; |
| 539 | animation-duration: 1500ms; | 587 | animation-duration: 1500ms; |
| @@ -541,73 +589,90 @@ | |||
| 541 | animation-delay: 0s; | 589 | animation-delay: 0s; |
| 542 | animation-iteration-count: infinite; | 590 | animation-iteration-count: infinite; |
| 543 | } | 591 | } |
| 592 | |||
| 544 | &#qr--modal-resume { | 593 | &#qr--modal-resume { |
| 545 | border-color: rgb(81, 163, 81); | 594 | border-color: rgb(81, 163, 81); |
| 546 | } | 595 | } |
| 596 | |||
| 547 | &#qr--modal-step { | 597 | &#qr--modal-step { |
| 548 | border-color: var(--SmartThemeQuoteColor); | 598 | border-color: var(--SmartThemeQuoteColor); |
| 549 | } | 599 | } |
| 600 | |||
| 550 | &#qr--modal-stepInto { | 601 | &#qr--modal-stepInto { |
| 551 | border-color: var(--SmartThemeQuoteColor); | 602 | border-color: var(--SmartThemeQuoteColor); |
| 552 | } | 603 | } |
| 604 | |||
| 553 | &#qr--modal-stepOut { | 605 | &#qr--modal-stepOut { |
| 554 | border-color: var(--SmartThemeQuoteColor); | 606 | border-color: var(--SmartThemeQuoteColor); |
| 555 | } | 607 | } |
| 556 | } | 608 | } |
| 557 | } | 609 | } |
| 558 | #qr--resizeHandle { | 610 | |
| 559 | width: 6px; | 611 | #qr--resizeHandle { |
| 560 | background-color: var(--SmartThemeBorderColor); | 612 | width: 6px; |
| 561 | border: 2px solid var(--SmartThemeBlurTintColor); | 613 | background-color: var(--SmartThemeBorderColor); |
| 562 | transition: border-color 200ms, background-color 200ms; | 614 | border: 2px solid var(--SmartThemeBlurTintColor); |
| 563 | cursor: w-resize; | 615 | transition: border-color var(--animation-duration-2x), background-color var(--animation-duration-2x); |
| 564 | &:hover { | 616 | cursor: w-resize; |
| 565 | background-color: var(--SmartThemeQuoteColor); | 617 | |
| 566 | border-color: var(--SmartThemeQuoteColor); | 618 | &:hover { |
| 567 | } | 619 | background-color: var(--SmartThemeQuoteColor); |
| 568 | } | 620 | border-color: var(--SmartThemeQuoteColor); |
| 569 | #qr--qrOptions { | 621 | } |
| 570 | width: var(--width, auto); | 622 | } |
| 571 | } | 623 | |
| 572 | } | 624 | #qr--qrOptions { |
| 573 | 625 | width: var(--width, auto); | |
| 574 | > #qr--main { | 626 | } |
| 575 | flex: 1 1 auto; | 627 | } |
| 576 | display: flex; | 628 | |
| 577 | flex-direction: column; | 629 | >#qr--main { |
| 578 | overflow: hidden; | 630 | flex: 1 1 auto; |
| 579 | > .qr--labels { | 631 | display: flex; |
| 580 | flex: 0 0 auto; | 632 | flex-direction: column; |
| 581 | display: flex; | 633 | overflow: hidden; |
| 582 | flex-direction: row; | 634 | |
| 583 | gap: 0.5em; | 635 | >.qr--labels { |
| 584 | padding: 1px; | 636 | flex: 0 0 auto; |
| 585 | > label, > .label { | 637 | display: flex; |
| 586 | flex: 1 1 1px; | 638 | flex-direction: row; |
| 587 | display: flex; | 639 | gap: 0.5em; |
| 588 | flex-direction: column; | 640 | padding: 1px; |
| 641 | |||
| 642 | >label, | ||
| 643 | >.label { | ||
| 644 | flex: 1 1 1px; | ||
| 645 | display: flex; | ||
| 646 | flex-direction: column; | ||
| 589 | position: relative; | 647 | position: relative; |
| 648 | |||
| 590 | &.qr--fit { | 649 | &.qr--fit { |
| 591 | flex: 0 0 auto; | 650 | flex: 0 0 auto; |
| 592 | justify-content: center; | 651 | justify-content: center; |
| 593 | } | 652 | } |
| 653 | |||
| 594 | .qr--inputGroup { | 654 | .qr--inputGroup { |
| 595 | display: flex; | 655 | display: flex; |
| 596 | align-items: baseline; | 656 | align-items: baseline; |
| 597 | gap: 0.5em; | 657 | gap: 0.5em; |
| 658 | |||
| 598 | input { | 659 | input { |
| 599 | flex: 1 1 auto; | 660 | flex: 1 1 auto; |
| 600 | } | 661 | } |
| 601 | } | 662 | } |
| 602 | .qr--labelText { | 663 | |
| 603 | flex: 1 1 auto; | 664 | .qr--labelText { |
| 604 | } | 665 | flex: 1 1 auto; |
| 605 | .qr--labelHint { | 666 | } |
| 606 | flex: 1 1 auto; | 667 | |
| 607 | } | 668 | .qr--labelHint { |
| 608 | input { | 669 | flex: 1 1 auto; |
| 609 | flex: 0 0 auto; | 670 | } |
| 610 | } | 671 | |
| 672 | input { | ||
| 673 | flex: 0 0 auto; | ||
| 674 | } | ||
| 675 | |||
| 611 | .qr--modal-switcherList { | 676 | .qr--modal-switcherList { |
| 612 | background-color: var(--stcdx--bgColor); | 677 | background-color: var(--stcdx--bgColor); |
| 613 | border: 1px solid var(--SmartThemeBorderColor); | 678 | border: 1px solid var(--SmartThemeBorderColor); |
| @@ -625,25 +690,32 @@ | |||
| 625 | list-style: none; | 690 | list-style: none; |
| 626 | z-index: 40000; | 691 | z-index: 40000; |
| 627 | max-width: 100%; | 692 | max-width: 100%; |
| 693 | |||
| 628 | .qr--modal-switcherItem { | 694 | .qr--modal-switcherItem { |
| 629 | display: flex; | 695 | display: flex; |
| 630 | gap: 1em; | 696 | gap: 1em; |
| 631 | text-align: left; | 697 | text-align: left; |
| 632 | opacity: 0.75; | 698 | opacity: 0.75; |
| 633 | transition: 200ms; | 699 | transition: var(--animation-duration-2x); |
| 634 | cursor: pointer; | 700 | cursor: pointer; |
| 701 | |||
| 635 | &:hover { | 702 | &:hover { |
| 636 | opacity: 1; | 703 | opacity: 1; |
| 637 | } | 704 | } |
| 705 | |||
| 638 | &.qr--current { | 706 | &.qr--current { |
| 639 | opacity: 1; | 707 | opacity: 1; |
| 640 | .qr--label, .qr--id { | 708 | |
| 709 | .qr--label, | ||
| 710 | .qr--id { | ||
| 641 | font-weight: bold; | 711 | font-weight: bold; |
| 642 | } | 712 | } |
| 643 | } | 713 | } |
| 644 | } | 714 | } |
| 715 | |||
| 645 | .qr--label { | 716 | .qr--label { |
| 646 | white-space: nowrap; | 717 | white-space: nowrap; |
| 718 | |||
| 647 | .menu_button { | 719 | .menu_button { |
| 648 | display: inline-block; | 720 | display: inline-block; |
| 649 | height: min-content; | 721 | height: min-content; |
| @@ -651,11 +723,19 @@ | |||
| 651 | margin: 0 0.5em 0 0; | 723 | margin: 0 0.5em 0 0; |
| 652 | } | 724 | } |
| 653 | } | 725 | } |
| 726 | |||
| 654 | .qr--id { | 727 | .qr--id { |
| 655 | opacity: 0.5; | 728 | opacity: 0.5; |
| 656 | &:before { content: "["; } | 729 | |
| 657 | &:after { content: "]"; } | 730 | &:before { |
| 731 | content: "["; | ||
| 732 | } | ||
| 733 | |||
| 734 | &:after { | ||
| 735 | content: "]"; | ||
| 736 | } | ||
| 658 | } | 737 | } |
| 738 | |||
| 659 | .qr--message { | 739 | .qr--message { |
| 660 | height: 1lh; | 740 | height: 1lh; |
| 661 | overflow: hidden; | 741 | overflow: hidden; |
| @@ -664,102 +744,124 @@ | |||
| 664 | opacity: 0.5; | 744 | opacity: 0.5; |
| 665 | } | 745 | } |
| 666 | } | 746 | } |
| 667 | } | 747 | } |
| 668 | } | 748 | } |
| 669 | > .qr--modal-messageContainer { | 749 | |
| 670 | flex: 1 1 auto; | 750 | >.qr--modal-messageContainer { |
| 671 | display: flex; | 751 | flex: 1 1 auto; |
| 672 | flex-direction: column; | 752 | display: flex; |
| 673 | overflow: hidden; | 753 | flex-direction: column; |
| 674 | > .qr--modal-editorSettings { | 754 | overflow: hidden; |
| 675 | display: flex; | 755 | |
| 756 | >.qr--modal-editorSettings { | ||
| 757 | display: flex; | ||
| 676 | flex-wrap: wrap; | 758 | flex-wrap: wrap; |
| 677 | flex-direction: row; | 759 | flex-direction: row; |
| 678 | column-gap: 1em; | 760 | column-gap: 1em; |
| 679 | color: var(--grey70); | 761 | color: var(--grey70); |
| 680 | font-size: smaller; | 762 | font-size: smaller; |
| 681 | align-items: baseline; | 763 | align-items: baseline; |
| 682 | > .checkbox_label { | 764 | |
| 683 | white-space: nowrap; | 765 | >.checkbox_label { |
| 684 | > input { | 766 | white-space: nowrap; |
| 685 | font-size: inherit; | 767 | |
| 686 | } | 768 | >input { |
| 687 | } | 769 | font-size: inherit; |
| 688 | } | 770 | } |
| 689 | > #qr--modal-messageHolder { | 771 | } |
| 690 | flex: 1 1 auto; | 772 | } |
| 691 | display: grid; | 773 | |
| 692 | text-align: left; | 774 | >#qr--modal-messageHolder { |
| 693 | overflow: hidden; | 775 | flex: 1 1 auto; |
| 694 | &.qr--noSyntax { | 776 | display: grid; |
| 695 | > #qr--modal-messageSyntax { | 777 | text-align: left; |
| 696 | display: none; | 778 | overflow: hidden; |
| 697 | } | 779 | |
| 698 | > #qr--modal-message { | 780 | &.qr--noSyntax { |
| 699 | background-color: var(--ac-style-color-background); | 781 | >#qr--modal-messageSyntax { |
| 700 | color: var(--ac-style-color-text); | 782 | display: none; |
| 701 | &::-webkit-scrollbar, &::-webkit-scrollbar-thumb { | 783 | } |
| 784 | |||
| 785 | >#qr--modal-message { | ||
| 786 | background-color: var(--ac-style-color-background); | ||
| 787 | color: var(--ac-style-color-text); | ||
| 788 | |||
| 789 | &::-webkit-scrollbar, | ||
| 790 | &::-webkit-scrollbar-thumb { | ||
| 702 | visibility: visible; | 791 | visibility: visible; |
| 703 | cursor: unset; | 792 | cursor: unset; |
| 704 | } | 793 | } |
| 705 | &::selection { | 794 | |
| 706 | color: unset; | 795 | &::selection { |
| 707 | background-color: rgba(108 171 251 / 0.25); | 796 | color: unset; |
| 708 | @supports (color: rgb(from white r g b / 0.25)) { | 797 | background-color: rgba(108 171 251 / 0.25); |
| 709 | background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25); | 798 | |
| 710 | } | 799 | @supports (color: rgb(from white r g b / 0.25)) { |
| 711 | } | 800 | background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25); |
| 712 | } | 801 | } |
| 713 | } | 802 | } |
| 714 | > #qr--modal-messageSyntax { | 803 | } |
| 715 | grid-column: 1; | 804 | } |
| 716 | grid-row: 1; | 805 | |
| 717 | padding: 0; | 806 | >#qr--modal-messageSyntax { |
| 718 | margin: 0; | 807 | grid-column: 1; |
| 719 | border: none; | 808 | grid-row: 1; |
| 720 | overflow: hidden; | 809 | padding: 0; |
| 721 | min-width: 100%; | 810 | margin: 0; |
| 722 | width: 0; | 811 | border: none; |
| 723 | > #qr--modal-messageSyntaxInner { | 812 | overflow: hidden; |
| 724 | height: 100%; | 813 | min-width: 100%; |
| 725 | } | 814 | width: 0; |
| 726 | } | 815 | |
| 727 | > #qr--modal-message { | 816 | >#qr--modal-messageSyntaxInner { |
| 728 | background-color: transparent; | 817 | height: 100%; |
| 729 | color: transparent; | 818 | } |
| 730 | grid-column: 1; | 819 | } |
| 731 | grid-row: 1; | 820 | |
| 732 | caret-color: var(--ac-style-color-text); | 821 | >#qr--modal-message { |
| 733 | overflow: auto; | 822 | background-color: transparent; |
| 734 | &::-webkit-scrollbar, &::-webkit-scrollbar-thumb { | 823 | color: transparent; |
| 735 | visibility: hidden; | 824 | grid-column: 1; |
| 736 | cursor: default; | 825 | grid-row: 1; |
| 737 | } | 826 | caret-color: var(--ac-style-color-text); |
| 738 | &::selection { | 827 | overflow: auto; |
| 739 | color: transparent; | 828 | |
| 740 | background-color: rgba(108 171 251 / 0.25); | 829 | &::-webkit-scrollbar, |
| 741 | @supports (color: rgb(from white r g b / 0.25)) { | 830 | &::-webkit-scrollbar-thumb { |
| 742 | background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25); | 831 | visibility: hidden; |
| 743 | } | 832 | cursor: default; |
| 744 | } | 833 | } |
| 745 | } | 834 | |
| 746 | #qr--modal-message, #qr--modal-messageSyntaxInner { | 835 | &::selection { |
| 747 | font-family: var(--monoFontFamily); | 836 | color: transparent; |
| 748 | padding: 0.75em; | 837 | background-color: rgba(108 171 251 / 0.25); |
| 749 | margin: 0; | 838 | |
| 750 | resize: none; | 839 | @supports (color: rgb(from white r g b / 0.25)) { |
| 751 | line-height: 1.2; | 840 | background-color: rgb(from var(--ac-style-color-matchedText) r g b / 0.25); |
| 752 | border: 1px solid var(--SmartThemeBorderColor); | 841 | } |
| 753 | border-radius: 5px; | 842 | } |
| 754 | position: relative; | 843 | } |
| 755 | } | 844 | |
| 756 | } | 845 | #qr--modal-message, |
| 757 | } | 846 | #qr--modal-messageSyntaxInner { |
| 758 | } | 847 | font-family: var(--monoFontFamily); |
| 848 | padding: 0.75em; | ||
| 849 | margin: 0; | ||
| 850 | resize: none; | ||
| 851 | line-height: 1.2; | ||
| 852 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 853 | border-radius: 5px; | ||
| 854 | position: relative; | ||
| 855 | } | ||
| 856 | } | ||
| 857 | } | ||
| 858 | } | ||
| 859 | |||
| 759 | #qr--modal-icon { | 860 | #qr--modal-icon { |
| 760 | height: 100%; | 861 | height: 100%; |
| 761 | aspect-ratio: 1 / 1; | 862 | aspect-ratio: 1 / 1; |
| 762 | } | 863 | } |
| 864 | |||
| 763 | #qr--modal-executeButtons { | 865 | #qr--modal-executeButtons { |
| 764 | display: flex; | 866 | display: flex; |
| 765 | gap: 1em; | 867 | gap: 1em; |
| @@ -778,7 +880,7 @@ | |||
| 778 | } | 880 | } |
| 779 | 881 | ||
| 780 | #qr--modal-execute { | 882 | #qr--modal-execute { |
| 781 | transition: 200ms; | 883 | transition: var(--animation-duration-2x); |
| 782 | filter: grayscale(0); | 884 | filter: grayscale(0); |
| 783 | 885 | ||
| 784 | &.qr--busy { | 886 | &.qr--busy { |
| @@ -819,16 +921,20 @@ | |||
| 819 | border-color: rgb(215, 136, 114); | 921 | border-color: rgb(215, 136, 114); |
| 820 | } | 922 | } |
| 821 | } | 923 | } |
| 822 | #qr--modal-debugButtons { | 924 | |
| 823 | display: none; | 925 | #qr--modal-debugButtons { |
| 824 | gap: 1em; | 926 | display: none; |
| 825 | .qr--modal-debugButton { | 927 | gap: 1em; |
| 826 | aspect-ratio: 1.25 / 1; | 928 | |
| 827 | width: 2.25em; | 929 | .qr--modal-debugButton { |
| 930 | aspect-ratio: 1.25 / 1; | ||
| 931 | width: 2.25em; | ||
| 828 | position: relative; | 932 | position: relative; |
| 933 | |||
| 829 | &:not(.fa-solid) { | 934 | &:not(.fa-solid) { |
| 830 | border-width: 1px; | 935 | border-width: 1px; |
| 831 | border-style: solid; | 936 | border-style: solid; |
| 937 | |||
| 832 | &:after { | 938 | &:after { |
| 833 | content: ''; | 939 | content: ''; |
| 834 | position: absolute; | 940 | position: absolute; |
| @@ -839,23 +945,28 @@ | |||
| 839 | mask-repeat: no-repeat; | 945 | mask-repeat: no-repeat; |
| 840 | } | 946 | } |
| 841 | } | 947 | } |
| 948 | |||
| 842 | &#qr--modal-resume:after { | 949 | &#qr--modal-resume:after { |
| 843 | mask-image: url('/img/step-resume.svg'); | 950 | mask-image: url('/img/step-resume.svg'); |
| 844 | } | 951 | } |
| 952 | |||
| 845 | &#qr--modal-step:after { | 953 | &#qr--modal-step:after { |
| 846 | mask-image: url('/img/step-over.svg'); | 954 | mask-image: url('/img/step-over.svg'); |
| 847 | } | 955 | } |
| 956 | |||
| 848 | &#qr--modal-stepInto:after { | 957 | &#qr--modal-stepInto:after { |
| 849 | mask-image: url('/img/step-into.svg'); | 958 | mask-image: url('/img/step-into.svg'); |
| 850 | } | 959 | } |
| 960 | |||
| 851 | &#qr--modal-stepOut:after { | 961 | &#qr--modal-stepOut:after { |
| 852 | mask-image: url('/img/step-out.svg'); | 962 | mask-image: url('/img/step-out.svg'); |
| 853 | } | 963 | } |
| 964 | |||
| 854 | &#qr--modal-maximize { | 965 | &#qr--modal-maximize { |
| 855 | display: none; | 966 | display: none; |
| 856 | } | 967 | } |
| 857 | } | 968 | } |
| 858 | } | 969 | } |
| 859 | 970 | ||
| 860 | #qr--modal-send_textarea { | 971 | #qr--modal-send_textarea { |
| 861 | flex: 0 0 auto; | 972 | flex: 0 0 auto; |
| @@ -879,7 +990,7 @@ | |||
| 879 | position: absolute; | 990 | position: absolute; |
| 880 | inset: 0; | 991 | inset: 0; |
| 881 | right: calc(100% - var(--prog) * 1%); | 992 | right: calc(100% - var(--prog) * 1%); |
| 882 | transition: 200ms; | 993 | transition: var(--animation-duration-2x); |
| 883 | } | 994 | } |
| 884 | 995 | ||
| 885 | &.qr--paused:after { | 996 | &.qr--paused:after { |
| @@ -939,135 +1050,180 @@ | |||
| 939 | overflow: auto; | 1050 | overflow: auto; |
| 940 | min-width: 100%; | 1051 | min-width: 100%; |
| 941 | width: 0; | 1052 | width: 0; |
| 942 | white-space: pre-wrap; | 1053 | white-space: pre-wrap; |
| 943 | } | 1054 | } |
| 944 | #qr--modal-debugState { | 1055 | |
| 945 | display: none; | 1056 | #qr--modal-debugState { |
| 946 | &.qr--active { | 1057 | display: none; |
| 947 | display: block; | 1058 | |
| 948 | } | 1059 | &.qr--active { |
| 949 | text-align: left; | 1060 | display: block; |
| 950 | font-size: smaller; | 1061 | } |
| 951 | font-family: var(--monoFontFamily); | 1062 | |
| 952 | // background-color: rgb(146, 190, 252); | 1063 | text-align: left; |
| 953 | color: white; | 1064 | font-size: smaller; |
| 954 | padding: 0.5em 0; | 1065 | font-family: var(--monoFontFamily); |
| 955 | overflow: auto; | 1066 | // background-color: rgb(146, 190, 252); |
| 956 | min-width: 100%; | 1067 | color: white; |
| 957 | width: 0; | 1068 | padding: 0.5em 0; |
| 958 | white-space: pre-wrap; | 1069 | overflow: auto; |
| 959 | 1070 | min-width: 100%; | |
| 960 | .qr--scope { | 1071 | width: 0; |
| 961 | display: grid; | 1072 | white-space: pre-wrap; |
| 962 | grid-template-columns: 0fr 1fr 1fr; | 1073 | |
| 963 | column-gap: 0em; | 1074 | .qr--scope { |
| 964 | .qr--title { | 1075 | display: grid; |
| 965 | grid-column: 1 / 4; | 1076 | grid-template-columns: 0fr 1fr 1fr; |
| 966 | font-weight: bold; | 1077 | column-gap: 0em; |
| 967 | font-family: var(--mainFontFamily); | 1078 | |
| 968 | background-color: var(--black50a); | 1079 | .qr--title { |
| 969 | padding: 0.25em; | 1080 | grid-column: 1 / 4; |
| 970 | margin-top: 0.5em; | 1081 | font-weight: bold; |
| 971 | } | 1082 | font-family: var(--mainFontFamily); |
| 972 | .qr--var, .qr--macro, .qr--pipe { | 1083 | background-color: var(--black50a); |
| 973 | display: contents; | 1084 | padding: 0.25em; |
| 974 | &:nth-child(2n + 1) { | 1085 | margin-top: 0.5em; |
| 975 | .qr--key, .qr--val { | 1086 | } |
| 976 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.25); | 1087 | |
| 977 | } | 1088 | .qr--var, |
| 978 | .qr--val { | 1089 | .qr--macro, |
| 979 | &:nth-child(2n) { | 1090 | .qr--pipe { |
| 980 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.125); | 1091 | display: contents; |
| 981 | } | 1092 | |
| 982 | &:hover { | 1093 | &:nth-child(2n + 1) { |
| 983 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.5); | 1094 | |
| 984 | } | 1095 | .qr--key, |
| 985 | } | 1096 | .qr--val { |
| 986 | } | 1097 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.25); |
| 987 | &:nth-child(2n) { | 1098 | } |
| 988 | .qr--val { | 1099 | |
| 989 | &:nth-child(2n) { | 1100 | .qr--val { |
| 990 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.0625); | 1101 | &:nth-child(2n) { |
| 991 | } | 1102 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.125); |
| 992 | &:hover { | 1103 | } |
| 993 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.5); | 1104 | |
| 994 | } | 1105 | &:hover { |
| 995 | } | 1106 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.5); |
| 996 | } | 1107 | } |
| 997 | &.qr--isHidden { | 1108 | } |
| 998 | .qr--key, .qr--val { | 1109 | } |
| 999 | opacity: 0.5; | 1110 | |
| 1000 | } | 1111 | &:nth-child(2n) { |
| 1001 | } | 1112 | .qr--val { |
| 1002 | .qr--val { | 1113 | &:nth-child(2n) { |
| 1003 | grid-column: 2 / 4; | 1114 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.0625); |
| 1004 | &.qr--singleCol { | 1115 | } |
| 1005 | grid-column: unset; | 1116 | |
| 1006 | } | 1117 | &:hover { |
| 1007 | &.qr--simple { | 1118 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.5); |
| 1008 | &:before, &:after { | 1119 | } |
| 1009 | content: '"'; | 1120 | } |
| 1010 | color: var(--SmartThemeQuoteColor); | 1121 | } |
| 1011 | } | 1122 | |
| 1012 | } | 1123 | &.qr--isHidden { |
| 1013 | &.qr--unresolved { | 1124 | |
| 1014 | &:after { | 1125 | .qr--key, |
| 1015 | content: '-UNRESOLVED-'; | 1126 | .qr--val { |
| 1016 | font-style: italic; | 1127 | opacity: 0.5; |
| 1017 | color: var(--SmartThemeQuoteColor); | 1128 | } |
| 1018 | } | 1129 | } |
| 1019 | } | 1130 | |
| 1020 | } | 1131 | .qr--val { |
| 1021 | } | 1132 | grid-column: 2 / 4; |
| 1022 | .qr--key { | 1133 | |
| 1023 | margin-left: 0.5em; | 1134 | &.qr--singleCol { |
| 1024 | padding-right: 1em; | 1135 | grid-column: unset; |
| 1025 | &:after { content: ": "; } | 1136 | } |
| 1026 | } | 1137 | |
| 1027 | .qr--pipe, .qr--macro { | 1138 | &.qr--simple { |
| 1028 | > .qr--key { | 1139 | |
| 1029 | &:before { content: "{{"; } | 1140 | &:before, |
| 1030 | &:after { content: "}}: "; } | 1141 | &:after { |
| 1031 | } | 1142 | content: '"'; |
| 1032 | } | 1143 | color: var(--SmartThemeQuoteColor); |
| 1033 | .qr--scope { | 1144 | } |
| 1034 | display: contents; | 1145 | } |
| 1035 | .qr--pipe { | 1146 | |
| 1036 | .qr--key, .qr--val { | 1147 | &.qr--unresolved { |
| 1037 | opacity: 0.5; | 1148 | &:after { |
| 1038 | } | 1149 | content: '-UNRESOLVED-'; |
| 1039 | } | 1150 | font-style: italic; |
| 1040 | } | 1151 | color: var(--SmartThemeQuoteColor); |
| 1041 | } | 1152 | } |
| 1042 | 1153 | } | |
| 1043 | .qr--stack { | 1154 | } |
| 1155 | } | ||
| 1156 | |||
| 1157 | .qr--key { | ||
| 1158 | margin-left: 0.5em; | ||
| 1159 | padding-right: 1em; | ||
| 1160 | |||
| 1161 | &:after { | ||
| 1162 | content: ": "; | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | .qr--pipe, | ||
| 1167 | .qr--macro { | ||
| 1168 | >.qr--key { | ||
| 1169 | &:before { | ||
| 1170 | content: "{{"; | ||
| 1171 | } | ||
| 1172 | |||
| 1173 | &:after { | ||
| 1174 | content: "}}: "; | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | } | ||
| 1178 | |||
| 1179 | .qr--scope { | ||
| 1180 | display: contents; | ||
| 1181 | |||
| 1182 | .qr--pipe { | ||
| 1183 | |||
| 1184 | .qr--key, | ||
| 1185 | .qr--val { | ||
| 1186 | opacity: 0.5; | ||
| 1187 | } | ||
| 1188 | } | ||
| 1189 | } | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | .qr--stack { | ||
| 1044 | display: grid; | 1193 | display: grid; |
| 1045 | grid-template-columns: 1fr 0fr; | 1194 | grid-template-columns: 1fr 0fr; |
| 1046 | .qr--title { | 1195 | |
| 1047 | grid-column: 1 / 3; | 1196 | .qr--title { |
| 1048 | font-weight: bold; | 1197 | grid-column: 1 / 3; |
| 1049 | font-family: var(--mainFontFamily); | 1198 | font-weight: bold; |
| 1050 | background-color: var(--black50a); | 1199 | font-family: var(--mainFontFamily); |
| 1051 | padding: 0.25em; | 1200 | background-color: var(--black50a); |
| 1052 | margin-top: 1em; | 1201 | padding: 0.25em; |
| 1053 | } | 1202 | margin-top: 1em; |
| 1054 | .qr--item { | 1203 | } |
| 1204 | |||
| 1205 | .qr--item { | ||
| 1055 | display: contents; | 1206 | display: contents; |
| 1056 | &:nth-child(2n + 1) { | 1207 | |
| 1057 | .qr--name, .qr--source { | 1208 | &:nth-child(2n + 1) { |
| 1209 | |||
| 1210 | .qr--name, | ||
| 1211 | .qr--source { | ||
| 1058 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.25); | 1212 | background-color: rgb(from var(--SmartThemeEmColor) r g b / 0.25); |
| 1059 | } | 1213 | } |
| 1060 | } | 1214 | } |
| 1215 | |||
| 1061 | .qr--name { | 1216 | .qr--name { |
| 1062 | margin-left: 0.5em; | 1217 | margin-left: 0.5em; |
| 1063 | } | 1218 | } |
| 1219 | |||
| 1064 | .qr--source { | 1220 | .qr--source { |
| 1065 | opacity: 0.5; | 1221 | opacity: 0.5; |
| 1066 | text-align: right; | 1222 | text-align: right; |
| 1067 | white-space: nowrap; | 1223 | white-space: nowrap; |
| 1068 | } | 1224 | } |
| 1069 | } | 1225 | } |
| 1070 | } | 1226 | } |
| 1071 | } | 1227 | } |
| 1072 | } | 1228 | } |
| 1073 | } | 1229 | } |
| @@ -1086,6 +1242,7 @@ | |||
| 1086 | } | 1242 | } |
| 1087 | 1243 | ||
| 1088 | @keyframes qr--debugPulse { | 1244 | @keyframes qr--debugPulse { |
| 1245 | |||
| 1089 | 0%, | 1246 | 0%, |
| 1090 | 100% { | 1247 | 100% { |
| 1091 | border-color: rgb(81, 163, 81); | 1248 | border-color: rgb(81, 163, 81); |
| @@ -1097,10 +1254,11 @@ | |||
| 1097 | } | 1254 | } |
| 1098 | 1255 | ||
| 1099 | .popup.qr--hide { | 1256 | .popup.qr--hide { |
| 1100 | opacity: 0 !important; | 1257 | opacity: 0 !important; |
| 1101 | &::backdrop { | 1258 | |
| 1102 | opacity: 0 !important; | 1259 | &::backdrop { |
| 1103 | } | 1260 | opacity: 0 !important; |
| 1261 | } | ||
| 1104 | } | 1262 | } |
| 1105 | 1263 | ||
| 1106 | .popup.qr--hide::backdrop { | 1264 | .popup.qr--hide::backdrop { |
| @@ -1110,50 +1268,56 @@ | |||
| 1110 | 1268 | ||
| 1111 | 1269 | ||
| 1112 | .popup:has(.qr--transferModal) { | 1270 | .popup:has(.qr--transferModal) { |
| 1113 | .popup-button-ok { | 1271 | .popup-button-ok { |
| 1114 | &:after { | 1272 | &:after { |
| 1115 | content: 'Transfer'; | 1273 | content: 'Transfer'; |
| 1116 | height: 0; | 1274 | height: 0; |
| 1117 | overflow: hidden; | 1275 | overflow: hidden; |
| 1118 | font-weight: bold; | 1276 | font-weight: bold; |
| 1119 | } | 1277 | } |
| 1120 | display: flex; | 1278 | |
| 1121 | align-items: center; | 1279 | display: flex; |
| 1122 | flex-direction: column; | 1280 | align-items: center; |
| 1123 | white-space: pre; | 1281 | flex-direction: column; |
| 1124 | font-weight: normal; | 1282 | white-space: pre; |
| 1125 | box-shadow: 0 0 0; | 1283 | font-weight: normal; |
| 1126 | transition: 200ms; | 1284 | box-shadow: 0 0 0; |
| 1127 | } | 1285 | transition: var(--animation-duration-2x); |
| 1128 | .qr--copy { | 1286 | } |
| 1129 | &:after { | 1287 | |
| 1130 | content: 'Copy'; | 1288 | .qr--copy { |
| 1131 | height: 0; | 1289 | &:after { |
| 1132 | overflow: hidden; | 1290 | content: 'Copy'; |
| 1133 | font-weight: bold; | 1291 | height: 0; |
| 1134 | } | 1292 | overflow: hidden; |
| 1135 | display: flex; | 1293 | font-weight: bold; |
| 1136 | align-items: center; | 1294 | } |
| 1137 | flex-direction: column; | 1295 | |
| 1138 | white-space: pre; | 1296 | display: flex; |
| 1139 | font-weight: normal; | 1297 | align-items: center; |
| 1140 | box-shadow: 0 0 0; | 1298 | flex-direction: column; |
| 1141 | transition: 200ms; | 1299 | white-space: pre; |
| 1142 | } | 1300 | font-weight: normal; |
| 1143 | &:has(.qr--transferSelect:focus) { | 1301 | box-shadow: 0 0 0; |
| 1144 | .popup-button-ok { | 1302 | transition: var(--animation-duration-2x); |
| 1145 | font-weight: bold; | 1303 | } |
| 1146 | box-shadow: 0 0 10px; | 1304 | |
| 1147 | } | 1305 | &:has(.qr--transferSelect:focus) { |
| 1148 | &.qr--isCopy { | 1306 | .popup-button-ok { |
| 1149 | .popup-button-ok { | 1307 | font-weight: bold; |
| 1150 | font-weight: normal; | 1308 | box-shadow: 0 0 10px; |
| 1151 | box-shadow: 0 0 0; | 1309 | } |
| 1152 | } | 1310 | |
| 1153 | .qr--copy { | 1311 | &.qr--isCopy { |
| 1154 | font-weight: bold; | 1312 | .popup-button-ok { |
| 1155 | box-shadow: 0 0 10px; | 1313 | font-weight: normal; |
| 1156 | } | 1314 | box-shadow: 0 0 0; |
| 1157 | } | 1315 | } |
| 1158 | } | 1316 | |
| 1317 | .qr--copy { | ||
| 1318 | font-weight: bold; | ||
| 1319 | box-shadow: 0 0 10px; | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | } | ||
| 1159 | } | 1323 | } |
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #scoped_scripts_block { | 25 | #scoped_scripts_block { |
| 26 | opacity: 1; | 26 | opacity: 1; |
| 27 | transition: opacity 0.2s ease-in-out; | 27 | transition: opacity var(--animation-duration-2x) ease-in-out; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | #scoped_scripts_block .move_to_scoped { | 30 | #scoped_scripts_block .move_to_scoped { |
| @@ -78,7 +78,7 @@ input.enable_scoped { | |||
| 78 | cursor: pointer; | 78 | cursor: pointer; |
| 79 | opacity: 0.5; | 79 | opacity: 0.5; |
| 80 | filter: grayscale(0.5); | 80 | filter: grayscale(0.5); |
| 81 | transition: opacity 0.2s ease-in-out; | 81 | transition: opacity var(--animation-duration-2x) ease-in-out; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | .regex-toggle-off:hover { | 84 | .regex-toggle-off:hover { |
| @@ -25,7 +25,7 @@ | |||
| 25 | outline: none; | 25 | outline: none; |
| 26 | border: none; | 26 | border: none; |
| 27 | cursor: pointer; | 27 | cursor: pointer; |
| 28 | transition: 0.3s; | 28 | transition: var(--animation-duration-2x); |
| 29 | opacity: 0.7; | 29 | opacity: 0.7; |
| 30 | align-items: center; | 30 | align-items: center; |
| 31 | justify-content: center; | 31 | justify-content: center; |
| @@ -2153,20 +2153,22 @@ export function getFreeName(name, list, numberFormatter = (n) => ` #${n}`) { | |||
| 2153 | */ | 2153 | */ |
| 2154 | export function toggleDrawer(drawer, expand = true) { | 2154 | export function toggleDrawer(drawer, expand = true) { |
| 2155 | /** @type {HTMLElement} */ | 2155 | /** @type {HTMLElement} */ |
| 2156 | const icon = drawer.querySelector('.inline-drawer-icon'); | 2156 | const icon = drawer.querySelector(':scope > .inline-drawer-header .inline-drawer-icon'); |
| 2157 | /** @type {HTMLElement} */ | 2157 | /** @type {HTMLElement} */ |
| 2158 | const content = drawer.querySelector('.inline-drawer-content'); | 2158 | const content = drawer.querySelector(':scope > .inline-drawer-content'); |
| 2159 | 2159 | ||
| 2160 | if (expand) { | 2160 | if (expand) { |
| 2161 | icon.classList.remove('up', 'fa-circle-chevron-up'); | ||
| 2162 | icon.classList.add('down', 'fa-circle-chevron-down'); | ||
| 2163 | content.style.display = 'block'; | ||
| 2164 | } else { | ||
| 2165 | icon.classList.remove('down', 'fa-circle-chevron-down'); | 2161 | icon.classList.remove('down', 'fa-circle-chevron-down'); |
| 2166 | icon.classList.add('up', 'fa-circle-chevron-up'); | 2162 | icon.classList.add('up', 'fa-circle-chevron-up'); |
| 2163 | content.style.display = 'block'; | ||
| 2164 | } else { | ||
| 2165 | icon.classList.remove('up', 'fa-circle-chevron-up'); | ||
| 2166 | icon.classList.add('down', 'fa-circle-chevron-down'); | ||
| 2167 | content.style.display = 'none'; | 2167 | content.style.display = 'none'; |
| 2168 | } | 2168 | } |
| 2169 | 2169 | ||
| 2170 | drawer.dispatchEvent(new CustomEvent('inline-drawer-toggle', { bubbles: true })); | ||
| 2171 | |||
| 2170 | // Set the height of "autoSetHeight" textareas within the inline-drawer to their scroll height | 2172 | // Set the height of "autoSetHeight" textareas within the inline-drawer to their scroll height |
| 2171 | if (!CSS.supports('field-sizing', 'content')) { | 2173 | if (!CSS.supports('field-sizing', 'content')) { |
| 2172 | content.querySelectorAll('textarea.autoSetHeight').forEach(resetScrollHeight); | 2174 | content.querySelectorAll('textarea.autoSetHeight').forEach(resetScrollHeight); |
| @@ -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 = []; |
| @@ -85,6 +86,7 @@ const saveSettingsDebounced = debounce(() => { | |||
| 85 | }, debounce_timeout.relaxed); | 86 | }, debounce_timeout.relaxed); |
| 86 | const sortFn = (a, b) => b.order - a.order; | 87 | const sortFn = (a, b) => b.order - a.order; |
| 87 | let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); }; | 88 | let updateEditor = (navigation, flashOnNav = true) => { console.debug('Triggered WI navigation', navigation, flashOnNav); }; |
| 89 | let isSaveWorldInfoDisabled = false; | ||
| 88 | 90 | ||
| 89 | // Do not optimize. updateEditor is a function that is updated by the displayWorldEntries with new data. | 91 | // Do not optimize. updateEditor is a function that is updated by the displayWorldEntries with new data. |
| 90 | export const worldInfoFilter = new FilterHelper(() => updateEditor()); | 92 | export const worldInfoFilter = new FilterHelper(() => updateEditor()); |
| @@ -965,6 +967,7 @@ export function reloadEditor(file, loadIfNotSelected = false) { | |||
| 965 | } | 967 | } |
| 966 | } | 968 | } |
| 967 | 969 | ||
| 970 | //MARK: regWISlashCommands | ||
| 968 | function registerWorldInfoSlashCommands() { | 971 | function registerWorldInfoSlashCommands() { |
| 969 | /** | 972 | /** |
| 970 | * Gets a *rough* approximation of the current chat context. | 973 | * Gets a *rough* approximation of the current chat context. |
| @@ -1754,12 +1757,12 @@ function registerWorldInfoSlashCommands() { | |||
| 1754 | */ | 1757 | */ |
| 1755 | export async function showWorldEditor(name) { | 1758 | export async function showWorldEditor(name) { |
| 1756 | if (!name) { | 1759 | if (!name) { |
| 1757 | hideWorldEditor(); | 1760 | await hideWorldEditor(); |
| 1758 | return; | 1761 | return; |
| 1759 | } | 1762 | } |
| 1760 | 1763 | ||
| 1761 | const wiData = await loadWorldInfo(name); | 1764 | const wiData = await loadWorldInfo(name); |
| 1762 | displayWorldEntries(name, wiData); | 1765 | await displayWorldEntries(name, wiData); |
| 1763 | } | 1766 | } |
| 1764 | 1767 | ||
| 1765 | /** | 1768 | /** |
| @@ -1815,8 +1818,8 @@ export async function updateWorldInfoList() { | |||
| 1815 | } | 1818 | } |
| 1816 | } | 1819 | } |
| 1817 | 1820 | ||
| 1818 | function hideWorldEditor() { | 1821 | async function hideWorldEditor() { |
| 1819 | displayWorldEntries(null, null); | 1822 | await displayWorldEntries(null, null); |
| 1820 | } | 1823 | } |
| 1821 | 1824 | ||
| 1822 | function getWIElement(name) { | 1825 | function getWIElement(name) { |
| @@ -1937,15 +1940,72 @@ function updateWorldEntryKeyOptionsCache(keyOptions, { remove = false, reset = f | |||
| 1937 | 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)); |
| 1938 | } | 1941 | } |
| 1939 | 1942 | ||
| 1940 | function displayWorldEntries(name, data, navigation = navigation_option.none, flashOnNav = true) { | 1943 | function clearEntryList($list) { |
| 1941 | updateEditor = (navigation, flashOnNav = true) => displayWorldEntries(name, data, navigation, flashOnNav); | 1944 | console.time('clearEntryList'); |
| 1942 | 1945 | ||
| 1943 | const worldEntriesList = $('#world_popup_entries_list'); | 1946 | if (!$list.children().length) { |
| 1947 | console.debug('List already empty, skipping cleanup.'); | ||
| 1948 | console.timeEnd('clearEntryList'); | ||
| 1949 | return; | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | // Step 1: Clean all <option> elements within <select> | ||
| 1953 | $list.find('option').each(function () { | ||
| 1954 | const $option = $(this); | ||
| 1955 | $option.off(); | ||
| 1956 | $.cleanData([$option[0]]); | ||
| 1957 | $option.remove(); | ||
| 1958 | }); | ||
| 1944 | 1959 | ||
| 1945 | // We save costly performance by removing all events before emptying. Because we know there are no relevant event handlers reacting on removing elements | 1960 | // Step 2: Clean all <select> elements |
| 1946 | // This prevents jQuery from actually going through all registered events on the controls for each entry when removing it | 1961 | $list.find('select').each(function () { |
| 1947 | worldEntriesList.find('*').off(); | 1962 | const $select = $(this); |
| 1948 | worldEntriesList.empty().show(); | 1963 | // Remove Select2-related data and container if present |
| 1964 | if ($select.data('select2')) { | ||
| 1965 | try { | ||
| 1966 | $select.select2('destroy'); | ||
| 1967 | } catch (e) { | ||
| 1968 | console.debug('Select2 destroy failed:', e); | ||
| 1969 | } | ||
| 1970 | } | ||
| 1971 | const $container = $select.parent(); | ||
| 1972 | if ($container.length) { | ||
| 1973 | $container.find('*').off(); | ||
| 1974 | $.cleanData($container.find('*').get()); | ||
| 1975 | $container.remove(); | ||
| 1976 | } | ||
| 1977 | |||
| 1978 | $select.off(); | ||
| 1979 | $.cleanData([$select[0]]); | ||
| 1980 | }); | ||
| 1981 | |||
| 1982 | // Step 3: Clean <div>, <span>, <input> | ||
| 1983 | $list.find('div, span, input').each(function () { | ||
| 1984 | const $elem = $(this); | ||
| 1985 | $elem.off(); | ||
| 1986 | $.cleanData([$elem[0]]); | ||
| 1987 | $elem.remove(); | ||
| 1988 | }); | ||
| 1989 | |||
| 1990 | const totalElementsOfAnyKindLeftInList = $list.children().length; | ||
| 1991 | |||
| 1992 | // Final cleanup | ||
| 1993 | if (totalElementsOfAnyKindLeftInList) { | ||
| 1994 | console.time('empty'); | ||
| 1995 | $list.empty(); | ||
| 1996 | console.timeEnd('empty'); | ||
| 1997 | } | ||
| 1998 | |||
| 1999 | console.timeEnd('clearEntryList'); | ||
| 2000 | } | ||
| 2001 | |||
| 2002 | //MARK: displayWorldEntries | ||
| 2003 | async function displayWorldEntries(name, data, navigation = navigation_option.none, flashOnNav = true) { | ||
| 2004 | updateEditor = async (navigation, flashOnNav = true) => await displayWorldEntries(name, data, navigation, flashOnNav); | ||
| 2005 | |||
| 2006 | const worldEntriesList = $('#world_popup_entries_list'); | ||
| 2007 | clearEntryList(worldEntriesList); | ||
| 2008 | worldEntriesList.show(); | ||
| 1949 | 2009 | ||
| 1950 | if (!data || !('entries' in data)) { | 2010 | if (!data || !('entries' in data)) { |
| 1951 | $('#world_popup_new').off('click').on('click', nullWorldInfo); | 2011 | $('#world_popup_new').off('click').on('click', nullWorldInfo); |
| @@ -2038,22 +2098,39 @@ function displayWorldEntries(name, data, navigation = navigation_option.none, fl | |||
| 2038 | formatNavigator: PAGINATION_TEMPLATE, | 2098 | formatNavigator: PAGINATION_TEMPLATE, |
| 2039 | showNavigator: true, | 2099 | showNavigator: true, |
| 2040 | callback: async function (/** @type {object[]} */ page) { | 2100 | callback: async function (/** @type {object[]} */ page) { |
| 2041 | // We save costly performance by removing all events before emptying. Because we know there are no relevant event handlers reacting on removing elements | 2101 | try { |
| 2042 | // This prevents jQuery from actually going through all registered events on the controls for each entry when removing it | 2102 | // Prevent saveWorldInfo from firing timeouts while rendering the list |
| 2043 | worldEntriesList.find('*').off(); | 2103 | isSaveWorldInfoDisabled = true; |
| 2044 | worldEntriesList.empty(); | 2104 | clearEntryList(worldEntriesList); |
| 2045 | 2105 | ||
| 2046 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); | 2106 | const keywordHeaders = await renderTemplateAsync('worldInfoKeywordHeaders'); |
| 2047 | const blocksPromises = page.map(async (entry) => await getWorldEntry(name, data, entry)).filter(x => x); | 2107 | const blocks = []; |
| 2048 | const blocks = await Promise.all(blocksPromises); | 2108 | |
| 2049 | const isCustomOrder = $('#world_info_sort_order').find(':selected').data('rule') === 'custom'; | 2109 | for (const entry of page) { |
| 2050 | if (!isCustomOrder) { | 2110 | try { |
| 2051 | blocks.forEach(block => { | 2111 | const block = await getWorldEntry(name, data, entry); |
| 2052 | block.find('.drag-handle').remove(); | 2112 | if (block) { |
| 2053 | }); | 2113 | blocks.push(block); |
| 2114 | } | ||
| 2115 | } catch (error) { | ||
| 2116 | console.error(`Error while processing entry ${entry.uid}:`, error); | ||
| 2117 | } | ||
| 2118 | } | ||
| 2119 | |||
| 2120 | const isCustomOrder = $('#world_info_sort_order').find(':selected').data('rule') === 'custom'; | ||
| 2121 | if (!isCustomOrder) { | ||
| 2122 | blocks.forEach(block => { | ||
| 2123 | block.find('.drag-handle').remove(); | ||
| 2124 | }); | ||
| 2125 | } | ||
| 2126 | |||
| 2127 | worldEntriesList.append(keywordHeaders); | ||
| 2128 | worldEntriesList.append(blocks); | ||
| 2129 | } catch (error) { | ||
| 2130 | console.error('Error while rendering WI entries:', error); | ||
| 2131 | } finally { | ||
| 2132 | isSaveWorldInfoDisabled = false; | ||
| 2054 | } | 2133 | } |
| 2055 | worldEntriesList.append(keywordHeaders); | ||
| 2056 | worldEntriesList.append(blocks); | ||
| 2057 | }, | 2134 | }, |
| 2058 | afterSizeSelectorChange: function (e) { | 2135 | afterSizeSelectorChange: function (e) { |
| 2059 | accountStorage.setItem(storageKey, e.target.value); | 2136 | accountStorage.setItem(storageKey, e.target.value); |
| @@ -2173,7 +2250,7 @@ function displayWorldEntries(name, data, navigation = navigation_option.none, fl | |||
| 2173 | if (selectedIndex !== -1) { | 2250 | if (selectedIndex !== -1) { |
| 2174 | $('#world_editor_select').val(selectedIndex).trigger('change'); | 2251 | $('#world_editor_select').val(selectedIndex).trigger('change'); |
| 2175 | } else { | 2252 | } else { |
| 2176 | hideWorldEditor(); | 2253 | await hideWorldEditor(); |
| 2177 | } | 2254 | } |
| 2178 | } | 2255 | } |
| 2179 | }); | 2256 | }); |
| @@ -2211,6 +2288,7 @@ function displayWorldEntries(name, data, navigation = navigation_option.none, fl | |||
| 2211 | await saveWorldInfo(name, data); | 2288 | await saveWorldInfo(name, data); |
| 2212 | }, | 2289 | }, |
| 2213 | }); | 2290 | }); |
| 2291 | |||
| 2214 | //$("#world_popup_entries_list").disableSelection(); | 2292 | //$("#world_popup_entries_list").disableSelection(); |
| 2215 | } | 2293 | } |
| 2216 | 2294 | ||
| @@ -2453,208 +2531,137 @@ export function parseRegexFromString(input) { | |||
| 2453 | } | 2531 | } |
| 2454 | } | 2532 | } |
| 2455 | 2533 | ||
| 2456 | export async function getWorldEntry(name, data, entry) { | 2534 | //MARK: getWorldEntry |
| 2457 | if (!data.entries[entry.uid]) { | 2535 | function enableKeysInputHelper({ template, entry, entryPropName, originalDataValueName, name, data }) { |
| 2458 | return; | 2536 | const isFancyInput = !isMobile() && !power_user.wi_key_input_plaintext; |
| 2459 | } | 2537 | const input = isFancyInput ? template.find(`select[name="${entryPropName}"]`) : template.find(`textarea[name="${entryPropName}"]`); |
| 2460 | 2538 | input.data('uid', entry.uid); | |
| 2461 | const template = WI_ENTRY_EDIT_TEMPLATE.clone(); | 2539 | input.on('click', function (event) { |
| 2462 | template.data('uid', entry.uid); | 2540 | event.stopPropagation(); |
| 2463 | template.attr('uid', entry.uid); | 2541 | }); |
| 2464 | |||
| 2465 | // Init default state of WI Key toggle (=> true) | ||
| 2466 | if (typeof power_user.wi_key_input_plaintext === 'undefined') power_user.wi_key_input_plaintext = true; | ||
| 2467 | 2542 | ||
| 2468 | /** Function to build the keys input controls @param {string} entryPropName @param {string} originalDataValueName */ | 2543 | function templateStyling(item, { searchStyle = false } = {}) { |
| 2469 | function enableKeysInput(entryPropName, originalDataValueName) { | 2544 | const content = $('<span>').addClass('item').text(item.text).attr('title', `${item.text}\n\nClick to edit`); |
| 2470 | const isFancyInput = !isMobile() && !power_user.wi_key_input_plaintext; | 2545 | const isRegex = isValidRegex(item.text); |
| 2471 | const input = isFancyInput ? template.find(`select[name="${entryPropName}"]`) : template.find(`textarea[name="${entryPropName}"]`); | 2546 | if (isRegex) { |
| 2472 | input.data('uid', entry.uid); | 2547 | content.html(highlightRegex(item.text)); |
| 2473 | input.on('click', function (event) { | 2548 | content.addClass('regex_item').prepend($('<span>').addClass('regex_icon').text('•*').attr('title', 'Regex')); |
| 2474 | // Prevent closing the drawer on clicking the input | 2549 | } |
| 2475 | event.stopPropagation(); | 2550 | if (searchStyle && item.count) { |
| 2551 | const wrapper = $('<span>').addClass('result_block').append(content); | ||
| 2552 | wrapper.append($('<span>').addClass('item_count').text(item.count).attr('title', `Used as a key ${item.count} ${item.count != 1 ? 'times' : 'time'} in this lorebook`)); | ||
| 2553 | return wrapper; | ||
| 2554 | } | ||
| 2555 | return content; | ||
| 2556 | } | ||
| 2557 | |||
| 2558 | if (isFancyInput) { | ||
| 2559 | select2ModifyOptions(input, entry[entryPropName], { select: true, changeEventArgs: { skipReset: true, noSave: true } }); | ||
| 2560 | input.select2({ | ||
| 2561 | ajax: dynamicSelect2DataViaAjax(() => worldEntryKeyOptionsCache), | ||
| 2562 | tags: true, | ||
| 2563 | tokenSeparators: [','], | ||
| 2564 | tokenizer: customTokenizer, | ||
| 2565 | placeholder: input.attr('placeholder'), | ||
| 2566 | templateResult: item => templateStyling(item, { searchStyle: true }), | ||
| 2567 | templateSelection: item => templateStyling(item), | ||
| 2476 | }); | 2568 | }); |
| 2477 | 2569 | ||
| 2478 | function templateStyling(/** @type {Select2Option} */ item, { searchStyle = false } = {}) { | 2570 | // TypeScript-safe event handler |
| 2479 | const content = $('<span>').addClass('item').text(item.text).attr('title', `${item.text}\n\nClick to edit`); | 2571 | /** |
| 2480 | const isRegex = isValidRegex(item.text); | 2572 | * @param {Event} _event |
| 2481 | if (isRegex) { | 2573 | * @param {{ skipReset?: boolean, noSave?: boolean }} [arg] |
| 2482 | content.html(highlightRegex(item.text)); | 2574 | */ |
| 2483 | content.addClass('regex_item').prepend($('<span>').addClass('regex_icon').text('•*').attr('title', 'Regex')); | 2575 | input.on('change', async function (_event, arg) { |
| 2484 | } | 2576 | const uid = $(this).data('uid'); |
| 2485 | 2577 | const keys = ($(this).select2('data')).map(x => x.text); | |
| 2486 | if (searchStyle && item.count) { | 2578 | const skipReset = arg?.skipReset ?? false; |
| 2487 | // Build a wrapping element | 2579 | const noSave = arg?.noSave ?? false; |
| 2488 | const wrapper = $('<span>').addClass('result_block') | 2580 | if (!skipReset) await resetScrollHeight(this); |
| 2489 | .append(content); | 2581 | if (!noSave) { |
| 2490 | wrapper.append($('<span>').addClass('item_count').text(item.count).attr('title', `Used as a key ${item.count} ${item.count != 1 ? 'times' : 'time'} in this lorebook`)); | 2582 | data.entries[uid][entryPropName] = keys; |
| 2491 | return wrapper; | 2583 | setWIOriginalDataValue(data, uid, originalDataValueName, data.entries[uid][entryPropName]); |
| 2584 | await saveWorldInfo(name, data); | ||
| 2492 | } | 2585 | } |
| 2586 | $(this).toggleClass('empty', !data.entries[uid][entryPropName].length); | ||
| 2587 | }); | ||
| 2493 | 2588 | ||
| 2494 | return content; | 2589 | input.toggleClass('empty', !entry[entryPropName].length); |
| 2495 | } | 2590 | input.on('select2:select', event => updateWorldEntryKeyOptionsCache([event.params.data])); |
| 2496 | 2591 | input.on('select2:unselect', event => updateWorldEntryKeyOptionsCache([event.params.data], { remove: true })); | |
| 2497 | if (isFancyInput) { | 2592 | |
| 2498 | // First initialize existing values as options, before initializing select2, to speed up performance | 2593 | select2ChoiceClickSubscribe(input, target => { |
| 2499 | select2ModifyOptions(input, entry[entryPropName], { select: true, changeEventArgs: { skipReset: true, noSave: true } }); | 2594 | const key = $(target.closest('.regex-highlight, .item')).text(); |
| 2500 | 2595 | const selected = input.val(); | |
| 2501 | input.select2({ | 2596 | if (!Array.isArray(selected)) return; |
| 2502 | ajax: dynamicSelect2DataViaAjax(() => worldEntryKeyOptionsCache), | 2597 | var index = selected.indexOf(getSelect2OptionId(key)); |
| 2503 | tags: true, | 2598 | if (index > -1) selected.splice(index, 1); |
| 2504 | tokenSeparators: [','], | 2599 | input.val(selected).trigger('change'); |
| 2505 | tokenizer: customTokenizer, | 2600 | updateWorldEntryKeyOptionsCache([key], { remove: true }); |
| 2506 | placeholder: input.attr('placeholder'), | 2601 | input.next('span.select2-container').find('textarea').val(key).trigger('input'); |
| 2507 | templateResult: item => templateStyling(item, { searchStyle: true }), | 2602 | }, { openDrawer: true }); |
| 2508 | templateSelection: item => templateStyling(item), | 2603 | } else { |
| 2509 | }); | 2604 | template.find(`select[name="${entryPropName}"]`).hide(); |
| 2510 | input.on('change', async function (_, { skipReset, noSave } = {}) { | 2605 | input.show(); |
| 2511 | const uid = $(this).data('uid'); | 2606 | /** |
| 2512 | /** @type {string[]} */ | 2607 | * @param {Event} _event |
| 2513 | const keys = ($(this).select2('data')).map(x => x.text); | 2608 | * @param {{ skipReset?: boolean, noSave?: boolean }} [arg] |
| 2514 | 2609 | */ | |
| 2515 | !skipReset && await resetScrollHeight(this); | 2610 | input.on('change', async function (_event, arg) { |
| 2516 | if (!noSave) { | 2611 | const uid = $(this).data('uid'); |
| 2517 | data.entries[uid][entryPropName] = keys; | 2612 | const value = String($(this).val()); |
| 2518 | setWIOriginalDataValue(data, uid, originalDataValueName, data.entries[uid][entryPropName]); | 2613 | const skipReset = arg?.skipReset ?? false; |
| 2519 | await saveWorldInfo(name, data); | 2614 | const noSave = arg?.noSave ?? false; |
| 2520 | } | 2615 | if (!skipReset) await resetScrollHeight(this); |
| 2616 | if (!noSave) { | ||
| 2617 | data.entries[uid][entryPropName] = splitKeywordsAndRegexes(value); | ||
| 2618 | setWIOriginalDataValue(data, uid, originalDataValueName, data.entries[uid][entryPropName]); | ||
| 2619 | await saveWorldInfo(name, data); | ||
| 2521 | $(this).toggleClass('empty', !data.entries[uid][entryPropName].length); | 2620 | $(this).toggleClass('empty', !data.entries[uid][entryPropName].length); |
| 2522 | }); | 2621 | } |
| 2523 | input.toggleClass('empty', !entry[entryPropName].length); | 2622 | }); |
| 2524 | input.on('select2:select', /** @type {function(*):void} */ event => updateWorldEntryKeyOptionsCache([event.params.data])); | 2623 | input.val(entry[entryPropName].join(', ')).trigger('input', { skipReset: true }); |
| 2525 | input.on('select2:unselect', /** @type {function(*):void} */ event => updateWorldEntryKeyOptionsCache([event.params.data], { remove: true })); | ||
| 2526 | |||
| 2527 | select2ChoiceClickSubscribe(input, target => { | ||
| 2528 | const key = $(target.closest('.regex-highlight, .item')).text(); | ||
| 2529 | console.debug('Editing WI key', key); | ||
| 2530 | |||
| 2531 | // Remove the current key from the actual selection | ||
| 2532 | const selected = input.val(); | ||
| 2533 | if (!Array.isArray(selected)) return; | ||
| 2534 | var index = selected.indexOf(getSelect2OptionId(key)); | ||
| 2535 | if (index > -1) selected.splice(index, 1); | ||
| 2536 | input.val(selected).trigger('change'); | ||
| 2537 | // Manually update the cache, that change event is not gonna trigger it | ||
| 2538 | updateWorldEntryKeyOptionsCache([key], { remove: true }); | ||
| 2539 | |||
| 2540 | // We need to "hack" the actual text input into the currently open textarea | ||
| 2541 | input.next('span.select2-container').find('textarea') | ||
| 2542 | .val(key).trigger('input'); | ||
| 2543 | }, { openDrawer: true }); | ||
| 2544 | } | ||
| 2545 | else { | ||
| 2546 | // Compatibility with mobile devices. On mobile we need a text input field, not a select option control, so we need its own event handlers | ||
| 2547 | template.find(`select[name="${entryPropName}"]`).hide(); | ||
| 2548 | input.show(); | ||
| 2549 | |||
| 2550 | input.on('input', async function (_, { skipReset, noSave } = {}) { | ||
| 2551 | const uid = $(this).data('uid'); | ||
| 2552 | const value = String($(this).val()); | ||
| 2553 | !skipReset && await resetScrollHeight(this); | ||
| 2554 | if (!noSave) { | ||
| 2555 | data.entries[uid][entryPropName] = splitKeywordsAndRegexes(value); | ||
| 2556 | setWIOriginalDataValue(data, uid, originalDataValueName, data.entries[uid][entryPropName]); | ||
| 2557 | await saveWorldInfo(name, data); | ||
| 2558 | $(this).toggleClass('empty', !data.entries[uid][entryPropName].length); | ||
| 2559 | } | ||
| 2560 | }); | ||
| 2561 | input.val(entry[entryPropName].join(', ')).trigger('input', { skipReset: true }); | ||
| 2562 | } | ||
| 2563 | return { isFancy: isFancyInput, control: input }; | ||
| 2564 | } | 2624 | } |
| 2625 | return { isFancy: isFancyInput, control: input }; | ||
| 2626 | } | ||
| 2565 | 2627 | ||
| 2566 | // key | 2628 | /** |
| 2567 | const keyInput = enableKeysInput('key', 'keys'); | 2629 | * Helper to handle match checkboxes for WI entries. |
| 2568 | 2630 | */ | |
| 2569 | // keysecondary | 2631 | function handleMatchCheckboxHelper({ template, entry, fieldName, data, name }) { |
| 2570 | const keySecondaryInput = enableKeysInput('keysecondary', 'secondary_keys'); | 2632 | const key = originalWIDataKeyMap[fieldName]; |
| 2571 | 2633 | const checkBoxElem = template.find(`input[type="checkbox"][name="${fieldName}"]`); | |
| 2572 | // draw key input switch button | 2634 | checkBoxElem.data('uid', entry.uid); |
| 2573 | template.find('.switch_input_type_icon').on('click', function () { | 2635 | checkBoxElem.on('input', async function () { |
| 2574 | power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext; | ||
| 2575 | saveSettingsDebounced(); | ||
| 2576 | |||
| 2577 | // Just redraw the panel | ||
| 2578 | const uid = ($(this).parents('.world_entry')).data('uid'); | ||
| 2579 | updateEditor(uid, false); | ||
| 2580 | |||
| 2581 | $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click'); | ||
| 2582 | // setTimeout(() => { | ||
| 2583 | // }, debounce_timeout.standard); | ||
| 2584 | }).each((_, icon) => { | ||
| 2585 | $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off')); | ||
| 2586 | $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off')); | ||
| 2587 | }); | ||
| 2588 | |||
| 2589 | // logic AND/NOT | ||
| 2590 | const selectiveLogicDropdown = template.find('select[name="entryLogicType"]'); | ||
| 2591 | selectiveLogicDropdown.data('uid', entry.uid); | ||
| 2592 | |||
| 2593 | selectiveLogicDropdown.on('click', function (event) { | ||
| 2594 | event.stopPropagation(); | ||
| 2595 | }); | ||
| 2596 | |||
| 2597 | selectiveLogicDropdown.on('input', async function () { | ||
| 2598 | const uid = $(this).data('uid'); | ||
| 2599 | const value = Number($(this).val()); | ||
| 2600 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; | ||
| 2601 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); | ||
| 2602 | await saveWorldInfo(name, data); | ||
| 2603 | }); | ||
| 2604 | |||
| 2605 | template | ||
| 2606 | .find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`) | ||
| 2607 | .prop('selected', true) | ||
| 2608 | .trigger('input'); | ||
| 2609 | |||
| 2610 | // Character filter | ||
| 2611 | const characterFilterLabel = template.find('label[for="characterFilter"] > small'); | ||
| 2612 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 2613 | |||
| 2614 | // exclude characters checkbox | ||
| 2615 | const characterExclusionInput = template.find('input[name="character_exclusion"]'); | ||
| 2616 | characterExclusionInput.data('uid', entry.uid); | ||
| 2617 | characterExclusionInput.on('input', async function () { | ||
| 2618 | const uid = $(this).data('uid'); | 2636 | const uid = $(this).data('uid'); |
| 2619 | const value = $(this).prop('checked'); | 2637 | const value = $(this).prop('checked'); |
| 2620 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); | 2638 | data.entries[uid][fieldName] = value; |
| 2621 | if (data.entries[uid].characterFilter) { | 2639 | setWIOriginalDataValue(data, uid, key, data.entries[uid][fieldName]); |
| 2622 | if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) { | ||
| 2623 | delete data.entries[uid].characterFilter; | ||
| 2624 | } else { | ||
| 2625 | data.entries[uid].characterFilter.isExclude = value; | ||
| 2626 | } | ||
| 2627 | } else if (value) { | ||
| 2628 | Object.assign( | ||
| 2629 | data.entries[uid], | ||
| 2630 | { | ||
| 2631 | characterFilter: { | ||
| 2632 | isExclude: true, | ||
| 2633 | names: [], | ||
| 2634 | tags: [], | ||
| 2635 | }, | ||
| 2636 | }, | ||
| 2637 | ); | ||
| 2638 | } | ||
| 2639 | |||
| 2640 | // Verify names to exist in the system | ||
| 2641 | if (data.entries[uid]?.characterFilter?.names?.length > 0) { | ||
| 2642 | for (const name of [...data.entries[uid].characterFilter.names]) { | ||
| 2643 | if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) { | ||
| 2644 | console.warn(`World Info: Character ${name} not found. Removing from the entry filter.`, entry); | ||
| 2645 | data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name); | ||
| 2646 | } | ||
| 2647 | } | ||
| 2648 | } | ||
| 2649 | |||
| 2650 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | ||
| 2651 | await saveWorldInfo(name, data); | 2640 | await saveWorldInfo(name, data); |
| 2652 | }); | 2641 | }); |
| 2653 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input'); | 2642 | checkBoxElem.prop('checked', !!entry[fieldName]).trigger('input'); |
| 2643 | } | ||
| 2654 | 2644 | ||
| 2655 | const characterFilter = template.find('select[name="characterFilter"]'); | 2645 | /** |
| 2656 | characterFilter.data('uid', entry.uid); | 2646 | * Helper to update position/order display. |
| 2647 | */ | ||
| 2648 | function updatePosOrdDisplayHelper({ template, data, uid }) { | ||
| 2649 | let entry = data.entries[uid]; | ||
| 2650 | let posText = entry.position; | ||
| 2651 | switch (entry.position) { | ||
| 2652 | case 0: posText = '↑CD'; break; | ||
| 2653 | case 1: posText = 'CD↓'; break; | ||
| 2654 | case 2: posText = '↑AN'; break; | ||
| 2655 | case 3: posText = 'AN↓'; break; | ||
| 2656 | case 4: posText = `@D${entry.depth}`; break; | ||
| 2657 | } | ||
| 2658 | template.find('.world_entry_form_position_value').text(`(${posText} ${entry.order})`); | ||
| 2659 | } | ||
| 2657 | 2660 | ||
| 2661 | /** | ||
| 2662 | * Helper to initialize character filter select2. | ||
| 2663 | */ | ||
| 2664 | function initCharacterFilterSelect2Helper(characterFilter, t) { | ||
| 2658 | if (!isMobile()) { | 2665 | if (!isMobile()) { |
| 2659 | $(characterFilter).select2({ | 2666 | $(characterFilter).select2({ |
| 2660 | width: '100%', | 2667 | width: '100%', |
| @@ -2663,7 +2670,12 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2663 | closeOnSelect: false, | 2670 | closeOnSelect: false, |
| 2664 | }); | 2671 | }); |
| 2665 | } | 2672 | } |
| 2673 | } | ||
| 2666 | 2674 | ||
| 2675 | /** | ||
| 2676 | * Helper to fill character and tag options for character filter. | ||
| 2677 | */ | ||
| 2678 | function fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext }) { | ||
| 2667 | const characters = getContext().characters; | 2679 | const characters = getContext().characters; |
| 2668 | characters.forEach((character) => { | 2680 | characters.forEach((character) => { |
| 2669 | const option = document.createElement('option'); | 2681 | const option = document.createElement('option'); |
| @@ -2673,7 +2685,6 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2673 | option.setAttribute('data-type', 'character'); | 2685 | option.setAttribute('data-type', 'character'); |
| 2674 | characterFilter.append(option); | 2686 | characterFilter.append(option); |
| 2675 | }); | 2687 | }); |
| 2676 | |||
| 2677 | const tags = getContext().tags; | 2688 | const tags = getContext().tags; |
| 2678 | tags.forEach((tag) => { | 2689 | tags.forEach((tag) => { |
| 2679 | const option = document.createElement('option'); | 2690 | const option = document.createElement('option'); |
| @@ -2683,14 +2694,17 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2683 | option.setAttribute('data-type', 'tag'); | 2694 | option.setAttribute('data-type', 'tag'); |
| 2684 | characterFilter.append(option); | 2695 | characterFilter.append(option); |
| 2685 | }); | 2696 | }); |
| 2697 | } | ||
| 2686 | 2698 | ||
| 2699 | /** | ||
| 2700 | * Helper to handle character filter changes. | ||
| 2701 | */ | ||
| 2702 | function handleCharacterFilterChangeHelper({ characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t }) { | ||
| 2687 | characterFilter.on('mousedown change', async function (e) { | 2703 | characterFilter.on('mousedown change', async function (e) { |
| 2688 | // If there's no world names, don't do anything | ||
| 2689 | if (world_names.length === 0) { | 2704 | if (world_names.length === 0) { |
| 2690 | e.preventDefault(); | 2705 | e.preventDefault(); |
| 2691 | return; | 2706 | return; |
| 2692 | } | 2707 | } |
| 2693 | |||
| 2694 | const uid = $(this).data('uid'); | 2708 | const uid = $(this).data('uid'); |
| 2695 | const selected = $(this).find(':selected'); | 2709 | const selected = $(this).find(':selected'); |
| 2696 | if ((!selected || selected?.length === 0) && !data.entries[uid].characterFilter?.isExclude) { | 2710 | if ((!selected || selected?.length === 0) && !data.entries[uid].characterFilter?.isExclude) { |
| @@ -2712,361 +2726,99 @@ export async function getWorldEntry(name, data, entry) { | |||
| 2712 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | 2726 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); |
| 2713 | await saveWorldInfo(name, data); | 2727 | await saveWorldInfo(name, data); |
| 2714 | }); | 2728 | }); |
| 2729 | } | ||
| 2715 | 2730 | ||
| 2716 | // comment | 2731 | /** |
| 2717 | const commentInput = template.find('textarea[name="comment"]'); | 2732 | * Helper to handle probability input. |
| 2718 | const commentToggle = template.find('input[name="addMemo"]'); | 2733 | */ |
| 2719 | commentInput.data('uid', entry.uid); | 2734 | function handleProbabilityInputHelper({ probabilityInput, data, entry, name, setWIOriginalDataValue, saveWorldInfo }) { |
| 2720 | commentInput.on('input', async function (_, { skipReset } = {}) { | ||
| 2721 | const uid = $(this).data('uid'); | ||
| 2722 | const value = $(this).val(); | ||
| 2723 | !skipReset && await resetScrollHeight(this); | ||
| 2724 | data.entries[uid].comment = value; | ||
| 2725 | |||
| 2726 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); | ||
| 2727 | await saveWorldInfo(name, data); | ||
| 2728 | }); | ||
| 2729 | commentToggle.data('uid', entry.uid); | ||
| 2730 | commentToggle.on('input', async function () { | ||
| 2731 | const uid = $(this).data('uid'); | ||
| 2732 | const value = $(this).prop('checked'); | ||
| 2733 | //console.log(value) | ||
| 2734 | const commentContainer = $(this) | ||
| 2735 | .closest('.world_entry') | ||
| 2736 | .find('.commentContainer'); | ||
| 2737 | data.entries[uid].addMemo = value; | ||
| 2738 | await saveWorldInfo(name, data); | ||
| 2739 | value ? commentContainer.show() : commentContainer.hide(); | ||
| 2740 | }); | ||
| 2741 | |||
| 2742 | commentInput.val(entry.comment).trigger('input', { skipReset: true }); | ||
| 2743 | //initScrollHeight(commentInput); | ||
| 2744 | commentToggle.prop('checked', true /* entry.addMemo */).trigger('input'); | ||
| 2745 | commentToggle.parent().hide(); | ||
| 2746 | |||
| 2747 | // content | ||
| 2748 | const counter = template.find('.world_entry_form_token_counter'); | ||
| 2749 | const countTokensDebounced = debounce(async function (counter, value) { | ||
| 2750 | const numberOfTokens = await getTokenCountAsync(value); | ||
| 2751 | $(counter).text(numberOfTokens); | ||
| 2752 | }, debounce_timeout.relaxed); | ||
| 2753 | |||
| 2754 | const contentInputId = `world_entry_content_${entry.uid}`; | ||
| 2755 | const contentInput = template.find('textarea[name="content"]'); | ||
| 2756 | contentInput.data('uid', entry.uid); | ||
| 2757 | contentInput.attr('id', contentInputId); | ||
| 2758 | contentInput.on('input', async function (_, { skipCount } = {}) { | ||
| 2759 | const uid = $(this).data('uid'); | ||
| 2760 | const value = $(this).val(); | ||
| 2761 | data.entries[uid].content = value; | ||
| 2762 | |||
| 2763 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); | ||
| 2764 | await saveWorldInfo(name, data); | ||
| 2765 | |||
| 2766 | if (skipCount) { | ||
| 2767 | return; | ||
| 2768 | } | ||
| 2769 | |||
| 2770 | // count tokens | ||
| 2771 | countTokensDebounced(counter, value); | ||
| 2772 | }); | ||
| 2773 | contentInput.val(entry.content).trigger('input', { skipCount: true }); | ||
| 2774 | |||
| 2775 | const contentExpandButton = template.find('.editor_maximize'); | ||
| 2776 | contentExpandButton.attr('data-for', contentInputId); | ||
| 2777 | |||
| 2778 | template.find('.inline-drawer-toggle').on('click', function () { | ||
| 2779 | if (counter.data('first-run')) { | ||
| 2780 | counter.data('first-run', false); | ||
| 2781 | countTokensDebounced(counter, contentInput.val()); | ||
| 2782 | if (!keyInput.isFancy) initScrollHeight(keyInput.control); | ||
| 2783 | if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control); | ||
| 2784 | } | ||
| 2785 | }); | ||
| 2786 | |||
| 2787 | // selective | ||
| 2788 | const selectiveInput = template.find('input[name="selective"]'); | ||
| 2789 | selectiveInput.data('uid', entry.uid); | ||
| 2790 | selectiveInput.on('input', async function () { | ||
| 2791 | const uid = $(this).data('uid'); | ||
| 2792 | const value = $(this).prop('checked'); | ||
| 2793 | data.entries[uid].selective = value; | ||
| 2794 | |||
| 2795 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); | ||
| 2796 | await saveWorldInfo(name, data); | ||
| 2797 | |||
| 2798 | const keysecondary = $(this) | ||
| 2799 | .closest('.world_entry') | ||
| 2800 | .find('.keysecondary'); | ||
| 2801 | |||
| 2802 | const keysecondarytextpole = $(this) | ||
| 2803 | .closest('.world_entry') | ||
| 2804 | .find('.keysecondarytextpole'); | ||
| 2805 | |||
| 2806 | const keyprimaryselect = $(this) | ||
| 2807 | .closest('.world_entry') | ||
| 2808 | .find('.keyprimaryselect'); | ||
| 2809 | |||
| 2810 | const keyprimaryHeight = keyprimaryselect.outerHeight(); | ||
| 2811 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); | ||
| 2812 | |||
| 2813 | value ? keysecondary.show() : keysecondary.hide(); | ||
| 2814 | |||
| 2815 | }); | ||
| 2816 | //forced on, ignored if empty | ||
| 2817 | selectiveInput.prop('checked', true /* entry.selective */).trigger('input'); | ||
| 2818 | selectiveInput.parent().hide(); | ||
| 2819 | |||
| 2820 | |||
| 2821 | // constant | ||
| 2822 | /* | ||
| 2823 | const constantInput = template.find('input[name="constant"]'); | ||
| 2824 | constantInput.data("uid", entry.uid); | ||
| 2825 | constantInput.on("input", async function () { | ||
| 2826 | const uid = $(this).data("uid"); | ||
| 2827 | const value = $(this).prop("checked"); | ||
| 2828 | data.entries[uid].constant = value; | ||
| 2829 | setOriginalDataValue(data, uid, "constant", data.entries[uid].constant); | ||
| 2830 | await saveWorldInfo(name, data); | ||
| 2831 | }); | ||
| 2832 | constantInput.prop("checked", entry.constant).trigger("input"); | ||
| 2833 | */ | ||
| 2834 | |||
| 2835 | // order | ||
| 2836 | const orderInput = template.find('input[name="order"]'); | ||
| 2837 | orderInput.data('uid', entry.uid); | ||
| 2838 | orderInput.on('input', async function () { | ||
| 2839 | const uid = $(this).data('uid'); | ||
| 2840 | const value = Number($(this).val()); | ||
| 2841 | |||
| 2842 | data.entries[uid].order = !isNaN(value) ? value : 0; | ||
| 2843 | updatePosOrdDisplay(uid); | ||
| 2844 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); | ||
| 2845 | await saveWorldInfo(name, data); | ||
| 2846 | }); | ||
| 2847 | orderInput.val(entry.order).trigger('input'); | ||
| 2848 | orderInput.css('width', 'calc(3em + 15px)'); | ||
| 2849 | |||
| 2850 | // group | ||
| 2851 | const groupInput = template.find('input[name="group"]'); | ||
| 2852 | groupInput.data('uid', entry.uid); | ||
| 2853 | groupInput.on('input', async function () { | ||
| 2854 | const uid = $(this).data('uid'); | ||
| 2855 | const value = String($(this).val()).trim(); | ||
| 2856 | |||
| 2857 | data.entries[uid].group = value; | ||
| 2858 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); | ||
| 2859 | await saveWorldInfo(name, data); | ||
| 2860 | }); | ||
| 2861 | groupInput.val(entry.group ?? '').trigger('input'); | ||
| 2862 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); | ||
| 2863 | |||
| 2864 | // inclusion priority | ||
| 2865 | const groupOverrideInput = template.find('input[name="groupOverride"]'); | ||
| 2866 | groupOverrideInput.data('uid', entry.uid); | ||
| 2867 | groupOverrideInput.on('input', async function () { | ||
| 2868 | const uid = $(this).data('uid'); | ||
| 2869 | const value = $(this).prop('checked'); | ||
| 2870 | data.entries[uid].groupOverride = value; | ||
| 2871 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); | ||
| 2872 | await saveWorldInfo(name, data); | ||
| 2873 | }); | ||
| 2874 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input'); | ||
| 2875 | |||
| 2876 | // group weight | ||
| 2877 | const groupWeightInput = template.find('input[name="groupWeight"]'); | ||
| 2878 | groupWeightInput.data('uid', entry.uid); | ||
| 2879 | groupWeightInput.on('input', async function () { | ||
| 2880 | const uid = $(this).data('uid'); | ||
| 2881 | let value = Number($(this).val()); | ||
| 2882 | const min = Number($(this).attr('min')); | ||
| 2883 | const max = Number($(this).attr('max')); | ||
| 2884 | |||
| 2885 | // Clamp the value | ||
| 2886 | if (value < min) { | ||
| 2887 | value = min; | ||
| 2888 | $(this).val(min); | ||
| 2889 | } else if (value > max) { | ||
| 2890 | value = max; | ||
| 2891 | $(this).val(max); | ||
| 2892 | } | ||
| 2893 | |||
| 2894 | data.entries[uid].groupWeight = !isNaN(value) ? Math.abs(value) : 1; | ||
| 2895 | setWIOriginalDataValue(data, uid, 'extensions.group_weight', data.entries[uid].groupWeight); | ||
| 2896 | await saveWorldInfo(name, data); | ||
| 2897 | }); | ||
| 2898 | groupWeightInput.val(entry.groupWeight ?? DEFAULT_WEIGHT).trigger('input'); | ||
| 2899 | |||
| 2900 | // sticky | ||
| 2901 | const sticky = template.find('input[name="sticky"]'); | ||
| 2902 | sticky.data('uid', entry.uid); | ||
| 2903 | sticky.on('input', async function () { | ||
| 2904 | const uid = $(this).data('uid'); | ||
| 2905 | const value = Number($(this).val()); | ||
| 2906 | data.entries[uid].sticky = !isNaN(value) ? value : null; | ||
| 2907 | |||
| 2908 | setWIOriginalDataValue(data, uid, 'extensions.sticky', data.entries[uid].sticky); | ||
| 2909 | await saveWorldInfo(name, data); | ||
| 2910 | }); | ||
| 2911 | sticky.val(entry.sticky > 0 ? entry.sticky : '').trigger('input'); | ||
| 2912 | |||
| 2913 | // cooldown | ||
| 2914 | const cooldown = template.find('input[name="cooldown"]'); | ||
| 2915 | cooldown.data('uid', entry.uid); | ||
| 2916 | cooldown.on('input', async function () { | ||
| 2917 | const uid = $(this).data('uid'); | ||
| 2918 | const value = Number($(this).val()); | ||
| 2919 | data.entries[uid].cooldown = !isNaN(value) ? value : null; | ||
| 2920 | |||
| 2921 | setWIOriginalDataValue(data, uid, 'extensions.cooldown', data.entries[uid].cooldown); | ||
| 2922 | await saveWorldInfo(name, data); | ||
| 2923 | }); | ||
| 2924 | cooldown.val(entry.cooldown > 0 ? entry.cooldown : '').trigger('input'); | ||
| 2925 | |||
| 2926 | // delay | ||
| 2927 | const delay = template.find('input[name="delay"]'); | ||
| 2928 | delay.data('uid', entry.uid); | ||
| 2929 | delay.on('input', async function () { | ||
| 2930 | const uid = $(this).data('uid'); | ||
| 2931 | const value = Number($(this).val()); | ||
| 2932 | data.entries[uid].delay = !isNaN(value) ? value : null; | ||
| 2933 | |||
| 2934 | setWIOriginalDataValue(data, uid, 'extensions.delay', data.entries[uid].delay); | ||
| 2935 | await saveWorldInfo(name, data); | ||
| 2936 | }); | ||
| 2937 | delay.val(entry.delay > 0 ? entry.delay : '').trigger('input'); | ||
| 2938 | |||
| 2939 | // probability | ||
| 2940 | if (entry.probability === undefined) { | ||
| 2941 | entry.probability = null; | ||
| 2942 | } | ||
| 2943 | |||
| 2944 | // depth | ||
| 2945 | const depthInput = template.find('input[name="depth"]'); | ||
| 2946 | depthInput.data('uid', entry.uid); | ||
| 2947 | |||
| 2948 | depthInput.on('input', async function () { | ||
| 2949 | const uid = $(this).data('uid'); | ||
| 2950 | const value = Number($(this).val()); | ||
| 2951 | |||
| 2952 | data.entries[uid].depth = !isNaN(value) ? value : 0; | ||
| 2953 | updatePosOrdDisplay(uid); | ||
| 2954 | setWIOriginalDataValue(data, uid, 'extensions.depth', data.entries[uid].depth); | ||
| 2955 | await saveWorldInfo(name, data); | ||
| 2956 | }); | ||
| 2957 | depthInput.val(entry.depth ?? DEFAULT_DEPTH).trigger('input'); | ||
| 2958 | depthInput.css('width', 'calc(3em + 15px)'); | ||
| 2959 | |||
| 2960 | // Hide by default unless depth is specified | ||
| 2961 | if (entry.position === world_info_position.atDepth) { | ||
| 2962 | //depthInput.parent().hide(); | ||
| 2963 | } | ||
| 2964 | |||
| 2965 | const probabilityInput = template.find('input[name="probability"]'); | ||
| 2966 | probabilityInput.data('uid', entry.uid); | 2735 | probabilityInput.data('uid', entry.uid); |
| 2967 | probabilityInput.on('input', async function () { | 2736 | probabilityInput.on('input', async function () { |
| 2968 | const uid = $(this).data('uid'); | 2737 | const uid = $(this).data('uid'); |
| 2969 | const value = Number($(this).val()); | 2738 | const value = Number($(this).val()); |
| 2970 | |||
| 2971 | data.entries[uid].probability = !isNaN(value) ? value : null; | 2739 | data.entries[uid].probability = !isNaN(value) ? value : null; |
| 2972 | |||
| 2973 | // Clamp probability to 0-100 | ||
| 2974 | if (data.entries[uid].probability !== null) { | 2740 | if (data.entries[uid].probability !== null) { |
| 2975 | data.entries[uid].probability = Math.min(100, Math.max(0, data.entries[uid].probability)); | 2741 | data.entries[uid].probability = Math.min(100, Math.max(0, data.entries[uid].probability)); |
| 2976 | |||
| 2977 | if (data.entries[uid].probability !== value) { | 2742 | if (data.entries[uid].probability !== value) { |
| 2978 | $(this).val(data.entries[uid].probability); | 2743 | $(this).val(data.entries[uid].probability); |
| 2979 | } | 2744 | } |
| 2980 | } | 2745 | } |
| 2981 | |||
| 2982 | setWIOriginalDataValue(data, uid, 'extensions.probability', data.entries[uid].probability); | 2746 | setWIOriginalDataValue(data, uid, 'extensions.probability', data.entries[uid].probability); |
| 2983 | await saveWorldInfo(name, data); | 2747 | await saveWorldInfo(name, data); |
| 2984 | }); | 2748 | }); |
| 2985 | probabilityInput.val(entry.probability).trigger('input'); | 2749 | probabilityInput.val(entry.probability).trigger('input'); |
| 2986 | probabilityInput.css('width', 'calc(3em + 15px)'); | 2750 | probabilityInput.css('width', 'calc(3em + 15px)'); |
| 2751 | } | ||
| 2987 | 2752 | ||
| 2988 | // probability toggle | 2753 | /** |
| 2989 | if (entry.useProbability === undefined) { | 2754 | * Helper to handle probability toggle. |
| 2990 | entry.useProbability = false; | 2755 | */ |
| 2991 | } | 2756 | function handleProbabilityToggleHelper({ probabilityToggle, data, entry, name, probabilityInput, setWIOriginalDataValue, saveWorldInfo }) { |
| 2992 | |||
| 2993 | const probabilityToggle = template.find('input[name="useProbability"]'); | ||
| 2994 | probabilityToggle.data('uid', entry.uid); | 2757 | probabilityToggle.data('uid', entry.uid); |
| 2995 | probabilityToggle.on('input', async function () { | 2758 | probabilityToggle.on('input', async function () { |
| 2996 | const uid = $(this).data('uid'); | 2759 | const uid = $(this).data('uid'); |
| 2997 | const value = $(this).prop('checked'); | 2760 | const value = $(this).prop('checked'); |
| 2998 | data.entries[uid].useProbability = value; | 2761 | data.entries[uid].useProbability = value; |
| 2999 | const probabilityContainer = $(this) | 2762 | const probabilityContainer = $(this).closest('.world_entry').find('.probabilityContainer'); |
| 3000 | .closest('.world_entry') | ||
| 3001 | .find('.probabilityContainer'); | ||
| 3002 | await saveWorldInfo(name, data); | 2763 | await saveWorldInfo(name, data); |
| 3003 | value ? probabilityContainer.show() : probabilityContainer.hide(); | 2764 | value ? probabilityContainer.show() : probabilityContainer.hide(); |
| 3004 | |||
| 3005 | if (value && data.entries[uid].probability === null) { | 2765 | if (value && data.entries[uid].probability === null) { |
| 3006 | data.entries[uid].probability = 100; | 2766 | data.entries[uid].probability = 100; |
| 3007 | } | 2767 | } |
| 3008 | |||
| 3009 | if (!value) { | 2768 | if (!value) { |
| 3010 | data.entries[uid].probability = null; | 2769 | data.entries[uid].probability = null; |
| 3011 | } | 2770 | } |
| 3012 | |||
| 3013 | probabilityInput.val(data.entries[uid].probability).trigger('input'); | 2771 | probabilityInput.val(data.entries[uid].probability).trigger('input'); |
| 3014 | }); | 2772 | }); |
| 3015 | //forced on, 100% by default | 2773 | probabilityToggle.prop('checked', true).trigger('input'); |
| 3016 | probabilityToggle.prop('checked', true /* entry.useProbability */).trigger('input'); | ||
| 3017 | probabilityToggle.parent().hide(); | 2774 | probabilityToggle.parent().hide(); |
| 2775 | } | ||
| 3018 | 2776 | ||
| 3019 | // position | 2777 | /** |
| 3020 | if (entry.position === undefined) { | 2778 | * Helper to handle select2 dropdowns for boolean selects. |
| 3021 | entry.position = 0; | 2779 | */ |
| 3022 | } | 2780 | function handleBooleanSelectHelper({ selectElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo }) { |
| 3023 | 2781 | selectElem.data('uid', entry.uid); | |
| 3024 | const positionInput = template.find('select[name="position"]'); | 2782 | selectElem.on('input', async function () { |
| 3025 | //initScrollHeight(positionInput); | 2783 | const uid = $(this).data('uid'); |
| 3026 | positionInput.data('uid', entry.uid); | 2784 | const value = $(this).val(); |
| 3027 | positionInput.on('click', function (event) { | 2785 | data.entries[uid][entryKey] = value === 'null' ? null : value === 'true'; |
| 3028 | // Prevent closing the drawer on clicking the input | 2786 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); |
| 3029 | event.stopPropagation(); | 2787 | await saveWorldInfo(name, data); |
| 3030 | }); | 2788 | }); |
| 3031 | positionInput.on('input', async function () { | 2789 | selectElem.val((entry[entryKey] === null || entry[entryKey] === undefined) ? 'null' : entry[entryKey] ? 'true' : 'false').trigger('input'); |
| 2790 | } | ||
| 2791 | |||
| 2792 | /** | ||
| 2793 | * Helper to handle input fields for numbers. | ||
| 2794 | */ | ||
| 2795 | function handleNumberInputHelper({ inputElem, entry, entryKey, data, name, setWIOriginalDataValue, saveWorldInfo, min, max, clamp = false }) { | ||
| 2796 | inputElem.data('uid', entry.uid); | ||
| 2797 | inputElem.on('input', async function () { | ||
| 3032 | const uid = $(this).data('uid'); | 2798 | const uid = $(this).data('uid'); |
| 3033 | const value = Number($(this).val()); | 2799 | let value = Number($(this).val()); |
| 3034 | data.entries[uid].position = !isNaN(value) ? value : 0; | 2800 | if (clamp) { |
| 3035 | if (value === world_info_position.atDepth) { | 2801 | if (value < min) { |
| 3036 | depthInput.prop('disabled', false); | 2802 | value = min; |
| 3037 | depthInput.css('visibility', 'visible'); | 2803 | $(this).val(min); |
| 3038 | //depthInput.parent().show(); | 2804 | } else if (value > max) { |
| 3039 | const role = Number($(this).find(':selected').data('role')); | 2805 | value = max; |
| 3040 | data.entries[uid].role = role; | 2806 | $(this).val(max); |
| 3041 | } else { | 2807 | } |
| 3042 | depthInput.prop('disabled', true); | ||
| 3043 | depthInput.css('visibility', 'hidden'); | ||
| 3044 | data.entries[uid].role = null; | ||
| 3045 | //depthInput.parent().hide(); | ||
| 3046 | } | 2808 | } |
| 3047 | updatePosOrdDisplay(uid); | 2809 | data.entries[uid][entryKey] = !isNaN(value) ? value : null; |
| 3048 | // Spec v2 only supports before_char and after_char | 2810 | setWIOriginalDataValue(data, uid, `extensions.${entryKey.replace(/[A-Z]/g, m => `_${m.toLowerCase()}`)}`, data.entries[uid][entryKey]); |
| 3049 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); | ||
| 3050 | // Write the original value as extensions field | ||
| 3051 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); | ||
| 3052 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); | ||
| 3053 | await saveWorldInfo(name, data); | 2811 | await saveWorldInfo(name, data); |
| 3054 | }); | 2812 | }); |
| 2813 | inputElem.val(entry[entryKey] ?? (clamp ? min : '')).trigger('input'); | ||
| 2814 | } | ||
| 3055 | 2815 | ||
| 3056 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; | 2816 | /** |
| 3057 | template | 2817 | * Helper to handle tri-state selector for constant/normal/vectorized. |
| 3058 | .find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`) | 2818 | */ |
| 3059 | .prop('selected', true) | 2819 | function handleEntryStateSelectorHelper({ entryStateSelector, entry, data, name, setWIOriginalDataValue, saveWorldInfo }) { |
| 3060 | .trigger('input'); | ||
| 3061 | |||
| 3062 | //add UID above content box (less important doesn't need to be always visible) | ||
| 3063 | template.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`); | ||
| 3064 | |||
| 3065 | //new tri-state selector for constant/normal/vectorized | ||
| 3066 | const entryStateSelector = template.find('select[name="entryStateSelector"]'); | ||
| 3067 | entryStateSelector.data('uid', entry.uid); | 2820 | entryStateSelector.data('uid', entry.uid); |
| 3068 | entryStateSelector.on('click', function (event) { | 2821 | entryStateSelector.on('click', function (event) { |
| 3069 | // Prevent closing the drawer on clicking the input | ||
| 3070 | event.stopPropagation(); | 2822 | event.stopPropagation(); |
| 3071 | }); | 2823 | }); |
| 3072 | entryStateSelector.on('input', async function () { | 2824 | entryStateSelector.on('input', async function () { |
| @@ -3093,12 +2845,17 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3093 | break; | 2845 | break; |
| 3094 | } | 2846 | } |
| 3095 | await saveWorldInfo(name, data); | 2847 | await saveWorldInfo(name, data); |
| 3096 | |||
| 3097 | }); | 2848 | }); |
| 2849 | const entryState = () => entry.constant === true ? 'constant' : entry.vectorized === true ? 'vectorized' : 'normal'; | ||
| 2850 | entryStateSelector.find(`option[value=${entryState()}]`).prop('selected', true).trigger('input'); | ||
| 2851 | } | ||
| 3098 | 2852 | ||
| 3099 | const entryKillSwitch = template.find('div[name="entryKillSwitch"]'); | 2853 | /** |
| 2854 | * Helper to handle kill switch toggle. | ||
| 2855 | */ | ||
| 2856 | function handleEntryKillSwitchHelper({ entryKillSwitch, entry, data, name, setWIOriginalDataValue, saveWorldInfo, template }) { | ||
| 3100 | entryKillSwitch.data('uid', entry.uid); | 2857 | entryKillSwitch.data('uid', entry.uid); |
| 3101 | entryKillSwitch.on('click', async function (event) { | 2858 | entryKillSwitch.on('click', async function () { |
| 3102 | const uid = entry.uid; | 2859 | const uid = entry.uid; |
| 3103 | data.entries[uid].disable = !data.entries[uid].disable; | 2860 | data.entries[uid].disable = !data.entries[uid].disable; |
| 3104 | const isActive = !data.entries[uid].disable; | 2861 | const isActive = !data.entries[uid].disable; |
| @@ -3107,104 +2864,114 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3107 | entryKillSwitch.toggleClass('fa-toggle-off', !isActive); | 2864 | entryKillSwitch.toggleClass('fa-toggle-off', !isActive); |
| 3108 | entryKillSwitch.toggleClass('fa-toggle-on', isActive); | 2865 | entryKillSwitch.toggleClass('fa-toggle-on', isActive); |
| 3109 | await saveWorldInfo(name, data); | 2866 | await saveWorldInfo(name, data); |
| 3110 | |||
| 3111 | }); | 2867 | }); |
| 3112 | |||
| 3113 | const entryState = function () { | ||
| 3114 | if (entry.constant === true) { | ||
| 3115 | return 'constant'; | ||
| 3116 | } else if (entry.vectorized === true) { | ||
| 3117 | return 'vectorized'; | ||
| 3118 | } else { | ||
| 3119 | return 'normal'; | ||
| 3120 | } | ||
| 3121 | }; | ||
| 3122 | |||
| 3123 | const isActive = !entry.disable; | 2868 | const isActive = !entry.disable; |
| 3124 | template.toggleClass('disabledWIEntry', !isActive); | 2869 | template.toggleClass('disabledWIEntry', !isActive); |
| 3125 | entryKillSwitch.toggleClass('fa-toggle-off', !isActive); | 2870 | entryKillSwitch.toggleClass('fa-toggle-off', !isActive); |
| 3126 | entryKillSwitch.toggleClass('fa-toggle-on', isActive); | 2871 | entryKillSwitch.toggleClass('fa-toggle-on', isActive); |
| 2872 | } | ||
| 2873 | |||
| 2874 | /** | ||
| 2875 | * Main function to build the WI entry editor template. | ||
| 2876 | */ | ||
| 2877 | export async function getWorldEntry(name, data, entry) { | ||
| 2878 | if (!data.entries[entry.uid]) return; | ||
| 3127 | 2879 | ||
| 3128 | template | 2880 | const headerTemplate = WI_ENTRY_HEADER_TEMPLATE.clone(); |
| 3129 | .find(`select[name="entryStateSelector"] option[value=${entryState()}]`) | 2881 | headerTemplate.data('uid', entry.uid); |
| 3130 | .prop('selected', true) | 2882 | headerTemplate.attr('uid', entry.uid); |
| 3131 | .trigger('input'); | ||
| 3132 | 2883 | ||
| 3133 | // exclude recursion | 2884 | if (typeof power_user.wi_key_input_plaintext === 'undefined') power_user.wi_key_input_plaintext = true; |
| 3134 | const excludeRecursionInput = template.find('input[name="exclude_recursion"]'); | 2885 | |
| 3135 | excludeRecursionInput.data('uid', entry.uid); | 2886 | // Comment |
| 3136 | excludeRecursionInput.on('input', async function () { | 2887 | const commentInput = headerTemplate.find('textarea[name="comment"]'); |
| 2888 | commentInput.data('uid', entry.uid); | ||
| 2889 | commentInput.on('input', async function (_, { skipReset } = {}) { | ||
| 3137 | const uid = $(this).data('uid'); | 2890 | const uid = $(this).data('uid'); |
| 3138 | const value = $(this).prop('checked'); | 2891 | const value = $(this).val(); |
| 3139 | data.entries[uid].excludeRecursion = value; | 2892 | !skipReset && await resetScrollHeight(this); |
| 3140 | setWIOriginalDataValue(data, uid, 'extensions.exclude_recursion', data.entries[uid].excludeRecursion); | 2893 | data.entries[uid].comment = value; |
| 2894 | setWIOriginalDataValue(data, uid, 'comment', data.entries[uid].comment); | ||
| 3141 | await saveWorldInfo(name, data); | 2895 | await saveWorldInfo(name, data); |
| 3142 | }); | 2896 | }); |
| 3143 | excludeRecursionInput.prop('checked', entry.excludeRecursion).trigger('input'); | 2897 | commentInput.val(entry.comment).trigger('input', { skipReset: true }); |
| 3144 | 2898 | ||
| 3145 | // prevent recursion | 2899 | // Order |
| 3146 | const preventRecursionInput = template.find('input[name="prevent_recursion"]'); | 2900 | const orderInput = headerTemplate.find('input[name="order"]'); |
| 3147 | preventRecursionInput.data('uid', entry.uid); | 2901 | orderInput.data('uid', entry.uid); |
| 3148 | preventRecursionInput.on('input', async function () { | 2902 | orderInput.on('input', async function () { |
| 3149 | const uid = $(this).data('uid'); | 2903 | const uid = $(this).data('uid'); |
| 3150 | const value = $(this).prop('checked'); | 2904 | const value = Number($(this).val()); |
| 3151 | data.entries[uid].preventRecursion = value; | 2905 | data.entries[uid].order = !isNaN(value) ? value : 0; |
| 3152 | setWIOriginalDataValue(data, uid, 'extensions.prevent_recursion', data.entries[uid].preventRecursion); | 2906 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); |
| 2907 | setWIOriginalDataValue(data, uid, 'insertion_order', data.entries[uid].order); | ||
| 3153 | await saveWorldInfo(name, data); | 2908 | await saveWorldInfo(name, data); |
| 3154 | }); | 2909 | }); |
| 3155 | preventRecursionInput.prop('checked', entry.preventRecursion).trigger('input'); | 2910 | orderInput.val(entry.order).trigger('input'); |
| 3156 | 2911 | orderInput.css('width', 'calc(3em + 15px)'); | |
| 3157 | // delay until recursion | ||
| 3158 | // delay until recursion level | ||
| 3159 | const delayUntilRecursionInput = template.find('input[name="delay_until_recursion"]'); | ||
| 3160 | delayUntilRecursionInput.data('uid', entry.uid); | ||
| 3161 | const delayUntilRecursionLevelInput = template.find('input[name="delayUntilRecursionLevel"]'); | ||
| 3162 | delayUntilRecursionLevelInput.data('uid', entry.uid); | ||
| 3163 | delayUntilRecursionInput.on('input', async function () { | ||
| 3164 | const uid = $(this).data('uid'); | ||
| 3165 | const toggled = $(this).prop('checked'); | ||
| 3166 | |||
| 3167 | // If the value contains a number, we'll take that one (set by the level input), otherwise we can use true/false switch | ||
| 3168 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; | ||
| 3169 | 2912 | ||
| 3170 | if (!toggled) delayUntilRecursionLevelInput.val(''); | 2913 | // Probability |
| 2914 | handleProbabilityInputHelper({ probabilityInput: headerTemplate.find('input[name="probability"]'), data, entry, name, setWIOriginalDataValue, saveWorldInfo }); | ||
| 3171 | 2915 | ||
| 3172 | data.entries[uid].delayUntilRecursion = value; | 2916 | // Depth |
| 3173 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | 2917 | handleNumberInputHelper({ |
| 3174 | await saveWorldInfo(name, data); | 2918 | inputElem: headerTemplate.find('input[name="depth"]'), |
| 2919 | entry, entryKey: 'depth', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 2920 | min: 0, max: MAX_SCAN_DEPTH, clamp: false, | ||
| 3175 | }); | 2921 | }); |
| 3176 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input'); | 2922 | headerTemplate.find('input[name="depth"]').css('width', 'calc(3em + 15px)'); |
| 3177 | delayUntilRecursionLevelInput.on('input', async function () { | 2923 | |
| 2924 | // Position | ||
| 2925 | if (entry.position === undefined) entry.position = 0; | ||
| 2926 | const positionInput = headerTemplate.find('select[name="position"]'); | ||
| 2927 | positionInput.data('uid', entry.uid); | ||
| 2928 | positionInput.on('click', e => e.stopPropagation()); | ||
| 2929 | positionInput.on('input', async function () { | ||
| 3178 | const uid = $(this).data('uid'); | 2930 | const uid = $(this).data('uid'); |
| 3179 | const content = $(this).val(); | 2931 | const value = Number($(this).val()); |
| 3180 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) | 2932 | data.entries[uid].position = !isNaN(value) ? value : 0; |
| 3181 | : content === 1 ? true | 2933 | const depthInput = headerTemplate.find('input[name="depth"]'); |
| 3182 | : !isNaN(Number(content)) ? Number(content) | 2934 | if (value === world_info_position.atDepth) { |
| 3183 | : false; | 2935 | depthInput.prop('disabled', false); |
| 3184 | 2936 | depthInput.css('visibility', 'visible'); | |
| 3185 | data.entries[uid].delayUntilRecursion = value; | 2937 | const role = Number($(this).find(':selected').data('role')); |
| 3186 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | 2938 | data.entries[uid].role = role; |
| 2939 | } else { | ||
| 2940 | depthInput.prop('disabled', true); | ||
| 2941 | depthInput.css('visibility', 'hidden'); | ||
| 2942 | data.entries[uid].role = null; | ||
| 2943 | } | ||
| 2944 | updatePosOrdDisplayHelper({ template: headerTemplate, data, uid }); | ||
| 2945 | setWIOriginalDataValue(data, uid, 'position', data.entries[uid].position == 0 ? 'before_char' : 'after_char'); | ||
| 2946 | setWIOriginalDataValue(data, uid, 'extensions.position', data.entries[uid].position); | ||
| 2947 | setWIOriginalDataValue(data, uid, 'extensions.role', data.entries[uid].role); | ||
| 3187 | await saveWorldInfo(name, data); | 2948 | await saveWorldInfo(name, data); |
| 3188 | }); | 2949 | }); |
| 3189 | // No need to retrigger inpout event, we'll just set the curret current value. It was edited/saved above already | 2950 | const roleValue = entry.position === world_info_position.atDepth ? String(entry.role ?? extension_prompt_roles.SYSTEM) : ''; |
| 3190 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input'); | 2951 | headerTemplate.find(`select[name="position"] option[value="${entry.position}"][data-role="${roleValue}"]`).prop('selected', true).trigger('input'); |
| 2952 | |||
| 2953 | // Tri-state selector | ||
| 2954 | handleEntryStateSelectorHelper({ | ||
| 2955 | entryStateSelector: headerTemplate.find('select[name="entryStateSelector"]'), | ||
| 2956 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 2957 | }); | ||
| 2958 | |||
| 2959 | // Kill switch | ||
| 2960 | handleEntryKillSwitchHelper({ | ||
| 2961 | entryKillSwitch: headerTemplate.find('div[name="entryKillSwitch"]'), | ||
| 2962 | entry, data, name, setWIOriginalDataValue, saveWorldInfo, template: headerTemplate, | ||
| 2963 | }); | ||
| 3191 | 2964 | ||
| 3192 | // duplicate button | 2965 | // Duplicate/delete/move buttons |
| 3193 | const duplicateButton = template.find('.duplicate_entry_button'); | 2966 | headerTemplate.find('.duplicate_entry_button').data('uid', entry.uid).on('click', async function () { |
| 3194 | duplicateButton.data('uid', entry.uid); | ||
| 3195 | duplicateButton.on('click', async function () { | ||
| 3196 | const uid = $(this).data('uid'); | 2967 | const uid = $(this).data('uid'); |
| 3197 | const entry = duplicateWorldInfoEntry(data, uid); | 2968 | const entryDup = duplicateWorldInfoEntry(data, uid); |
| 3198 | if (entry) { | 2969 | if (entryDup) { |
| 3199 | await saveWorldInfo(name, data); | 2970 | await saveWorldInfo(name, data); |
| 3200 | updateEditor(entry.uid); | 2971 | updateEditor(entryDup.uid); |
| 3201 | } | 2972 | } |
| 3202 | }); | 2973 | }); |
| 3203 | 2974 | headerTemplate.find('.delete_entry_button').data('uid', entry.uid).on('click', async function (e) { | |
| 3204 | // delete button | ||
| 3205 | const deleteButton = template.find('.delete_entry_button'); | ||
| 3206 | deleteButton.data('uid', entry.uid); | ||
| 3207 | deleteButton.on('click', async function (e) { | ||
| 3208 | e.stopPropagation(); | 2975 | e.stopPropagation(); |
| 3209 | const uid = $(this).data('uid'); | 2976 | const uid = $(this).data('uid'); |
| 3210 | const deleted = await deleteWorldInfoEntry(data, uid); | 2977 | const deleted = await deleteWorldInfoEntry(data, uid); |
| @@ -3213,36 +2980,24 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3213 | await saveWorldInfo(name, data); | 2980 | await saveWorldInfo(name, data); |
| 3214 | updateEditor(navigation_option.previous); | 2981 | updateEditor(navigation_option.previous); |
| 3215 | }); | 2982 | }); |
| 3216 | 2983 | headerTemplate.find('.move_entry_button').attr('data-uid', entry.uid).attr('data-current-world', name).on('click', async function (e) { | |
| 3217 | // move button | ||
| 3218 | const moveButton = template.find('.move_entry_button'); | ||
| 3219 | moveButton.attr('data-uid', entry.uid); | ||
| 3220 | moveButton.attr('data-current-world', name); | ||
| 3221 | moveButton.on('click', async function (e) { | ||
| 3222 | e.stopPropagation(); | 2984 | e.stopPropagation(); |
| 3223 | const sourceUid = $(this).attr('data-uid'); | 2985 | const sourceUid = $(this).attr('data-uid'); |
| 3224 | const sourceWorld = $(this).attr('data-current-world'); | 2986 | const sourceWorld = $(this).attr('data-current-world'); |
| 3225 | const sourceWorldInfo = await loadWorldInfo(sourceWorld); | 2987 | const sourceWorldInfo = await loadWorldInfo(sourceWorld); |
| 3226 | if (!sourceWorldInfo) { | 2988 | if (!sourceWorldInfo) return; |
| 3227 | return; | ||
| 3228 | } | ||
| 3229 | const sourceName = sourceWorldInfo.entries[sourceUid]?.comment; | 2989 | const sourceName = sourceWorldInfo.entries[sourceUid]?.comment; |
| 3230 | if (sourceName === undefined) { | 2990 | if (sourceName === undefined) return; |
| 3231 | return; | ||
| 3232 | } | ||
| 3233 | |||
| 3234 | const select = document.createElement('select'); | 2991 | const select = document.createElement('select'); |
| 3235 | select.id = 'move_entry_target_select'; | 2992 | select.id = 'move_entry_target_select'; |
| 3236 | select.classList.add('text_pole', 'wide100p', 'marginTop10'); | 2993 | select.classList.add('text_pole', 'wide100p', 'marginTop10'); |
| 3237 | |||
| 3238 | const defaultOption = document.createElement('option'); | 2994 | const defaultOption = document.createElement('option'); |
| 3239 | defaultOption.value = ''; | 2995 | defaultOption.value = ''; |
| 3240 | defaultOption.textContent = `-- ${t`Select Target Lorebook`} --`; | 2996 | defaultOption.textContent = `-- ${t`Select Target Lorebook`} --`; |
| 3241 | select.appendChild(defaultOption); | 2997 | select.appendChild(defaultOption); |
| 3242 | |||
| 3243 | let selectableWorldCount = 0; | 2998 | let selectableWorldCount = 0; |
| 3244 | world_names.forEach(worldName => { | 2999 | world_names.forEach(worldName => { |
| 3245 | if (worldName !== sourceWorld) { // Exclude current world | 3000 | if (worldName !== sourceWorld) { |
| 3246 | const option = document.createElement('option'); | 3001 | const option = document.createElement('option'); |
| 3247 | option.value = world_names.indexOf(worldName).toString(); | 3002 | option.value = world_names.indexOf(worldName).toString(); |
| 3248 | option.textContent = worldName; | 3003 | option.textContent = worldName; |
| @@ -3250,177 +3005,343 @@ export async function getWorldEntry(name, data, entry) { | |||
| 3250 | selectableWorldCount++; | 3005 | selectableWorldCount++; |
| 3251 | } | 3006 | } |
| 3252 | }); | 3007 | }); |
| 3253 | |||
| 3254 | if (selectableWorldCount === 0) { | 3008 | if (selectableWorldCount === 0) { |
| 3255 | toastr.warning(t`There are no other lorebooks to move to.`); | 3009 | toastr.warning(t`There are no other lorebooks to move to.`); |
| 3256 | return; | 3010 | return; |
| 3257 | } | 3011 | } |
| 3258 | |||
| 3259 | // Create wrapper div | ||
| 3260 | const wrapper = document.createElement('div'); | 3012 | const wrapper = document.createElement('div'); |
| 3261 | wrapper.textContent = t`Move '${sourceName}' to:`; | 3013 | wrapper.textContent = t`Move '${sourceName}' to:`; |
| 3262 | |||
| 3263 | // Create container and append elements | ||
| 3264 | const container = document.createElement('div'); | 3014 | const container = document.createElement('div'); |
| 3265 | container.appendChild(wrapper); | 3015 | container.appendChild(wrapper); |
| 3266 | container.appendChild(select); | 3016 | container.appendChild(select); |
| 3267 | |||
| 3268 | let selectedWorldIndex = -1; | 3017 | let selectedWorldIndex = -1; |
| 3269 | select.addEventListener('change', function() { | 3018 | select.addEventListener('change', function () { |
| 3270 | selectedWorldIndex = this.value === '' ? -1 : Number(this.value); | 3019 | selectedWorldIndex = this.value === '' ? -1 : Number(this.value); |
| 3271 | }); | 3020 | }); |
| 3272 | |||
| 3273 | const popupConfirm = await callGenericPopup(container, POPUP_TYPE.CONFIRM, '', { | 3021 | const popupConfirm = await callGenericPopup(container, POPUP_TYPE.CONFIRM, '', { |
| 3274 | okButton: t`Move`, | 3022 | okButton: t`Move`, |
| 3275 | cancelButton: t`Cancel`, | 3023 | cancelButton: t`Cancel`, |
| 3276 | }); | 3024 | }); |
| 3277 | if (!popupConfirm) { | 3025 | if (!popupConfirm) return; |
| 3278 | return; | 3026 | if (selectedWorldIndex === -1) return; |
| 3279 | } | ||
| 3280 | |||
| 3281 | if (selectedWorldIndex === -1) { | ||
| 3282 | return; | ||
| 3283 | } | ||
| 3284 | |||
| 3285 | const selectedValue = world_names[selectedWorldIndex]; | 3027 | const selectedValue = world_names[selectedWorldIndex]; |
| 3286 | |||
| 3287 | if (!selectedValue) { | 3028 | if (!selectedValue) { |
| 3288 | toastr.warning(t`Please select a target lorebook.`); | 3029 | toastr.warning(t`Please select a target lorebook.`); |
| 3289 | return; | 3030 | return; |
| 3290 | } | 3031 | } |
| 3291 | |||
| 3292 | await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid); | 3032 | await moveWorldInfoEntry(sourceWorld, selectedValue, sourceUid); |
| 3293 | }); | 3033 | }); |
| 3294 | 3034 | ||
| 3295 | // scan depth | 3035 | let drawerInitialized = false; |
| 3296 | const scanDepthInput = template.find('input[name="scanDepth"]'); | 3036 | let drawerDestroyTimeout = null; |
| 3297 | scanDepthInput.data('uid', entry.uid); | 3037 | headerTemplate.find('.inline-drawer').on('inline-drawer-toggle', function () { |
| 3298 | scanDepthInput.on('input', async function () { | 3038 | if (drawerDestroyTimeout) { |
| 3299 | const uid = $(this).data('uid'); | 3039 | clearTimeout(drawerDestroyTimeout); |
| 3300 | const isEmpty = $(this).val() === ''; | 3040 | drawerDestroyTimeout = null; |
| 3301 | const value = Number($(this).val()); | 3041 | } |
| 3302 | 3042 | if (drawerInitialized) { | |
| 3303 | // Clamp if necessary | 3043 | drawerDestroyTimeout = setTimeout(() => { |
| 3304 | if (value < 0) { | 3044 | // Drawer was reopened, so we don't destroy it |
| 3305 | $(this).val(0).trigger('input'); | 3045 | if (editOutlet.is(':visible')) { |
| 3306 | toastr.warning('Scan depth cannot be negative'); | 3046 | return; |
| 3307 | return; | 3047 | } |
| 3308 | } | 3048 | drawerInitialized = false; |
| 3309 | 3049 | clearEntryList(editOutlet); | |
| 3310 | if (value > MAX_SCAN_DEPTH) { | 3050 | drawerDestroyTimeout = null; |
| 3311 | $(this).val(MAX_SCAN_DEPTH).trigger('input'); | 3051 | }, debounce_timeout.relaxed); |
| 3312 | toastr.warning(`Scan depth cannot exceed ${MAX_SCAN_DEPTH}`); | 3052 | } else { |
| 3313 | return; | 3053 | drawerInitialized = true; |
| 3054 | addEditorDrawerContent(); | ||
| 3314 | } | 3055 | } |
| 3315 | |||
| 3316 | data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null; | ||
| 3317 | setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth); | ||
| 3318 | await saveWorldInfo(name, data); | ||
| 3319 | }); | 3056 | }); |
| 3320 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input'); | ||
| 3321 | 3057 | ||
| 3322 | // case sensitive select | 3058 | const editOutlet = headerTemplate.find('.inline-drawer-outlet'); |
| 3323 | const caseSensitiveSelect = template.find('select[name="caseSensitive"]'); | ||
| 3324 | caseSensitiveSelect.data('uid', entry.uid); | ||
| 3325 | caseSensitiveSelect.on('input', async function () { | ||
| 3326 | const uid = $(this).data('uid'); | ||
| 3327 | const value = $(this).val(); | ||
| 3328 | 3059 | ||
| 3329 | data.entries[uid].caseSensitive = value === 'null' ? null : value === 'true'; | 3060 | function addEditorDrawerContent() { |
| 3330 | setWIOriginalDataValue(data, uid, 'extensions.case_sensitive', data.entries[uid].caseSensitive); | 3061 | const editTemplate = WI_ENTRY_EDIT_TEMPLATE.clone(); |
| 3331 | await saveWorldInfo(name, data); | ||
| 3332 | }); | ||
| 3333 | caseSensitiveSelect.val((entry.caseSensitive === null || entry.caseSensitive === undefined) ? 'null' : entry.caseSensitive ? 'true' : 'false').trigger('input'); | ||
| 3334 | 3062 | ||
| 3335 | // match whole words select | 3063 | // UID display |
| 3336 | const matchWholeWordsSelect = template.find('select[name="matchWholeWords"]'); | 3064 | editTemplate.find('.world_entry_form_uid_value').text(`(UID: ${entry.uid})`); |
| 3337 | matchWholeWordsSelect.data('uid', entry.uid); | ||
| 3338 | matchWholeWordsSelect.on('input', async function () { | ||
| 3339 | const uid = $(this).data('uid'); | ||
| 3340 | const value = $(this).val(); | ||
| 3341 | 3065 | ||
| 3342 | data.entries[uid].matchWholeWords = value === 'null' ? null : value === 'true'; | 3066 | // Key inputs |
| 3343 | setWIOriginalDataValue(data, uid, 'extensions.match_whole_words', data.entries[uid].matchWholeWords); | 3067 | const keyInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'key', originalDataValueName: 'keys', name, data }); |
| 3344 | await saveWorldInfo(name, data); | 3068 | const keySecondaryInput = enableKeysInputHelper({ template: editTemplate, entry, entryPropName: 'keysecondary', originalDataValueName: 'secondary_keys', name, data }); |
| 3345 | }); | 3069 | if (!keyInput.isFancy) initScrollHeight(keyInput.control); |
| 3346 | matchWholeWordsSelect.val((entry.matchWholeWords === null || entry.matchWholeWords === undefined) ? 'null' : entry.matchWholeWords ? 'true' : 'false').trigger('input'); | 3070 | if (!keySecondaryInput.isFancy) initScrollHeight(keySecondaryInput.control); |
| 3347 | 3071 | ||
| 3348 | // use group scoring select | 3072 | // Key input switch |
| 3349 | const useGroupScoringSelect = template.find('select[name="useGroupScoring"]'); | 3073 | editTemplate.find('.switch_input_type_icon').on('click', function () { |
| 3350 | useGroupScoringSelect.data('uid', entry.uid); | 3074 | power_user.wi_key_input_plaintext = !power_user.wi_key_input_plaintext; |
| 3351 | useGroupScoringSelect.on('input', async function () { | 3075 | saveSettingsDebounced(); |
| 3352 | const uid = $(this).data('uid'); | 3076 | const uid = ($(this).parents('.world_entry')).data('uid'); |
| 3353 | const value = $(this).val(); | 3077 | updateEditor(uid, false); |
| 3078 | $(`.world_entry[uid="${uid}"] .inline-drawer-icon`).trigger('click'); | ||
| 3079 | }).each((_, icon) => { | ||
| 3080 | $(icon).attr('title', $(icon).data(power_user.wi_key_input_plaintext ? 'tooltip-on' : 'tooltip-off')); | ||
| 3081 | $(icon).text($(icon).data(power_user.wi_key_input_plaintext ? 'icon-on' : 'icon-off')); | ||
| 3082 | }); | ||
| 3354 | 3083 | ||
| 3355 | data.entries[uid].useGroupScoring = value === 'null' ? null : value === 'true'; | 3084 | // Probability toggle |
| 3356 | setWIOriginalDataValue(data, uid, 'extensions.use_group_scoring', data.entries[uid].useGroupScoring); | 3085 | handleProbabilityToggleHelper({ |
| 3357 | await saveWorldInfo(name, data); | 3086 | probabilityToggle: editTemplate.find('input[name="useProbability"]'), |
| 3358 | }); | 3087 | data, entry, name, |
| 3359 | useGroupScoringSelect.val((entry.useGroupScoring === null || entry.useGroupScoring === undefined) ? 'null' : entry.useGroupScoring ? 'true' : 'false').trigger('input'); | 3088 | probabilityInput: headerTemplate.find('input[name="probability"]'), |
| 3089 | setWIOriginalDataValue, saveWorldInfo, | ||
| 3090 | }); | ||
| 3360 | 3091 | ||
| 3361 | function handleMatchCheckbox(fieldName) { | 3092 | // Comment toggle |
| 3362 | const key = originalWIDataKeyMap[fieldName]; | 3093 | const commentToggle = editTemplate.find('input[name="addMemo"]'); |
| 3363 | const checkBoxElem = template.find(`input[type="checkbox"][name="${fieldName}"]`); | 3094 | commentToggle.data('uid', entry.uid); |
| 3364 | checkBoxElem.data('uid', entry.uid); | 3095 | commentToggle.on('input', async function () { |
| 3365 | checkBoxElem.on('input', async function () { | ||
| 3366 | const uid = $(this).data('uid'); | 3096 | const uid = $(this).data('uid'); |
| 3367 | const value = $(this).prop('checked'); | 3097 | const value = $(this).prop('checked'); |
| 3098 | const commentContainer = $(this).closest('.world_entry').find('.commentContainer'); | ||
| 3099 | data.entries[uid].addMemo = value; | ||
| 3100 | await saveWorldInfo(name, data); | ||
| 3101 | value ? commentContainer.show() : commentContainer.hide(); | ||
| 3102 | }); | ||
| 3103 | commentToggle.prop('checked', true).trigger('input'); | ||
| 3104 | commentToggle.parent().hide(); | ||
| 3105 | |||
| 3106 | // Logic AND/NOT | ||
| 3107 | const selectiveLogicDropdown = editTemplate.find('select[name="entryLogicType"]'); | ||
| 3108 | selectiveLogicDropdown.data('uid', entry.uid); | ||
| 3109 | selectiveLogicDropdown.on('click', e => e.stopPropagation()); | ||
| 3110 | selectiveLogicDropdown.on('input', async function () { | ||
| 3111 | const uid = $(this).data('uid'); | ||
| 3112 | const value = Number($(this).val()); | ||
| 3113 | data.entries[uid].selectiveLogic = !isNaN(value) ? value : world_info_logic.AND_ANY; | ||
| 3114 | setWIOriginalDataValue(data, uid, 'selectiveLogic', data.entries[uid].selectiveLogic); | ||
| 3115 | await saveWorldInfo(name, data); | ||
| 3116 | }); | ||
| 3117 | editTemplate.find(`select[name="entryLogicType"] option[value=${entry.selectiveLogic}]`).prop('selected', true).trigger('input'); | ||
| 3368 | 3118 | ||
| 3369 | data.entries[uid][fieldName] = value; | 3119 | // Selective |
| 3370 | setWIOriginalDataValue(data, uid, key, data.entries[uid][fieldName]); | 3120 | const selectiveInput = editTemplate.find('input[name="selective"]'); |
| 3121 | selectiveInput.data('uid', entry.uid); | ||
| 3122 | selectiveInput.on('input', async function () { | ||
| 3123 | const uid = $(this).data('uid'); | ||
| 3124 | const value = $(this).prop('checked'); | ||
| 3125 | data.entries[uid].selective = value; | ||
| 3126 | setWIOriginalDataValue(data, uid, 'selective', data.entries[uid].selective); | ||
| 3371 | await saveWorldInfo(name, data); | 3127 | await saveWorldInfo(name, data); |
| 3128 | const keysecondary = $(this).closest('.world_entry').find('.keysecondary'); | ||
| 3129 | const keysecondarytextpole = $(this).closest('.world_entry').find('.keysecondarytextpole'); | ||
| 3130 | const keyprimaryselect = $(this).closest('.world_entry').find('.keyprimaryselect'); | ||
| 3131 | const keyprimaryHeight = keyprimaryselect.outerHeight(); | ||
| 3132 | keysecondarytextpole.css('height', keyprimaryHeight + 'px'); | ||
| 3133 | value ? keysecondary.show() : keysecondary.hide(); | ||
| 3134 | }); | ||
| 3135 | selectiveInput.prop('checked', true).trigger('input'); | ||
| 3136 | selectiveInput.parent().hide(); | ||
| 3137 | |||
| 3138 | // Character filter | ||
| 3139 | const characterFilterLabel = editTemplate.find('label[for="characterFilter"] > small'); | ||
| 3140 | characterFilterLabel.text(entry.characterFilter?.isExclude ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 3141 | const characterExclusionInput = editTemplate.find('input[name="character_exclusion"]'); | ||
| 3142 | characterExclusionInput.data('uid', entry.uid); | ||
| 3143 | characterExclusionInput.on('input', async function () { | ||
| 3144 | const uid = $(this).data('uid'); | ||
| 3145 | const value = $(this).prop('checked'); | ||
| 3146 | characterFilterLabel.text(value ? 'Exclude Character(s)' : 'Filter to Character(s)'); | ||
| 3147 | if (data.entries[uid].characterFilter) { | ||
| 3148 | if (!value && data.entries[uid].characterFilter.names.length === 0 && data.entries[uid].characterFilter.tags.length === 0) { | ||
| 3149 | delete data.entries[uid].characterFilter; | ||
| 3150 | } else { | ||
| 3151 | data.entries[uid].characterFilter.isExclude = value; | ||
| 3152 | } | ||
| 3153 | } else if (value) { | ||
| 3154 | Object.assign(data.entries[uid], { characterFilter: { isExclude: true, names: [], tags: [] } }); | ||
| 3155 | } | ||
| 3156 | if (data.entries[uid]?.characterFilter?.names?.length > 0) { | ||
| 3157 | for (const name of [...data.entries[uid].characterFilter.names]) { | ||
| 3158 | if (!getContext().characters.find(x => x.avatar.replace(/\.[^/.]+$/, '') === name)) { | ||
| 3159 | data.entries[uid].characterFilter.names = data.entries[uid].characterFilter.names.filter(x => x !== name); | ||
| 3160 | } | ||
| 3161 | } | ||
| 3162 | } | ||
| 3163 | setWIOriginalDataValue(data, uid, 'character_filter', data.entries[uid].characterFilter); | ||
| 3164 | await saveWorldInfo(name, data); | ||
| 3165 | }); | ||
| 3166 | characterExclusionInput.prop('checked', entry.characterFilter?.isExclude ?? false).trigger('input'); | ||
| 3167 | |||
| 3168 | const characterFilter = editTemplate.find('select[name="characterFilter"]'); | ||
| 3169 | characterFilter.data('uid', entry.uid); | ||
| 3170 | initCharacterFilterSelect2Helper(characterFilter, t); | ||
| 3171 | fillCharacterAndTagOptionsHelper({ characterFilter, entry, getContext }); | ||
| 3172 | handleCharacterFilterChangeHelper({ | ||
| 3173 | characterFilter, data, entry, name, world_names, getContext, setWIOriginalDataValue, saveWorldInfo, t, | ||
| 3372 | }); | 3174 | }); |
| 3373 | checkBoxElem.prop('checked', !!entry[fieldName]).trigger('input'); | ||
| 3374 | } | ||
| 3375 | 3175 | ||
| 3376 | handleMatchCheckbox('matchPersonaDescription'); | 3176 | // Content |
| 3377 | handleMatchCheckbox('matchCharacterDescription'); | 3177 | const counter = editTemplate.find('.world_entry_form_token_counter'); |
| 3378 | handleMatchCheckbox('matchCharacterPersonality'); | 3178 | const countTokensDebounced = debounce(async function (counter, value) { |
| 3379 | handleMatchCheckbox('matchCharacterDepthPrompt'); | 3179 | const numberOfTokens = await getTokenCountAsync(value); |
| 3380 | handleMatchCheckbox('matchScenario'); | 3180 | $(counter).text(numberOfTokens); |
| 3381 | handleMatchCheckbox('matchCreatorNotes'); | 3181 | }, debounce_timeout.relaxed); |
| 3182 | const contentInputId = `world_entry_content_${entry.uid}`; | ||
| 3183 | const contentInput = editTemplate.find('textarea[name="content"]'); | ||
| 3184 | contentInput.data('uid', entry.uid); | ||
| 3185 | contentInput.attr('id', contentInputId); | ||
| 3186 | contentInput.on('input', async function (_, { skipCount } = {}) { | ||
| 3187 | const uid = $(this).data('uid'); | ||
| 3188 | const value = $(this).val(); | ||
| 3189 | data.entries[uid].content = value; | ||
| 3190 | setWIOriginalDataValue(data, uid, 'content', data.entries[uid].content); | ||
| 3191 | await saveWorldInfo(name, data); | ||
| 3192 | if (!skipCount) countTokensDebounced(counter, value); | ||
| 3193 | }); | ||
| 3194 | contentInput.val(entry.content).trigger('input', { skipCount: true }); | ||
| 3195 | editTemplate.find('.editor_maximize').attr('data-for', contentInputId); | ||
| 3382 | 3196 | ||
| 3383 | // automation id | 3197 | // Scan depth |
| 3384 | const automationIdInput = template.find('input[name="automationId"]'); | 3198 | const scanDepthInput = editTemplate.find('input[name="scanDepth"]'); |
| 3385 | automationIdInput.data('uid', entry.uid); | 3199 | scanDepthInput.data('uid', entry.uid); |
| 3386 | automationIdInput.on('input', async function () { | 3200 | scanDepthInput.on('input', async function () { |
| 3387 | const uid = $(this).data('uid'); | 3201 | const uid = $(this).data('uid'); |
| 3388 | const value = $(this).val(); | 3202 | const isEmpty = $(this).val() === ''; |
| 3203 | const value = Number($(this).val()); | ||
| 3204 | if (value < 0) { | ||
| 3205 | $(this).val(0).trigger('input'); | ||
| 3206 | toastr.warning('Scan depth cannot be negative'); | ||
| 3207 | return; | ||
| 3208 | } | ||
| 3209 | if (value > MAX_SCAN_DEPTH) { | ||
| 3210 | $(this).val(MAX_SCAN_DEPTH).trigger('input'); | ||
| 3211 | toastr.warning(`Scan depth cannot exceed ${MAX_SCAN_DEPTH}`); | ||
| 3212 | return; | ||
| 3213 | } | ||
| 3214 | data.entries[uid].scanDepth = !isEmpty && !isNaN(value) && value >= 0 && value <= MAX_SCAN_DEPTH ? Math.floor(value) : null; | ||
| 3215 | setWIOriginalDataValue(data, uid, 'extensions.scan_depth', data.entries[uid].scanDepth); | ||
| 3216 | await saveWorldInfo(name, data); | ||
| 3217 | }); | ||
| 3218 | scanDepthInput.val(entry.scanDepth ?? null).trigger('input'); | ||
| 3389 | 3219 | ||
| 3390 | data.entries[uid].automationId = value; | 3220 | // Group |
| 3391 | setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId); | 3221 | const groupInput = editTemplate.find('input[name="group"]'); |
| 3392 | await saveWorldInfo(name, data); | 3222 | groupInput.data('uid', entry.uid); |
| 3393 | }); | 3223 | groupInput.on('input', async function () { |
| 3394 | automationIdInput.val(entry.automationId ?? '').trigger('input'); | 3224 | const uid = $(this).data('uid'); |
| 3395 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); | 3225 | const value = String($(this).val()).trim(); |
| 3226 | data.entries[uid].group = value; | ||
| 3227 | setWIOriginalDataValue(data, uid, 'extensions.group', data.entries[uid].group); | ||
| 3228 | await saveWorldInfo(name, data); | ||
| 3229 | }); | ||
| 3230 | groupInput.val(entry.group ?? '').trigger('input'); | ||
| 3231 | setTimeout(() => createEntryInputAutocomplete(groupInput, getInclusionGroupCallback(data), { allowMultiple: true }), 1); | ||
| 3396 | 3232 | ||
| 3397 | template.find('.inline-drawer-content').css('display', 'none'); //entries start collapsed | 3233 | // Inclusion priority |
| 3234 | const groupOverrideInput = editTemplate.find('input[name="groupOverride"]'); | ||
| 3235 | groupOverrideInput.data('uid', entry.uid); | ||
| 3236 | groupOverrideInput.on('input', async function () { | ||
| 3237 | const uid = $(this).data('uid'); | ||
| 3238 | const value = $(this).prop('checked'); | ||
| 3239 | data.entries[uid].groupOverride = value; | ||
| 3240 | setWIOriginalDataValue(data, uid, 'extensions.group_override', data.entries[uid].groupOverride); | ||
| 3241 | await saveWorldInfo(name, data); | ||
| 3242 | }); | ||
| 3243 | groupOverrideInput.prop('checked', entry.groupOverride).trigger('input'); | ||
| 3398 | 3244 | ||
| 3399 | function updatePosOrdDisplay(uid) { | 3245 | // Group weight |
| 3400 | // display position/order info left of keyword box | 3246 | handleNumberInputHelper({ |
| 3401 | let entry = data.entries[uid]; | 3247 | inputElem: editTemplate.find('input[name="groupWeight"]'), |
| 3402 | let posText = entry.position; | 3248 | entry, entryKey: 'groupWeight', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3403 | switch (entry.position) { | 3249 | min: 1, max: 10000, clamp: true, |
| 3404 | case 0: | 3250 | }); |
| 3405 | posText = '↑CD'; | 3251 | |
| 3406 | break; | 3252 | // Sticky, cooldown, delay |
| 3407 | case 1: | 3253 | handleNumberInputHelper({ |
| 3408 | posText = 'CD↓'; | 3254 | inputElem: editTemplate.find('input[name="sticky"]'), |
| 3409 | break; | 3255 | entry, entryKey: 'sticky', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3410 | case 2: | 3256 | min: 1, max: 10000, clamp: false, |
| 3411 | posText = '↑AN'; | 3257 | }); |
| 3412 | break; | 3258 | handleNumberInputHelper({ |
| 3413 | case 3: | 3259 | inputElem: editTemplate.find('input[name="cooldown"]'), |
| 3414 | posText = 'AN↓'; | 3260 | entry, entryKey: 'cooldown', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3415 | break; | 3261 | min: 1, max: 10000, clamp: false, |
| 3416 | case 4: | 3262 | }); |
| 3417 | posText = `@D${entry.depth}`; | 3263 | handleNumberInputHelper({ |
| 3418 | break; | 3264 | inputElem: editTemplate.find('input[name="delay"]'), |
| 3419 | } | 3265 | entry, entryKey: 'delay', data, name, setWIOriginalDataValue, saveWorldInfo, |
| 3420 | template.find('.world_entry_form_position_value').text(`(${posText} ${entry.order})`); | 3266 | min: 1, max: 10000, clamp: false, |
| 3267 | }); | ||
| 3268 | |||
| 3269 | // Exclude/prevent recursion | ||
| 3270 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'excludeRecursion', data, name }); | ||
| 3271 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'preventRecursion', data, name }); | ||
| 3272 | |||
| 3273 | // Delay until recursion | ||
| 3274 | const delayUntilRecursionInput = editTemplate.find('input[name="delay_until_recursion"]'); | ||
| 3275 | delayUntilRecursionInput.data('uid', entry.uid); | ||
| 3276 | const delayUntilRecursionLevelInput = editTemplate.find('input[name="delayUntilRecursionLevel"]'); | ||
| 3277 | delayUntilRecursionLevelInput.data('uid', entry.uid); | ||
| 3278 | delayUntilRecursionInput.on('input', async function () { | ||
| 3279 | const uid = $(this).data('uid'); | ||
| 3280 | const toggled = $(this).prop('checked'); | ||
| 3281 | const value = toggled ? data.entries[uid].delayUntilRecursion || true : false; | ||
| 3282 | if (!toggled) delayUntilRecursionLevelInput.val(''); | ||
| 3283 | data.entries[uid].delayUntilRecursion = value; | ||
| 3284 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3285 | await saveWorldInfo(name, data); | ||
| 3286 | }); | ||
| 3287 | delayUntilRecursionInput.prop('checked', entry.delayUntilRecursion).trigger('input'); | ||
| 3288 | delayUntilRecursionLevelInput.on('input', async function () { | ||
| 3289 | const uid = $(this).data('uid'); | ||
| 3290 | const content = $(this).val(); | ||
| 3291 | const value = content === '' ? (typeof data.entries[uid].delayUntilRecursion === 'boolean' ? data.entries[uid].delayUntilRecursion : true) | ||
| 3292 | : content === 1 ? true | ||
| 3293 | : !isNaN(Number(content)) ? Number(content) | ||
| 3294 | : false; | ||
| 3295 | data.entries[uid].delayUntilRecursion = value; | ||
| 3296 | setWIOriginalDataValue(data, uid, 'extensions.delay_until_recursion', data.entries[uid].delayUntilRecursion); | ||
| 3297 | await saveWorldInfo(name, data); | ||
| 3298 | }); | ||
| 3299 | delayUntilRecursionLevelInput.val(['number', 'string'].includes(typeof entry.delayUntilRecursion) ? entry.delayUntilRecursion : '').trigger('input'); | ||
| 3300 | |||
| 3301 | // Boolean selects | ||
| 3302 | handleBooleanSelectHelper({ | ||
| 3303 | selectElem: editTemplate.find('select[name="caseSensitive"]'), | ||
| 3304 | entry, entryKey: 'caseSensitive', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3305 | }); | ||
| 3306 | handleBooleanSelectHelper({ | ||
| 3307 | selectElem: editTemplate.find('select[name="matchWholeWords"]'), | ||
| 3308 | entry, entryKey: 'matchWholeWords', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3309 | }); | ||
| 3310 | handleBooleanSelectHelper({ | ||
| 3311 | selectElem: editTemplate.find('select[name="useGroupScoring"]'), | ||
| 3312 | entry, entryKey: 'useGroupScoring', data, name, setWIOriginalDataValue, saveWorldInfo, | ||
| 3313 | }); | ||
| 3314 | |||
| 3315 | // Match checkboxes | ||
| 3316 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchPersonaDescription', data, name }); | ||
| 3317 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDescription', data, name }); | ||
| 3318 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterPersonality', data, name }); | ||
| 3319 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCharacterDepthPrompt', data, name }); | ||
| 3320 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchScenario', data, name }); | ||
| 3321 | handleMatchCheckboxHelper({ template: editTemplate, entry, fieldName: 'matchCreatorNotes', data, name }); | ||
| 3322 | |||
| 3323 | // Automation ID | ||
| 3324 | const automationIdInput = editTemplate.find('input[name="automationId"]'); | ||
| 3325 | automationIdInput.data('uid', entry.uid); | ||
| 3326 | automationIdInput.on('input', async function () { | ||
| 3327 | const uid = $(this).data('uid'); | ||
| 3328 | const value = $(this).val(); | ||
| 3329 | data.entries[uid].automationId = value; | ||
| 3330 | setWIOriginalDataValue(data, uid, 'extensions.automation_id', data.entries[uid].automationId); | ||
| 3331 | await saveWorldInfo(name, data); | ||
| 3332 | }); | ||
| 3333 | automationIdInput.val(entry.automationId ?? '').trigger('input'); | ||
| 3334 | setTimeout(() => createEntryInputAutocomplete(automationIdInput, getAutomationIdCallback(data)), 1); | ||
| 3335 | |||
| 3336 | countTokensDebounced(counter, contentInput.val()); | ||
| 3337 | |||
| 3338 | editTemplate.find('.inline-drawer-content').css('display', 'none'); | ||
| 3339 | editOutlet.append(editTemplate); | ||
| 3421 | } | 3340 | } |
| 3422 | 3341 | ||
| 3423 | return template; | 3342 | headerTemplate.find('.inline-drawer-content').css('display', 'none'); |
| 3343 | |||
| 3344 | return headerTemplate; | ||
| 3424 | } | 3345 | } |
| 3425 | 3346 | ||
| 3426 | /** | 3347 | /** |
| @@ -3661,6 +3582,11 @@ async function _save(name, data) { | |||
| 3661 | * @return {Promise<void>} A promise that resolves when the world info is saved | 3582 | * @return {Promise<void>} A promise that resolves when the world info is saved |
| 3662 | */ | 3583 | */ |
| 3663 | export async function saveWorldInfo(name, data, immediately = false) { | 3584 | export async function saveWorldInfo(name, data, immediately = false) { |
| 3585 | // Saving is temporarily disabled | ||
| 3586 | if (isSaveWorldInfoDisabled) { | ||
| 3587 | return; | ||
| 3588 | } | ||
| 3589 | |||
| 3664 | if (!name || !data) { | 3590 | if (!name || !data) { |
| 3665 | return; | 3591 | return; |
| 3666 | } | 3592 | } |
| @@ -3819,7 +3745,7 @@ export async function createNewWorldInfo(worldName, { interactive = false } = {} | |||
| 3819 | if (selectedIndex !== -1) { | 3745 | if (selectedIndex !== -1) { |
| 3820 | $('#world_editor_select').val(selectedIndex).trigger('change'); | 3746 | $('#world_editor_select').val(selectedIndex).trigger('change'); |
| 3821 | } else { | 3747 | } else { |
| 3822 | hideWorldEditor(); | 3748 | await hideWorldEditor(); |
| 3823 | } | 3749 | } |
| 3824 | 3750 | ||
| 3825 | return true; | 3751 | return true; |
| @@ -4067,6 +3993,8 @@ function parseDecorators(content) { | |||
| 4067 | * @property {Set<any>} allActivatedEntries All entries. | 3993 | * @property {Set<any>} allActivatedEntries All entries. |
| 4068 | * @returns {Promise<WIActivated>} The world info activated. | 3994 | * @returns {Promise<WIActivated>} The world info activated. |
| 4069 | */ | 3995 | */ |
| 3996 | |||
| 3997 | //MARK: checkWorldInfo | ||
| 4070 | export async function checkWorldInfo(chat, maxContext, isDryRun, globalScanData) { | 3998 | export async function checkWorldInfo(chat, maxContext, isDryRun, globalScanData) { |
| 4071 | const context = getContext(); | 3999 | const context = getContext(); |
| 4072 | const buffer = new WorldInfoBuffer(chat, globalScanData); | 4000 | const buffer = new WorldInfoBuffer(chat, globalScanData); |
| @@ -5385,7 +5313,7 @@ export function initWorldInfo() { | |||
| 5385 | const selectedIndex = String($('#world_editor_select').find(':selected').val()); | 5313 | const selectedIndex = String($('#world_editor_select').find(':selected').val()); |
| 5386 | 5314 | ||
| 5387 | if (selectedIndex === '') { | 5315 | if (selectedIndex === '') { |
| 5388 | hideWorldEditor(); | 5316 | await hideWorldEditor(); |
| 5389 | } else { | 5317 | } else { |
| 5390 | const worldName = world_names[selectedIndex]; | 5318 | const worldName = world_names[selectedIndex]; |
| 5391 | showWorldEditor(worldName); | 5319 | showWorldEditor(worldName); |
| @@ -5537,9 +5465,12 @@ export function initWorldInfo() { | |||
| 5537 | select2ChoiceClickSubscribe($('#world_info'), target => { | 5465 | select2ChoiceClickSubscribe($('#world_info'), target => { |
| 5538 | const name = $(target).text(); | 5466 | const name = $(target).text(); |
| 5539 | const selectedIndex = world_names.indexOf(name); | 5467 | const selectedIndex = world_names.indexOf(name); |
| 5540 | if (selectedIndex !== -1) { | 5468 | const alreadySelectedInEditor = $('#world_editor_select option:selected').text() === name; |
| 5469 | if (selectedIndex !== -1 && !alreadySelectedInEditor) { | ||
| 5541 | $('#world_editor_select').val(selectedIndex).trigger('change'); | 5470 | $('#world_editor_select').val(selectedIndex).trigger('change'); |
| 5542 | console.log('Quick selection of world', name); | 5471 | console.log('Quick selection of world', name); |
| 5472 | } else { | ||
| 5473 | console.warn('lets not reload an already loaded list yes?'); | ||
| 5543 | } | 5474 | } |
| 5544 | }, { buttonStyle: true, closeDrawer: true }); | 5475 | }, { buttonStyle: true, closeDrawer: true }); |
| 5545 | } | 5476 | } |
| @@ -14,6 +14,7 @@ | |||
| 14 | @import url(css/data-maid.css); | 14 | @import url(css/data-maid.css); |
| 15 | 15 | ||
| 16 | :root { | 16 | :root { |
| 17 | interpolate-size: allow-keywords; | ||
| 17 | --doc-height: 100%; | 18 | --doc-height: 100%; |
| 18 | --transparent: rgba(0, 0, 0, 0); | 19 | --transparent: rgba(0, 0, 0, 0); |
| 19 | 20 | ||
| @@ -122,7 +123,9 @@ | |||
| 122 | --inline-avatar-small-factor: 0.6; | 123 | --inline-avatar-small-factor: 0.6; |
| 123 | 124 | ||
| 124 | --animation-duration: 125ms; | 125 | --animation-duration: 125ms; |
| 125 | --animation-duration-slow: calc(var(--animation-duration) * 3); | 126 | --animation-duration-2x: calc(var(--animation-duration) * 2); |
| 127 | --animation-duration-3x: calc(var(--animation-duration) * 3); | ||
| 128 | --animation-duration-slow: var(--animation-duration-3x); | ||
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | * { | 131 | * { |
| @@ -719,7 +722,7 @@ hr { | |||
| 719 | position: absolute; | 722 | position: absolute; |
| 720 | width: 100%; | 723 | width: 100%; |
| 721 | height: 100%; | 724 | height: 100%; |
| 722 | transition: background-image 0.5s ease-in-out; | 725 | transition: background-image var(--animation-duration-3x) ease-in-out; |
| 723 | } | 726 | } |
| 724 | 727 | ||
| 725 | /* Background fitting options */ | 728 | /* Background fitting options */ |
| @@ -835,7 +838,7 @@ body.reduced-motion #bg_custom { | |||
| 835 | cursor: -webkit-grab; | 838 | cursor: -webkit-grab; |
| 836 | display: none; | 839 | display: none; |
| 837 | filter: drop-shadow(0px 0px 0px black); | 840 | filter: drop-shadow(0px 0px 0px black); |
| 838 | transition: all 250ms; | 841 | transition: all var(--animation-duration-2x); |
| 839 | font-size: calc(var(--mainFontSize)*1.3); | 842 | font-size: calc(var(--mainFontSize)*1.3); |
| 840 | } | 843 | } |
| 841 | 844 | ||
| @@ -851,7 +854,7 @@ body .panelControlBar { | |||
| 851 | min-width: 55px; | 854 | min-width: 55px; |
| 852 | justify-content: flex-end; | 855 | justify-content: flex-end; |
| 853 | gap: 0px; | 856 | gap: 0px; |
| 854 | transition: all 250ms; | 857 | transition: all var(--animation-duration-2x); |
| 855 | } | 858 | } |
| 856 | 859 | ||
| 857 | .zoomed_avatar .panelControlBar { | 860 | .zoomed_avatar .panelControlBar { |
| @@ -973,7 +976,7 @@ body .panelControlBar { | |||
| 973 | display: flex; | 976 | display: flex; |
| 974 | align-items: center; | 977 | align-items: center; |
| 975 | justify-content: center; | 978 | justify-content: center; |
| 976 | transition: opacity 300ms; | 979 | transition: opacity var(--animation-duration-2x); |
| 977 | } | 980 | } |
| 978 | 981 | ||
| 979 | #rightSendForm>div:hover, | 982 | #rightSendForm>div:hover, |
| @@ -1000,7 +1003,7 @@ body .panelControlBar { | |||
| 1000 | padding-right: 2px; | 1003 | padding-right: 2px; |
| 1001 | place-self: center; | 1004 | place-self: center; |
| 1002 | cursor: pointer; | 1005 | cursor: pointer; |
| 1003 | transition: 0.3s; | 1006 | transition: var(--animation-duration-2x); |
| 1004 | opacity: 0.7; | 1007 | opacity: 0.7; |
| 1005 | } | 1008 | } |
| 1006 | 1009 | ||
| @@ -1047,7 +1050,7 @@ body .panelControlBar { | |||
| 1047 | padding-right: 2px; | 1050 | padding-right: 2px; |
| 1048 | place-self: center; | 1051 | place-self: center; |
| 1049 | cursor: pointer; | 1052 | cursor: pointer; |
| 1050 | transition: 0.3s; | 1053 | transition: var(--animation-duration-2x); |
| 1051 | opacity: 1; | 1054 | opacity: 1; |
| 1052 | display: none; | 1055 | display: none; |
| 1053 | 1056 | ||
| @@ -1094,7 +1097,7 @@ body .panelControlBar { | |||
| 1094 | z-index: 2001; | 1097 | z-index: 2001; |
| 1095 | margin-left: 10px; | 1098 | margin-left: 10px; |
| 1096 | padding: 0; | 1099 | padding: 0; |
| 1097 | transition: 0.3s; | 1100 | transition: var(--animation-duration-2x); |
| 1098 | display: flex; | 1101 | display: flex; |
| 1099 | align-items: center; | 1102 | align-items: center; |
| 1100 | order: 2; | 1103 | order: 2; |
| @@ -1337,7 +1340,7 @@ body.swipeAllMessages .mes:not(.last_mes) .swipes-counter { | |||
| 1337 | border: var(--avatar-base-border-radius) solid var(--SmartThemeBodyColor); | 1340 | border: var(--avatar-base-border-radius) solid var(--SmartThemeBodyColor); |
| 1338 | margin: var(--avatar-base-border-radius); | 1341 | margin: var(--avatar-base-border-radius); |
| 1339 | cursor: pointer; | 1342 | cursor: pointer; |
| 1340 | transition: filter 0.2s ease-in-out; | 1343 | transition: filter var(--animation-duration) ease-in-out; |
| 1341 | } | 1344 | } |
| 1342 | 1345 | ||
| 1343 | .add_avatar:hover { | 1346 | .add_avatar:hover { |
| @@ -1350,7 +1353,7 @@ body.swipeAllMessages .mes:not(.last_mes) .swipes-counter { | |||
| 1350 | border-radius: var(--avatar-base-border-radius-round); | 1353 | border-radius: var(--avatar-base-border-radius-round); |
| 1351 | border-style: none; | 1354 | border-style: none; |
| 1352 | flex: 1; | 1355 | flex: 1; |
| 1353 | transition: 250ms; | 1356 | transition: var(--animation-duration-2x); |
| 1354 | } | 1357 | } |
| 1355 | 1358 | ||
| 1356 | .last_mes .mesAvatarWrapper { | 1359 | .last_mes .mesAvatarWrapper { |
| @@ -1542,7 +1545,7 @@ button { | |||
| 1542 | 100% var(--progWidthClip), | 1545 | 100% var(--progWidthClip), |
| 1543 | 100% 100%, | 1546 | 100% 100%, |
| 1544 | 0% 100%); | 1547 | 0% 100%); |
| 1545 | transition: clip-path 200ms; | 1548 | transition: clip-path var(--animation-duration-2x); |
| 1546 | } | 1549 | } |
| 1547 | 1550 | ||
| 1548 | #send_textarea:placeholder-shown { | 1551 | #send_textarea:placeholder-shown { |
| @@ -2493,8 +2496,8 @@ body[data-stscript-style] .hljs.language-stscript { | |||
| 2493 | margin: 3px; | 2496 | margin: 3px; |
| 2494 | opacity: 0.75; | 2497 | opacity: 0.75; |
| 2495 | filter: grayscale(1); | 2498 | filter: grayscale(1); |
| 2496 | -webkit-transition: all 250ms ease-in-out; | 2499 | -webkit-transition: all var(--animation-duration-2x) ease-in-out; |
| 2497 | transition: all 250ms ease-in-out; | 2500 | transition: all var(--animation-duration-2x) ease-in-out; |
| 2498 | } | 2501 | } |
| 2499 | 2502 | ||
| 2500 | #character_popup .editor_maximize:hover { | 2503 | #character_popup .editor_maximize:hover { |
| @@ -2648,8 +2651,8 @@ input[type="file"] { | |||
| 2648 | margin-top: 0; | 2651 | margin-top: 0; |
| 2649 | padding: 1px; | 2652 | padding: 1px; |
| 2650 | filter: grayscale(1) brightness(75%); | 2653 | filter: grayscale(1) brightness(75%); |
| 2651 | -webkit-transition: all 0.5s ease-in-out; | 2654 | -webkit-transition: all var(--animation-duration-3x) ease-in-out; |
| 2652 | transition: all 0.5s ease-in-out; | 2655 | transition: all var(--animation-duration-3x) ease-in-out; |
| 2653 | } | 2656 | } |
| 2654 | 2657 | ||
| 2655 | .right_menu_button:hover { | 2658 | .right_menu_button:hover { |
| @@ -2669,7 +2672,7 @@ input[type="file"] { | |||
| 2669 | #lm_button_panel_pin_div, | 2672 | #lm_button_panel_pin_div, |
| 2670 | #WI_button_panel_pin_div { | 2673 | #WI_button_panel_pin_div { |
| 2671 | opacity: 0.5; | 2674 | opacity: 0.5; |
| 2672 | transition: 0.3s; | 2675 | transition: var(--animation-duration-2x); |
| 2673 | } | 2676 | } |
| 2674 | 2677 | ||
| 2675 | #rm_button_panel_pin_div:hover, | 2678 | #rm_button_panel_pin_div:hover, |
| @@ -2805,7 +2808,6 @@ input[type="file"] { | |||
| 2805 | } | 2808 | } |
| 2806 | 2809 | ||
| 2807 | #rm_extensions_block { | 2810 | #rm_extensions_block { |
| 2808 | display: none; | ||
| 2809 | overflow-y: auto; | 2811 | overflow-y: auto; |
| 2810 | } | 2812 | } |
| 2811 | 2813 | ||
| @@ -2830,6 +2832,7 @@ input[type="file"] { | |||
| 2830 | margin: 0; | 2832 | margin: 0; |
| 2831 | right: unset; | 2833 | right: unset; |
| 2832 | width: calc(((100dvw - var(--sheldWidth)) / 2) - 1px); | 2834 | width: calc(((100dvw - var(--sheldWidth)) / 2) - 1px); |
| 2835 | height: unset; | ||
| 2833 | 2836 | ||
| 2834 | } | 2837 | } |
| 2835 | 2838 | ||
| @@ -2871,7 +2874,7 @@ input[type="file"] { | |||
| 2871 | aspect-ratio: 1 / 1; | 2874 | aspect-ratio: 1 / 1; |
| 2872 | font-size: 20px; | 2875 | font-size: 20px; |
| 2873 | opacity: 0.5; | 2876 | opacity: 0.5; |
| 2874 | transition: all 250ms; | 2877 | transition: all var(--animation-duration-2x); |
| 2875 | } | 2878 | } |
| 2876 | 2879 | ||
| 2877 | .floating_panel_maximize:hover, | 2880 | .floating_panel_maximize:hover, |
| @@ -2885,7 +2888,7 @@ input[type="file"] { | |||
| 2885 | aspect-ratio: 1 / 1; | 2888 | aspect-ratio: 1 / 1; |
| 2886 | font-size: calc(var(--mainFontSize)*1.3); | 2889 | font-size: calc(var(--mainFontSize)*1.3); |
| 2887 | opacity: 0.5; | 2890 | opacity: 0.5; |
| 2888 | transition: all 250ms; | 2891 | transition: all var(--animation-duration-2x); |
| 2889 | filter: drop-shadow(0px 0px 2px black); | 2892 | filter: drop-shadow(0px 0px 2px black); |
| 2890 | text-shadow: none; | 2893 | text-shadow: none; |
| 2891 | } | 2894 | } |
| @@ -2934,7 +2937,6 @@ select option:not(:checked) { | |||
| 2934 | /*#######################################################################*/ | 2937 | /*#######################################################################*/ |
| 2935 | 2938 | ||
| 2936 | #rm_api_block { | 2939 | #rm_api_block { |
| 2937 | display: none; | ||
| 2938 | overflow-y: auto; | 2940 | overflow-y: auto; |
| 2939 | } | 2941 | } |
| 2940 | 2942 | ||
| @@ -3021,7 +3023,7 @@ select option:not(:checked) { | |||
| 3021 | 3023 | ||
| 3022 | #rm_characters_block { | 3024 | #rm_characters_block { |
| 3023 | display: flex; | 3025 | display: flex; |
| 3024 | overflow-y: auto; | 3026 | overflow-y: hidden; |
| 3025 | flex-direction: column; | 3027 | flex-direction: column; |
| 3026 | height: 100%; | 3028 | height: 100%; |
| 3027 | } | 3029 | } |
| @@ -3321,7 +3323,7 @@ input[type=search]:focus::-webkit-search-cancel-button { | |||
| 3321 | text-shadow: none; | 3323 | text-shadow: none; |
| 3322 | margin: 0; | 3324 | margin: 0; |
| 3323 | filter: drop-shadow(0px 0px 3px white); | 3325 | filter: drop-shadow(0px 0px 3px white); |
| 3324 | transition: opacity 0.2s ease-in-out; | 3326 | transition: opacity var(--animation-duration-2x) ease-in-out; |
| 3325 | display: none; | 3327 | display: none; |
| 3326 | } | 3328 | } |
| 3327 | 3329 | ||
| @@ -3474,7 +3476,7 @@ input[type=search]:focus::-webkit-search-cancel-button { | |||
| 3474 | border: 1px solid var(--SmartThemeBorderColor); | 3476 | border: 1px solid var(--SmartThemeBorderColor); |
| 3475 | border-radius: 10px; | 3477 | border-radius: 10px; |
| 3476 | cursor: pointer; | 3478 | cursor: pointer; |
| 3477 | transition: 0.2s; | 3479 | transition: var(--animation-duration-2x); |
| 3478 | } | 3480 | } |
| 3479 | 3481 | ||
| 3480 | .avatar-container { | 3482 | .avatar-container { |
| @@ -3769,7 +3771,7 @@ grammarly-extension { | |||
| 3769 | width: min-content; | 3771 | width: min-content; |
| 3770 | cursor: pointer; | 3772 | cursor: pointer; |
| 3771 | margin: 5px 0; | 3773 | margin: 5px 0; |
| 3772 | transition: 0.3s; | 3774 | transition: var(--animation-duration-2x); |
| 3773 | display: flex; | 3775 | display: flex; |
| 3774 | align-items: center; | 3776 | align-items: center; |
| 3775 | justify-content: center; | 3777 | justify-content: center; |
| @@ -3835,7 +3837,7 @@ grammarly-extension { | |||
| 3835 | background-color: var(--black30a); | 3837 | background-color: var(--black30a); |
| 3836 | border: 1px solid var(--SmartThemeBorderColor); | 3838 | border: 1px solid var(--SmartThemeBorderColor); |
| 3837 | cursor: grab; | 3839 | cursor: grab; |
| 3838 | transition: background-color 200ms ease-in-out; | 3840 | transition: background-color var(--animation-duration-2x) ease-in-out; |
| 3839 | position: relative; | 3841 | position: relative; |
| 3840 | user-select: none; | 3842 | user-select: none; |
| 3841 | display: flex; | 3843 | display: flex; |
| @@ -4009,7 +4011,7 @@ input[type="checkbox"]::before { | |||
| 4009 | width: 0.65em; | 4011 | width: 0.65em; |
| 4010 | height: 0.65em; | 4012 | height: 0.65em; |
| 4011 | transform: scale(0); | 4013 | transform: scale(0); |
| 4012 | transition: 120ms transform ease-in-out; | 4014 | transition: var(--animation-duration) transform ease-in-out; |
| 4013 | box-shadow: inset 1em 1em var(--SmartThemeCheckboxTickColor); | 4015 | box-shadow: inset 1em 1em var(--SmartThemeCheckboxTickColor); |
| 4014 | transform-origin: bottom left; | 4016 | transform-origin: bottom left; |
| 4015 | clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); | 4017 | clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); |
| @@ -4181,6 +4183,13 @@ input[type='checkbox'].del_checkbox { | |||
| 4181 | background-repeat: no-repeat !important; | 4183 | background-repeat: no-repeat !important; |
| 4182 | box-shadow: inset 0 0 2px var(--black50a) !important; | 4184 | box-shadow: inset 0 0 2px var(--black50a) !important; |
| 4183 | cursor: ew-resize !important; | 4185 | cursor: ew-resize !important; |
| 4186 | } | ||
| 4187 | |||
| 4188 | /* | ||
| 4189 | * Setting a z-index will allow scrollbar to display properly in Firefox, | ||
| 4190 | * while constraining to open drawers fixes a single frame linger in Chrome. | ||
| 4191 | */ | ||
| 4192 | .drawer-content.openDrawer .neo-range-slider { | ||
| 4184 | z-index: 1; | 4193 | z-index: 1; |
| 4185 | } | 4194 | } |
| 4186 | 4195 | ||
| @@ -4345,7 +4354,7 @@ input[type="range"]::-webkit-slider-thumb { | |||
| 4345 | border-radius: 100%; | 4354 | border-radius: 100%; |
| 4346 | box-shadow: 0 0 3px black; | 4355 | box-shadow: 0 0 3px black; |
| 4347 | */ | 4356 | */ |
| 4348 | transition: all 250ms; | 4357 | transition: all var(--animation-duration-2x); |
| 4349 | } | 4358 | } |
| 4350 | 4359 | ||
| 4351 | .topRightInset { | 4360 | .topRightInset { |
| @@ -4365,7 +4374,7 @@ input[type="range"]::-webkit-slider-thumb { | |||
| 4365 | font-weight: 400; | 4374 | font-weight: 400; |
| 4366 | text-decoration: none; | 4375 | text-decoration: none; |
| 4367 | border-bottom: 2px dashed red; | 4376 | border-bottom: 2px dashed red; |
| 4368 | transition: 0.3s; | 4377 | transition: var(--animation-duration-2x); |
| 4369 | } | 4378 | } |
| 4370 | 4379 | ||
| 4371 | .whitespacenowrap { | 4380 | .whitespacenowrap { |
| @@ -4398,7 +4407,7 @@ input[type="range"]::-webkit-slider-thumb { | |||
| 4398 | gap: 4px; | 4407 | gap: 4px; |
| 4399 | flex-wrap: nowrap; | 4408 | flex-wrap: nowrap; |
| 4400 | justify-content: flex-end; | 4409 | justify-content: flex-end; |
| 4401 | transition: all 200ms; | 4410 | transition: all var(--animation-duration-2x); |
| 4402 | overflow-x: hidden; | 4411 | overflow-x: hidden; |
| 4403 | padding: 1px; | 4412 | padding: 1px; |
| 4404 | } | 4413 | } |
| @@ -4410,7 +4419,7 @@ input[type="range"]::-webkit-slider-thumb { | |||
| 4410 | .mes_button, | 4419 | .mes_button, |
| 4411 | .extraMesButtons>div { | 4420 | .extraMesButtons>div { |
| 4412 | cursor: pointer; | 4421 | cursor: pointer; |
| 4413 | transition: opacity 0.2s ease-in-out; | 4422 | transition: opacity var(--animation-duration-2x) ease-in-out; |
| 4414 | filter: drop-shadow(0px 0px 2px black); | 4423 | filter: drop-shadow(0px 0px 2px black); |
| 4415 | opacity: 0.3; | 4424 | opacity: 0.3; |
| 4416 | padding: 1px 3px; | 4425 | padding: 1px 3px; |
| @@ -4441,7 +4450,7 @@ input[type="range"]::-webkit-slider-thumb { | |||
| 4441 | cursor: pointer; | 4450 | cursor: pointer; |
| 4442 | padding-bottom: 5px; | 4451 | padding-bottom: 5px; |
| 4443 | filter: drop-shadow(0px 0px 2px black); | 4452 | filter: drop-shadow(0px 0px 2px black); |
| 4444 | transition: 0.3s ease-in-out; | 4453 | transition: var(--animation-duration-2x) ease-in-out; |
| 4445 | } | 4454 | } |
| 4446 | 4455 | ||
| 4447 | .mes_reasoning_actions { | 4456 | .mes_reasoning_actions { |
| @@ -4776,7 +4785,7 @@ body .ui-slider-handle { | |||
| 4776 | text-align: center; | 4785 | text-align: center; |
| 4777 | margin-left: 0; | 4786 | margin-left: 0; |
| 4778 | opacity: 1 !important; | 4787 | opacity: 1 !important; |
| 4779 | transition: filter 200ms; | 4788 | transition: filter var(--animation-duration-2x); |
| 4780 | filter: brightness(1.2); | 4789 | filter: brightness(1.2); |
| 4781 | } | 4790 | } |
| 4782 | 4791 | ||
| @@ -4834,7 +4843,7 @@ body .ui-widget-content li { | |||
| 4834 | align-items: center; | 4843 | align-items: center; |
| 4835 | cursor: pointer; | 4844 | cursor: pointer; |
| 4836 | opacity: 0.5; | 4845 | opacity: 0.5; |
| 4837 | transition: opacity 200ms; | 4846 | transition: opacity var(--animation-duration-2x); |
| 4838 | } | 4847 | } |
| 4839 | 4848 | ||
| 4840 | body .ui-widget-content li:hover { | 4849 | body .ui-widget-content li:hover { |
| @@ -4996,34 +5005,6 @@ a:hover { | |||
| 4996 | /* Right nav panel and nav-toggle */ | 5005 | /* Right nav panel and nav-toggle */ |
| 4997 | /* ############################################################# */ | 5006 | /* ############################################################# */ |
| 4998 | 5007 | ||
| 4999 | #right-nav-panel { | ||
| 5000 | width: calc((100vw - var(--sheldWidth) - 2px) /2); | ||
| 5001 | width: calc((100dvw - var(--sheldWidth) - 2px) /2); | ||
| 5002 | max-height: calc(100vh - var(--topBarBlockSize)); | ||
| 5003 | max-height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5004 | height: calc(100vh - var(--topBarBlockSize)); | ||
| 5005 | height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5006 | position: fixed; | ||
| 5007 | top: 0; | ||
| 5008 | margin: 0; | ||
| 5009 | right: 0; | ||
| 5010 | left: calc(100% - var(--sheldWidth) /2 + var(--sheldWidth) +1px); | ||
| 5011 | padding: 5px; | ||
| 5012 | margin-bottom: 5px; | ||
| 5013 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | ||
| 5014 | background-color: var(--SmartThemeBlurTintColor); | ||
| 5015 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | ||
| 5016 | z-index: 3000; | ||
| 5017 | |||
| 5018 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 5019 | |||
| 5020 | box-shadow: none; | ||
| 5021 | border-radius: 10px; | ||
| 5022 | overflow: hidden; | ||
| 5023 | flex-flow: column; | ||
| 5024 | min-width: 100px; | ||
| 5025 | } | ||
| 5026 | |||
| 5027 | #nav-toggle { | 5008 | #nav-toggle { |
| 5028 | position: fixed; | 5009 | position: fixed; |
| 5029 | right: 13px; | 5010 | right: 13px; |
| @@ -5047,7 +5028,7 @@ a:hover { | |||
| 5047 | display: none; | 5028 | display: none; |
| 5048 | position: relative; | 5029 | position: relative; |
| 5049 | width: fit-content; | 5030 | width: fit-content; |
| 5050 | transition: all 0.1s; | 5031 | transition: all var(--animation-duration); |
| 5051 | padding: 0.5rem; | 5032 | padding: 0.5rem; |
| 5052 | } | 5033 | } |
| 5053 | 5034 | ||
| @@ -5239,7 +5220,7 @@ body:not(.sd) .mes_img_swipes { | |||
| 5239 | border-radius: 10px; | 5220 | border-radius: 10px; |
| 5240 | padding: 2px 5px; | 5221 | padding: 2px 5px; |
| 5241 | border: 1px solid var(--SmartThemeBorderColor); | 5222 | border: 1px solid var(--SmartThemeBorderColor); |
| 5242 | transition: all 250ms; | 5223 | transition: all var(--animation-duration-2x); |
| 5243 | } | 5224 | } |
| 5244 | 5225 | ||
| 5245 | .standoutHeader.inline-drawer-header { | 5226 | .standoutHeader.inline-drawer-header { |
| @@ -5322,12 +5303,12 @@ body:has(#character_popup.open) #top-settings-holder:has(.drawer-content.openDra | |||
| 5322 | } | 5303 | } |
| 5323 | 5304 | ||
| 5324 | .drawer-icon.openIcon { | 5305 | .drawer-icon.openIcon { |
| 5325 | transition: all 0.275s; | 5306 | transition: all var(--animation-duration-2x); |
| 5326 | } | 5307 | } |
| 5327 | 5308 | ||
| 5328 | .drawer-icon.closedIcon { | 5309 | .drawer-icon.closedIcon { |
| 5329 | opacity: 0.3; | 5310 | opacity: 0.3; |
| 5330 | transition: all 0.275s; | 5311 | transition: all var(--animation-duration-2x); |
| 5331 | } | 5312 | } |
| 5332 | 5313 | ||
| 5333 | .drawer-icon.closedIcon:hover { | 5314 | .drawer-icon.closedIcon:hover { |
| @@ -5390,7 +5371,7 @@ body:has(#character_popup.open) #top-settings-holder:has(.drawer-content.openDra | |||
| 5390 | border: 1px solid var(--SmartThemeBorderColor); | 5371 | border: 1px solid var(--SmartThemeBorderColor); |
| 5391 | min-width: 450px; | 5372 | min-width: 450px; |
| 5392 | width: var(--sheldWidth); | 5373 | width: var(--sheldWidth); |
| 5393 | overflow-y: auto; | 5374 | overflow-y: hidden; |
| 5394 | max-height: calc(100vh - calc(var(--topBarBlockSize) + var(--bottomFormBlockSize))); | 5375 | max-height: calc(100vh - calc(var(--topBarBlockSize) + var(--bottomFormBlockSize))); |
| 5395 | max-height: calc(100dvh - calc(var(--topBarBlockSize) + var(--bottomFormBlockSize))); | 5376 | max-height: calc(100dvh - calc(var(--topBarBlockSize) + var(--bottomFormBlockSize))); |
| 5396 | display: none; | 5377 | display: none; |
| @@ -5399,9 +5380,30 @@ body:has(#character_popup.open) #top-settings-holder:has(.drawer-content.openDra | |||
| 5399 | left: 0; | 5380 | left: 0; |
| 5400 | right: 0; | 5381 | right: 0; |
| 5401 | margin: 0 auto; | 5382 | margin: 0 auto; |
| 5383 | height: 0; | ||
| 5402 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | 5384 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); |
| 5403 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | 5385 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); |
| 5404 | /* z-index: 1000 !important; */ | 5386 | /* z-index: 1000 !important; */ |
| 5387 | transition-property: height, display; | ||
| 5388 | transition-duration: var(--animation-duration-2x); | ||
| 5389 | transition-timing-function: ease-in-out; | ||
| 5390 | transition-behavior: allow-discrete; | ||
| 5391 | } | ||
| 5392 | |||
| 5393 | #movingDivs>.drawer-content { | ||
| 5394 | height: unset; | ||
| 5395 | } | ||
| 5396 | |||
| 5397 | .drawer-content.openDrawer { | ||
| 5398 | display: block; | ||
| 5399 | height: auto; | ||
| 5400 | height: calc-size(auto, size); | ||
| 5401 | overflow-y: auto; | ||
| 5402 | animation: hide-scroll var(--animation-duration-2x) backwards; | ||
| 5403 | |||
| 5404 | @starting-style { | ||
| 5405 | height: 0; | ||
| 5406 | } | ||
| 5405 | } | 5407 | } |
| 5406 | 5408 | ||
| 5407 | body.movingUI .inline-drawer-maximize { | 5409 | body.movingUI .inline-drawer-maximize { |
| @@ -5428,8 +5430,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5428 | .fillLeft { | 5430 | .fillLeft { |
| 5429 | width: calc((100vw - var(--sheldWidth) - 2px) /2); | 5431 | width: calc((100vw - var(--sheldWidth) - 2px) /2); |
| 5430 | width: calc((100dvw - var(--sheldWidth) - 2px) /2); | 5432 | width: calc((100dvw - var(--sheldWidth) - 2px) /2); |
| 5431 | height: calc(100vh - var(--topBarBlockSize)); | 5433 | height: 0; |
| 5432 | height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5433 | max-height: calc(100vh - var(--topBarBlockSize)); | 5434 | max-height: calc(100vh - var(--topBarBlockSize)); |
| 5434 | max-height: calc(100dvh - var(--topBarBlockSize)); | 5435 | max-height: calc(100dvh - var(--topBarBlockSize)); |
| 5435 | position: fixed; | 5436 | position: fixed; |
| @@ -5443,6 +5444,66 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5443 | border: 1px solid var(--SmartThemeBorderColor); | 5444 | border: 1px solid var(--SmartThemeBorderColor); |
| 5444 | } | 5445 | } |
| 5445 | 5446 | ||
| 5447 | .fillLeft.openDrawer { | ||
| 5448 | overflow-y: hidden; | ||
| 5449 | height: calc(100vh - var(--topBarBlockSize)); | ||
| 5450 | height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5451 | height: calc-size((100dvh - var(--topBarBlockSize)), size); | ||
| 5452 | |||
| 5453 | @starting-style { | ||
| 5454 | height: 0; | ||
| 5455 | } | ||
| 5456 | } | ||
| 5457 | |||
| 5458 | .fillRight { | ||
| 5459 | width: calc((100vw - var(--sheldWidth) - 2px) /2); | ||
| 5460 | width: calc((100dvw - var(--sheldWidth) - 2px) /2); | ||
| 5461 | max-height: calc(100vh - var(--topBarBlockSize)); | ||
| 5462 | max-height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5463 | height: 0; | ||
| 5464 | position: fixed; | ||
| 5465 | top: 0; | ||
| 5466 | margin: 0; | ||
| 5467 | right: 0; | ||
| 5468 | left: calc(100% - var(--sheldWidth) /2 + var(--sheldWidth) +1px); | ||
| 5469 | padding: 5px; | ||
| 5470 | margin-bottom: 5px; | ||
| 5471 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | ||
| 5472 | background-color: var(--SmartThemeBlurTintColor); | ||
| 5473 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | ||
| 5474 | z-index: 3000; | ||
| 5475 | |||
| 5476 | border: 1px solid var(--SmartThemeBorderColor); | ||
| 5477 | |||
| 5478 | box-shadow: none; | ||
| 5479 | border-radius: 10px; | ||
| 5480 | overflow: hidden; | ||
| 5481 | flex-flow: column; | ||
| 5482 | min-width: 100px; | ||
| 5483 | } | ||
| 5484 | |||
| 5485 | .fillRight.openDrawer { | ||
| 5486 | display: flex; | ||
| 5487 | height: calc(100vh - var(--topBarBlockSize)); | ||
| 5488 | height: calc(100dvh - var(--topBarBlockSize)); | ||
| 5489 | height: calc-size((100dvh - var(--topBarBlockSize)), size); | ||
| 5490 | |||
| 5491 | @starting-style { | ||
| 5492 | height: 0; | ||
| 5493 | } | ||
| 5494 | } | ||
| 5495 | |||
| 5496 | /* | ||
| 5497 | .fillRight #rm_print_characters_block { | ||
| 5498 | overflow-y: hidden; | ||
| 5499 | } | ||
| 5500 | |||
| 5501 | .fillRight.openDrawer #rm_print_characters_block { | ||
| 5502 | overflow-y: auto; | ||
| 5503 | animation: hide-scroll var(--animation-duration-2x) backwards; | ||
| 5504 | } | ||
| 5505 | */ | ||
| 5506 | |||
| 5446 | .scrollableInner { | 5507 | .scrollableInner { |
| 5447 | overflow-x: hidden; | 5508 | overflow-x: hidden; |
| 5448 | height: calc(100% - 30px); | 5509 | height: calc(100% - 30px); |
| @@ -5709,7 +5770,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5709 | aspect-ratio: 1 / 1; | 5770 | aspect-ratio: 1 / 1; |
| 5710 | font-size: 20px; | 5771 | font-size: 20px; |
| 5711 | opacity: 0.5; | 5772 | opacity: 0.5; |
| 5712 | transition: all 250ms; | 5773 | transition: all var(--animation-duration-2x); |
| 5713 | } | 5774 | } |
| 5714 | 5775 | ||
| 5715 | /* #groupMemberListPopout, | 5776 | /* #groupMemberListPopout, |
| @@ -5796,7 +5857,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5796 | color: var(--SmartThemeBodyColor); | 5857 | color: var(--SmartThemeBodyColor); |
| 5797 | border: 1px solid var(--SmartThemeBorderColor); | 5858 | border: 1px solid var(--SmartThemeBorderColor); |
| 5798 | border-radius: 5px; | 5859 | border-radius: 5px; |
| 5799 | transition: opacity 0.2s; | 5860 | transition: opacity var(--animation-duration-2x); |
| 5800 | opacity: 0.8; | 5861 | opacity: 0.8; |
| 5801 | cursor: pointer; | 5862 | cursor: pointer; |
| 5802 | } | 5863 | } |
| @@ -5988,7 +6049,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 5988 | margin: 7px; | 6049 | margin: 7px; |
| 5989 | width: calc(100% - 7px); | 6050 | width: calc(100% - 7px); |
| 5990 | box-sizing: border-box; | 6051 | box-sizing: border-box; |
| 5991 | transition: transform 0.2s ease-in-out, background-color 0.2s ease-in-out, border 0.2s ease-in-out; | 6052 | transition: transform var(--animation-duration-2x) ease-in-out, background-color var(--animation-duration-2x) ease-in-out, border var(--animation-duration-2x) ease-in-out; |
| 5992 | } | 6053 | } |
| 5993 | 6054 | ||
| 5994 | .model-card .details-container { | 6055 | .model-card .details-container { |
| @@ -6000,7 +6061,7 @@ body:not(.movingUI) .drawer-content.maximized { | |||
| 6000 | transform: scale(1.01); | 6061 | transform: scale(1.01); |
| 6001 | background-color: #444; | 6062 | background-color: #444; |
| 6002 | /* Smooth transition */ | 6063 | /* Smooth transition */ |
| 6003 | transition: transform 0.2s ease-in-out, background-color 0.2s ease-in-out; | 6064 | transition: transform var(--animation-duration-2x) ease-in-out, background-color var(--animation-duration-2x) ease-in-out; |
| 6004 | } | 6065 | } |
| 6005 | 6066 | ||
| 6006 | .model-card.selected { | 6067 | .model-card.selected { |