Merge branch 'staging' into fix/raw-quotes

c673ebcc229f8dc9e8a741778d1f0d5554c8bbdd

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

6 files changed, +15 -64Showing whitespace changes
.github/workflows/issues-updates-on-merge.yml+3 -3
@@ -36,10 +36,10 @@ jobs:
36 for ISSUE in $(echo $issues | jq -r '.[]'); do36 for ISSUE in $(echo $issues | jq -r '.[]'); do
37 if [ "${{ github.ref }}" == "refs/heads/staging" ]; then37 if [ "${{ github.ref }}" == "refs/heads/staging" ]; then
38 LABEL="✅ Done (staging)"38 LABEL="✅ Done (staging)"
39 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL"39 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL" --remove-label "🧑‍💻 In Progress"
40 elif [ "${{ github.ref }}" == "refs/heads/release" ]; then40 elif [ "${{ github.ref }}" == "refs/heads/release" ]; then
41 LABEL="✅ Done"41 LABEL="✅ Done"
42 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL"42 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "$LABEL" --remove-label "🧑‍💻 In Progress"
43 fi43 fi
44 echo "Added label '$LABEL' to issue #$ISSUE"44 echo "Added label '$LABEL' (and removed '🧑‍💻 In Progress' if present) in issue #$ISSUE"
45 done45 done
.github/workflows/pr-auto-manager.yml+2 -2
@@ -262,6 +262,6 @@ jobs:
262 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}262 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
263 run: |263 run: |
264 for ISSUE in $(echo $final_issues | jq -r '.[]'); do264 for ISSUE in $(echo $final_issues | jq -r '.[]'); do
265 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "✅ Done (staging)"265 gh issue edit $ISSUE -R ${{ github.repository }} --add-label "✅ Done (staging)" --remove-label "🧑‍💻 In Progress"
266 echo "Added label '✅ Done (staging)' to issue #$ISSUE"266 echo "Added label '✅ Done (staging)' (and removed '🧑‍💻 In Progress' if present) in issue #$ISSUE"
267 done267 done
public/scripts/PromptManager.js+2 -30
@@ -1,6 +1,6 @@
1'use strict';1'use strict';
22
3import { DOMPurify, Popper } from '../lib.js';3import { DOMPurify } from '../lib.js';
44
5import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js';5import { event_types, eventSource, is_send_press, main_api, substituteParams } from '../script.js';
6import { is_group_generating } from './group-chats.js';6import { is_group_generating } from './group-chats.js';
@@ -1440,36 +1440,8 @@ class PromptManager {
1440 footerDiv.querySelector('select').selectedIndex = selectedPromptIndex;1440 footerDiv.querySelector('select').selectedIndex = selectedPromptIndex;
14411441
1442 // Add prompt export dialogue and options1442 // Add prompt export dialogue and options
1443
1444 const exportForCharacter = await renderTemplateAsync('promptManagerExportForCharacter');
1445 const exportPopup = await renderTemplateAsync('promptManagerExportPopup', { isGlobalStrategy: 'global' === this.configuration.promptOrder.strategy, exportForCharacter });
1446 rangeBlockDiv.insertAdjacentHTML('beforeend', exportPopup);
1447
1448 // Destroy previous popper instance if it exists
1449 if (this.exportPopper) {
1450 this.exportPopper.destroy();
1451 }
1452
1453 this.exportPopper = Popper.createPopper(
1454 document.getElementById('prompt-manager-export'),
1455 document.getElementById('prompt-manager-export-format-popup'),
1456 { placement: 'bottom' },
1457 );
1458
1459 const showExportSelection = () => {
1460 const popup = document.getElementById('prompt-manager-export-format-popup');
1461 const show = popup.hasAttribute('data-show');
1462
1463 if (show) popup.removeAttribute('data-show');
1464 else popup.setAttribute('data-show', '');
1465
1466 this.exportPopper.update();
1467 };
1468
1469 footerDiv.querySelector('#prompt-manager-import').addEventListener('click', this.handleImport);1443 footerDiv.querySelector('#prompt-manager-import').addEventListener('click', this.handleImport);
1470 footerDiv.querySelector('#prompt-manager-export').addEventListener('click', showExportSelection);1444 footerDiv.querySelector('#prompt-manager-export').addEventListener('click', this.handleFullExport);
1471 rangeBlockDiv.querySelector('.export-promptmanager-prompts-full').addEventListener('click', this.handleFullExport);
1472 rangeBlockDiv.querySelector('.export-promptmanager-prompts-character')?.addEventListener('click', this.handleCharacterExport);
1473 }1445 }
1474 }1446 }
14751447
public/scripts/personas.js+8 -13
@@ -111,6 +111,7 @@ export function setUserAvatar(imgfile, { toastPersonaNameChange = true, navigate
111 reloadUserAvatar();111 reloadUserAvatar();
112 updatePersonaUIStates({ navigateToCurrent: navigateToCurrent });112 updatePersonaUIStates({ navigateToCurrent: navigateToCurrent });
113 selectCurrentPersona({ toastPersonaNameChange: toastPersonaNameChange });113 selectCurrentPersona({ toastPersonaNameChange: toastPersonaNameChange });
114 retriggerFirstMessageOnEmptyChat();
114 saveSettingsDebounced();115 saveSettingsDebounced();
115 $('.zoomed_avatar[forchar]').remove();116 $('.zoomed_avatar[forchar]').remove();
116}117}
@@ -465,7 +466,7 @@ export function initPersona(avatarId, personaName, personaDescription) {
465 * @returns {Promise<boolean>} A promise that resolves to true if the character was converted, false otherwise.466 * @returns {Promise<boolean>} A promise that resolves to true if the character was converted, false otherwise.
466 */467 */
467export async function convertCharacterToPersona(characterId = null) {468export async function convertCharacterToPersona(characterId = null) {
468 if (null === characterId) characterId = this_chid;469 if (null === characterId) characterId = Number(this_chid);
469470
470 const avatarUrl = characters[characterId]?.avatar;471 const avatarUrl = characters[characterId]?.avatar;
471 if (!avatarUrl) {472 if (!avatarUrl) {
@@ -1243,7 +1244,7 @@ function getPersonaStates(avatarId) {
1243 /** @type {PersonaConnection[]} */1244 /** @type {PersonaConnection[]} */
1244 const connections = power_user.persona_descriptions[avatarId]?.connections;1245 const connections = power_user.persona_descriptions[avatarId]?.connections;
1245 const hasCharLock = !!connections?.some(c =>1246 const hasCharLock = !!connections?.some(c =>
1246 (!selected_group && c.type === 'character' && c.id === characters[this_chid]?.avatar)1247 (!selected_group && c.type === 'character' && c.id === characters[Number(this_chid)]?.avatar)
1247 || (selected_group && c.type === 'group' && c.id === selected_group));1248 || (selected_group && c.type === 'group' && c.id === selected_group));
12481249
1249 return {1250 return {
@@ -1481,7 +1482,7 @@ async function loadPersonaForCurrentChat({ doRender = false } = {}) {
1481 * @returns {string[]} - An array of persona keys that are connected to the given character key1482 * @returns {string[]} - An array of persona keys that are connected to the given character key
1482 */1483 */
1483export function getConnectedPersonas(characterKey = undefined) {1484export function getConnectedPersonas(characterKey = undefined) {
1484 characterKey ??= selected_group || characters[this_chid]?.avatar;1485 characterKey ??= selected_group || characters[Number(this_chid)]?.avatar;
1485 const connectedPersonas = Object.entries(power_user.persona_descriptions)1486 const connectedPersonas = Object.entries(power_user.persona_descriptions)
1486 .filter(([_, desc]) => desc.connections?.some(conn => conn.type === 'character' && conn.id === characterKey))1487 .filter(([_, desc]) => desc.connections?.some(conn => conn.type === 'character' && conn.id === characterKey))
1487 .map(([key, _]) => key);1488 .map(([key, _]) => key);
@@ -1513,7 +1514,7 @@ export async function showCharConnections() {
1513 console.log(`Unlocking persona ${personaId} from current character ${name2}`);1514 console.log(`Unlocking persona ${personaId} from current character ${name2}`);
1514 power_user.persona_descriptions[personaId].connections = connections.filter(c => {1515 power_user.persona_descriptions[personaId].connections = connections.filter(c => {
1515 if (menu_type == 'group_edit' && c.type == 'group' && c.id == selected_group) return false;1516 if (menu_type == 'group_edit' && c.type == 'group' && c.id == selected_group) return false;
1516 else if (c.type == 'character' && c.id == characters[this_chid]?.avatar) return false;1517 else if (c.type == 'character' && c.id == characters[Number(this_chid)]?.avatar) return false;
1517 return true;1518 return true;
1518 });1519 });
1519 saveSettingsDebounced();1520 saveSettingsDebounced();
@@ -1545,8 +1546,8 @@ export async function showCharConnections() {
1545export function getCurrentConnectionObj() {1546export function getCurrentConnectionObj() {
1546 if (selected_group)1547 if (selected_group)
1547 return { type: 'group', id: selected_group };1548 return { type: 'group', id: selected_group };
1548 if (characters[this_chid]?.avatar)1549 if (characters[Number(this_chid)]?.avatar)
1549 return { type: 'character', id: characters[this_chid]?.avatar };1550 return { type: 'character', id: characters[Number(this_chid)]?.avatar };
1550 return null;1551 return null;
1551}1552}
15521553
@@ -1664,7 +1665,7 @@ async function syncUserNameToPersona() {
1664 * Only works if only the first message is present, and not in group mode.1665 * Only works if only the first message is present, and not in group mode.
1665 */1666 */
1666export function retriggerFirstMessageOnEmptyChat() {1667export function retriggerFirstMessageOnEmptyChat() {
1667 if (this_chid >= 0 && !selected_group && chat.length === 1) {1668 if (Number(this_chid) >= 0 && !selected_group && chat.length === 1) {
1668 $('#firstmessage_textarea').trigger('input');1669 $('#firstmessage_textarea').trigger('input');
1669 }1670 }
1670}1671}
@@ -1782,7 +1783,6 @@ function setNameCallback({ mode = 'all' }, name) {
1782 if (!persona) persona = Object.entries(power_user.personas).find(([_, personaName]) => personaName.toLowerCase() === name.toLowerCase())?.[1];1783 if (!persona) persona = Object.entries(power_user.personas).find(([_, personaName]) => personaName.toLowerCase() === name.toLowerCase())?.[1];
1783 if (persona) {1784 if (persona) {
1784 autoSelectPersona(persona);1785 autoSelectPersona(persona);
1785 retriggerFirstMessageOnEmptyChat();
1786 return '';1786 return '';
1787 } else if (mode === 'lookup') {1787 } else if (mode === 'lookup') {
1788 toastr.warning(`Persona ${name} not found`);1788 toastr.warning(`Persona ${name} not found`);
@@ -1793,7 +1793,6 @@ function setNameCallback({ mode = 'all' }, name) {
1793 if (['temp', 'all'].includes(mode)) {1793 if (['temp', 'all'].includes(mode)) {
1794 // Otherwise, set just the name1794 // Otherwise, set just the name
1795 setUserName(name); //this prevented quickReply usage1795 setUserName(name); //this prevented quickReply usage
1796 retriggerFirstMessageOnEmptyChat();
1797 }1796 }
17981797
1799 return '';1798 return '';
@@ -1944,9 +1943,6 @@ export async function initPersonas() {
1944 $(document).on('click', '#user_avatar_block .avatar-container', function () {1943 $(document).on('click', '#user_avatar_block .avatar-container', function () {
1945 const imgfile = $(this).attr('data-avatar-id');1944 const imgfile = $(this).attr('data-avatar-id');
1946 setUserAvatar(imgfile);1945 setUserAvatar(imgfile);
1947
1948 // force firstMes {{user}} update on persona switch
1949 retriggerFirstMessageOnEmptyChat();
1950 });1946 });
19511947
1952 $('#persona_rename_button').on('click', () => renamePersona(user_avatar));1948 $('#persona_rename_button').on('click', () => renamePersona(user_avatar));
@@ -1979,4 +1975,3 @@ export async function initPersonas() {
1979 eventSource.on(event_types.CHAT_CHANGED, loadPersonaForCurrentChat);1975 eventSource.on(event_types.CHAT_CHANGED, loadPersonaForCurrentChat);
1980 switchPersonaGridView();1976 switchPersonaGridView();
1981}1977}
1982
public/scripts/templates/promptManagerExportForCharacter.html+0 -4
@@ -1,4 +0,0 @@
1<div class="row">
2 <a class="export-promptmanager-prompts-character list-group-item" data-i18n="Export for character">Export for character</a>
3 <span class="tooltip fa-solid fa-info-circle" data-i18n="[title]Export prompts for this character, including their order." title="Export prompts for this character, including their order."></span>
4</div>
public/scripts/templates/promptManagerExportPopup.html+0 -12
@@ -1,12 +0,0 @@
1<div id="prompt-manager-export-format-popup" class="list-group">
2 <div class="prompt-manager-export-format-popup-flex">
3 <div class="row">
4 <a class="export-promptmanager-prompts-full list-group-item" data-i18n="Export all">Export all</a>
5 <span class="tooltip fa-solid fa-info-circle" data-i18n="[title]Export all your prompts to a file" title="Export all your prompts to a file"></span>
6 </div>
7 {{#if isGlobalStrategy}}
8 {{else}}
9 {{{exportForCharacter}}}
10 {{/if}}
11 </div>
12</div>