Merge pull request #2521 from SillyTavern/char-action-popups Update most char submenu popups to new popup
Signed| @@ -5123,23 +5123,6 @@ | |||
| 5123 | </div> | 5123 | </div> |
| 5124 | </div> | 5124 | </div> |
| 5125 | <!-- templates for JS to reuse when needed --> | 5125 | <!-- templates for JS to reuse when needed --> |
| 5126 | <div id="scenario_override_template" class="template_element"> | ||
| 5127 | <div class="scenario_override range-block flexFlowColumn flex-container"> | ||
| 5128 | <div class="range-block-title title_restorable"> | ||
| 5129 | <h3><span data-i18n="Chat Scenario Override" class="margin0">Chat Scenario Override</span></h3> | ||
| 5130 | <div title="Remove" data-i18n="[title]Remove" class="menu_button fa-solid fa-trash-can remove_scenario_override"></div> | ||
| 5131 | </div> | ||
| 5132 | <div class="range-block-counter justifyLeft flex-container flexFlowColumn"> | ||
| 5133 | <strong>Unique to this chat.</strong> | ||
| 5134 | <span data-group="true">All group members will use the following scenario text instead of what is specified in their character cards.</span> | ||
| 5135 | <span data-character="true">The following scenario text will be used instead of the value set in the character card.</span> | ||
| 5136 | Checkpoints inherit the scenario override from their parent, and can be changed individually after that. | ||
| 5137 | </div> | ||
| 5138 | <div class="range-block-range wide100p"> | ||
| 5139 | <textarea class="wide100p chat_scenario" class="text_pole" rows="15" data-i18n="[placeholder]Type here..." placeholder="Type here..."></textarea> | ||
| 5140 | </div> | ||
| 5141 | </div> | ||
| 5142 | </div> | ||
| 5143 | <div id="chat_world_template" class="template_element"> | 5126 | <div id="chat_world_template" class="template_element"> |
| 5144 | <div class="chat_world range-block flexFlowColumn flex-container"> | 5127 | <div class="chat_world range-block flexFlowColumn flex-container"> |
| 5145 | <div class="range-block-title"> | 5128 | <div class="range-block-title"> |
| @@ -7184,20 +7184,23 @@ function updateFavButtonState(state) { | |||
| 7184 | $('#favorite_button').toggleClass('fav_off', !fav_ch_checked); | 7184 | $('#favorite_button').toggleClass('fav_off', !fav_ch_checked); |
| 7185 | } | 7185 | } |
| 7186 | 7186 | ||
| 7187 | export function setScenarioOverride() { | 7187 | export async function setScenarioOverride() { |
| 7188 | if (!selected_group && !this_chid) { | 7188 | if (!selected_group && !this_chid) { |
| 7189 | console.warn('setScenarioOverride() -- no selected group or character'); | 7189 | console.warn('setScenarioOverride() -- no selected group or character'); |
| 7190 | return; | 7190 | return; |
| 7191 | } | 7191 | } |
| 7192 | 7192 | ||
| 7193 | const template = $('#scenario_override_template .scenario_override').clone(); | ||
| 7194 | const metadataValue = chat_metadata['scenario'] || ''; | 7193 | const metadataValue = chat_metadata['scenario'] || ''; |
| 7195 | const isGroup = !!selected_group; | 7194 | const isGroup = !!selected_group; |
| 7196 | template.find('[data-group="true"]').toggle(isGroup); | 7195 | |
| 7197 | template.find('[data-character="true"]').toggle(!isGroup); | 7196 | const $template = $(await renderTemplateAsync('scenarioOverride')); |
| 7198 | template.find('.chat_scenario').val(metadataValue).on('input', onScenarioOverrideInput); | 7197 | $template.find('[data-group="true"]').toggle(isGroup); |
| 7199 | template.find('.remove_scenario_override').on('click', onScenarioOverrideRemoveClick); | 7198 | $template.find('[data-character="true"]').toggle(!isGroup); |
| 7200 | callPopup(template, 'text'); | 7199 | // TODO: Why does this save on every character input? Save on popup close |
| 7200 | $template.find('.chat_scenario').val(metadataValue).on('input', onScenarioOverrideInput); | ||
| 7201 | $template.find('.remove_scenario_override').on('click', onScenarioOverrideRemoveClick); | ||
| 7202 | |||
| 7203 | await callGenericPopup($template, POPUP_TYPE.TEXT, ''); | ||
| 7201 | } | 7204 | } |
| 7202 | 7205 | ||
| 7203 | function onScenarioOverrideInput() { | 7206 | function onScenarioOverrideInput() { |
| @@ -10653,7 +10656,7 @@ jQuery(async function () { | |||
| 10653 | openCharacterWorldPopup(); | 10656 | openCharacterWorldPopup(); |
| 10654 | break; | 10657 | break; |
| 10655 | case 'set_chat_scenario': | 10658 | case 'set_chat_scenario': |
| 10656 | setScenarioOverride(); | 10659 | await setScenarioOverride(); |
| 10657 | break; | 10660 | break; |
| 10658 | case 'renameCharButton': | 10661 | case 'renameCharButton': |
| 10659 | renameCharacter(); | 10662 | renameCharacter(); |
| @@ -10674,7 +10677,7 @@ jQuery(async function () { | |||
| 10674 | const source = getCharacterSource(this_chid); | 10677 | const source = getCharacterSource(this_chid); |
| 10675 | if (source && isValidUrl(source)) { | 10678 | if (source && isValidUrl(source)) { |
| 10676 | const url = new URL(source); | 10679 | const url = new URL(source); |
| 10677 | const confirm = await callPopup(`Open ${url.hostname} in a new tab?`, 'confirm'); | 10680 | const confirm = await Popup.show.confirm('Open Source', `<span>Do you want to open the link to ${url.hostname} in a new tab?</span><var>${url}</var>`); |
| 10678 | if (confirm) { | 10681 | if (confirm) { |
| 10679 | window.open(source, '_blank'); | 10682 | window.open(source, '_blank'); |
| 10680 | } | 10683 | } |
| @@ -10683,7 +10686,7 @@ jQuery(async function () { | |||
| 10683 | } | 10686 | } |
| 10684 | } break; | 10687 | } break; |
| 10685 | case 'replace_update': { | 10688 | case 'replace_update': { |
| 10686 | const confirm = await callPopup('<p><b>Choose a new character card to replace this character with.</b></p><p>All chats, assets and group memberships will be preserved, but local changes to the character data will be lost.</p><p>Proceed?</p>', 'confirm', ''); | 10689 | const confirm = await Popup.show.confirm('Replace Character', '<p>Choose a new character card to replace this character with.</p>All chats, assets and group memberships will be preserved, but local changes to the character data will be lost.<br />Proceed?'); |
| 10687 | if (confirm) { | 10690 | if (confirm) { |
| 10688 | async function uploadReplacementCard(e) { | 10691 | async function uploadReplacementCard(e) { |
| 10689 | const file = e.target.files[0]; | 10692 | const file = e.target.files[0]; |
| @@ -395,19 +395,16 @@ export async function convertCharacterToPersona(characterId = null) { | |||
| 395 | const overwriteName = `${name} (Persona).png`; | 395 | const overwriteName = `${name} (Persona).png`; |
| 396 | 396 | ||
| 397 | if (overwriteName in power_user.personas) { | 397 | if (overwriteName in power_user.personas) { |
| 398 | const confirmation = await callPopup('This character exists as a persona already. Are you sure want to overwrite it?', 'confirm', '', { okButton: 'Yes' }); | 398 | const confirm = await Popup.show.confirm('Overwrite Existing Persona', 'This character exists as a persona already. Do you want to overwrite it?'); |
| 399 | 399 | if (!confirm) { | |
| 400 | if (confirmation === false) { | ||
| 401 | console.log('User cancelled the overwrite of the persona'); | 400 | console.log('User cancelled the overwrite of the persona'); |
| 402 | return; | 401 | return; |
| 403 | } | 402 | } |
| 404 | } | 403 | } |
| 405 | 404 | ||
| 406 | if (description.includes('{{char}}') || description.includes('{{user}}')) { | 405 | if (description.includes('{{char}}') || description.includes('{{user}}')) { |
| 407 | await delay(500); | 406 | const confirm = await Popup.show.confirm('Persona Description Macros', 'This character has a description that uses <code>{{char}}</code> or <code>{{user}}</code> macros. Do you want to swap them in the persona description?'); |
| 408 | const confirmation = await callPopup('This character has a description that uses {{char}} or {{user}} macros. Do you want to swap them in the persona description?', 'confirm', '', { okButton: 'Yes' }); | 407 | if (confirm) { |
| 409 | |||
| 410 | if (confirmation) { | ||
| 411 | description = description.replace(/{{char}}/gi, '{{personaChar}}').replace(/{{user}}/gi, '{{personaUser}}'); | 408 | description = description.replace(/{{char}}/gi, '{{personaChar}}').replace(/{{user}}/gi, '{{personaUser}}'); |
| 412 | description = description.replace(/{{personaUser}}/gi, '{{char}}').replace(/{{personaChar}}/gi, '{{user}}'); | 409 | description = description.replace(/{{personaUser}}/gi, '{{char}}').replace(/{{personaChar}}/gi, '{{user}}'); |
| 413 | } | 410 | } |
| @@ -0,0 +1,17 @@ | |||
| 1 | <div class="scenario_override range-block flexFlowColumn flex-container"> | ||
| 2 | <div class="range-block-title title_restorable"> | ||
| 3 | <h3><span data-i18n="Chat Scenario Override" class="margin0">Chat Scenario Override</span></h3> | ||
| 4 | <div title="Remove" data-i18n="[title]Remove" | ||
| 5 | class="menu_button fa-solid fa-trash-can remove_scenario_override"></div> | ||
| 6 | </div> | ||
| 7 | <div class="range-block-counter justifyLeft flex-container flexFlowColumn"> | ||
| 8 | <strong>Unique to this chat.</strong> | ||
| 9 | <span data-group="true">All group members will use the following scenario text instead of what is specified in their character cards.</span> | ||
| 10 | <span data-character="true">The following scenario text will be used instead of the value set in the character card.</span> | ||
| 11 | Checkpoints inherit the scenario override from their parent, and can be changed individually after that. | ||
| 12 | </div> | ||
| 13 | <div class="range-block-range wide100p"> | ||
| 14 | <textarea class="wide100p chat_scenario" class="text_pole" rows="15" data-i18n="[placeholder]Type here..." | ||
| 15 | placeholder="Type here..."></textarea> | ||
| 16 | </div> | ||
| 17 | </div> | ||