Show connected characters in persona panel - Print list of connected characters in persona panel - Fix smaller bugs with missing connections in persona description

255e75c6cf9d4fdd5ebf00320ac33a445818bafd

Wolfsblvt <wolfsblvt@gmail.com>

3 files changed, +41 -4Ignore whitespace
public/index.html+3 -1
@@ -4976,7 +4976,9 @@
49764976 <div data-i18n="Character">Character</div>
49774977 </div>
49784978 </div>
49794979 <div id="persona_connections_list" class="text_muted m-b-1 avatars_inline flex-container scroll-reset-container expander" data-i18n="persona_no_connections">[No connections]</div>
4980+ [No connections]
4981+ </div>
49804982 </div>
49814983
49824984 <div class="persona_management_global_settings">
public/script.js+2 -0
@@ -232,6 +232,7 @@ import {
232232 initPersonas,
233233 setPersonaDescription,
234234 initUserAvatar,
235+ updatePersonaConnectionsAvatarList,
235236} from './scripts/personas.js';
236237import { getBackgrounds, initBackgrounds, loadBackgroundSettings, background_settings } from './scripts/backgrounds.js';
237238import { hideLoader, showLoader } from './scripts/loader.js';
@@ -1537,6 +1538,7 @@ export async function printCharacters(fullRefresh = false) {
15371538 });
15381539
15391540 favsToHotswap();
1541+ updatePersonaConnectionsAvatarList();
15401542}
15411543
15421544/** Checks the state of the current search, and adds/removes the search sorting option accordingly */
public/scripts/personas.js+36 -3
@@ -1,4 +1,6 @@
11import {
2+ buildAvatarList,
3+ characterToEntity,
24 characters,
35 chat,
46 chat_metadata,
@@ -7,6 +9,7 @@ import {
79 event_types,
810 getRequestHeaders,
911 getThumbnailUrl,
12+ groupToEntity,
1013 menu_type,
1114 name1,
1215 name2,
@@ -19,10 +22,10 @@ import {
1922} from '../script.js';
2023import { persona_description_positions, power_user } from './power-user.js';
2124import { getTokenCountAsync } from './tokenizers.js';
2225import { PAGINATION_TEMPLATE, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, getCharIndex, parseJsonFile } from './utils.js';
2326import { debounce_timeout } from './constants.js';
2427import { FILTER_TYPES, FilterHelper } from './filters.js';
2528import { groups, selected_group } from './group-chats.js';
2629import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
2730import { t } from './i18n.js';
2831import { openWorldInfoEditor, world_names } from './world-info.js';
@@ -477,6 +480,34 @@ export function setPersonaDescription() {
477480 .prop('selected', String(true));
478481 $('#persona_lore_button').toggleClass('world_set', !!power_user.persona_description_lorebook);
479482 countPersonaDescriptionTokens();
483+
484+ updatePersonaLockIcons();
485+ updatePersonaConnectionsAvatarList();
486+}
487+
488+/**
489+ * Displays avatar connections for the current persona.
490+ * Converts connections to entities and populates the avatar list. Shows a message if no connections are found.
491+ */
492+export function updatePersonaConnectionsAvatarList() {
493+ /** @type {PersonaConnection[]} */
494+ const connections = power_user.persona_descriptions[user_avatar]?.connections ?? [];
495+ const entities = connections.map(connection => {
496+ if (connection.type === 'character') {
497+ const character = characters.find(c => c.avatar === connection.id);
498+ if (character) return characterToEntity(character, getCharIndex(character));
499+ }
500+ if (connection.type === 'group') {
501+ const group = groups.find(g => g.id === connection.id);
502+ if (group) return groupToEntity(group);
503+ }
504+ return undefined;
505+ }).filter(entity => entity?.item !== undefined);
506+
507+ if (entities.length)
508+ buildAvatarList($('#persona_connections_list'), entities);
509+ else
510+ $('#persona_connections_list').text('[No connections]');
480511}
481512
482513export function autoSelectPersona(name) {
@@ -694,6 +725,7 @@ async function unlockPersona(type = 'chat') {
694725 console.log(`Unlocking persona ${user_avatar} from this character ${name2}`);
695726 power_user.persona_descriptions[user_avatar].connections = connections.filter(c => !isPersonaConnectionLocked(c));
696727 saveSettingsDebounced();
728+ updatePersonaConnectionsAvatarList();
697729 if (power_user.persona_show_notifications) {
698730 toastr.info(t`User persona ${name1} is now unlocked from character ${name2}. Click the "Lock" again to revert.`, t`Persona unlocked`);
699731 }
@@ -756,6 +788,7 @@ async function lockPersona(type = 'chat') {
756788 console.log(`Locking persona ${user_avatar} to this character ${name2}`);
757789 power_user.persona_descriptions[user_avatar].connections = [...connections, newConnection];
758790 saveSettingsDebounced();
791+ updatePersonaConnectionsAvatarList();
759792 if (power_user.persona_show_notifications) {
760793 toastr.success(t`User persona ${name1} is locked to character ${name2}`);
761794 }
@@ -1026,7 +1059,7 @@ function updatePersonaLockIcons() {
10261059
10271060 /** @type {PersonaConnection[]} */
10281061 const connections = power_user.persona_descriptions[user_avatar]?.connections;
10291062 const hasCharLock = !!connections?.some(c =>
10301063 (menu_type === 'character_edit' && c.type === 'character' && c.id === characters[this_chid]?.avatar)
10311064 || (menu_type === 'group_edit' && c.type === 'group' && c.id === selected_group));
10321065 $('#lock_persona_to_char').toggleClass('locked', hasCharLock);