Add persona connection states to persona list - Show persona connection/lock states in persona list (chat & char lock) - Refactor persona images url to 'data-avatar-id' attribute - Try make persona blocks' height consistent - Fix persona list not correctly updating selected persona on navigating pages - Fix group/char difference not correctly working - Create common style template for hover-able images buttons/tags where the label only appears on hover

e5db40cf2dc22c7ca45ab73424d0b6bf594230e6

Wolfsblvt <wolfsblvt@gmail.com>

4 files changed, +162 -99Showing whitespace changes
public/css/toggle-dependent.css+0 -5
@@ -96,11 +96,6 @@ body.charListGrid #rm_print_characters_block .group_select .group_name_block,
96 flex-direction: column;96 flex-direction: column;
97}97}
9898
99#user_avatar_block.gridView .avatar-container .avatar-buttons {
100 flex-wrap: wrap;
101 justify-content: space-evenly;
102}
103
104body.charListGrid #rm_print_characters_block .bogus_folder_select .character_select_container,99body.charListGrid #rm_print_characters_block .bogus_folder_select .character_select_container,
105body.charListGrid #rm_print_characters_block .character_select .character_select_container,100body.charListGrid #rm_print_characters_block .character_select .character_select_container,
106body.charListGrid #rm_print_characters_block .group_select .group_select_container,101body.charListGrid #rm_print_characters_block .group_select .group_select_container,
public/index.html+12 -19
@@ -5470,27 +5470,20 @@
5470 <div class="flex-container wide100pLess70px character_select_container">5470 <div class="flex-container wide100pLess70px character_select_container">
5471 <div class="wide100p character_name_block">5471 <div class="wide100p character_name_block">
5472 <span class="ch_name flex1"></span>5472 <span class="ch_name flex1"></span>
5473 <div class="avatar-buttons">
5474 <!-- <button class="menu_button bind_user_name" title="Bind user name to that avatar" data-i18n="[title]Bind user name to that avatar">
5475 <i class="fa-fw fa-solid fa-user-edit fa-sm"></i>
5476 </button>
5477 <button class="menu_button set_persona_image" title="Change persona image" data-i18n="[title]Change persona image">
5478 <i class="fa-fw fa-solid fa-image fa-sm"></i>
5479 </button>
5480
5481 <button class="menu_button set_default_persona" title="Select this as default persona for the new chats." data-i18n="[title]Select this as default persona for the new chats.">
5482 <i class="fa-fw fa-solid fa-crown fa-sm"></i>
5483 </button>
5484
5485 <button class="menu_button duplicate_persona" title="Duplicate persona" data-i18n="[title]Duplicate persona">
5486 <i class="fa-fw fa-solid fa-clone fa-sm"></i>
5487 </button>
5488 <button class="menu_button delete_avatar" title="Delete persona" data-i18n="[title]Delete persona">
5489 <i class="fa-fw fa-solid fa-trash-alt fa-sm"></i>
5490 </button> -->
5491 </div>
5492 </div>5473 </div>
5493 <div class="ch_description"></div>5474 <div class="ch_description"></div>
5475 <div class="avatar_container_states buttons_block">
5476 <div class="locked_to_chat_label avatar_state has_hover_label menu_button menu_button_icon disabled" title="Persona is locked to the current chat" data-i18n="[title]Persona is locked to the current chat">
5477 <i class="icon fa-solid fa-lock fa-fw"></i>
5478 <i class="label_icon icon fa-solid fa-comments fa-fw"></i>
5479 <div class="label" data-i18n="Chat">Chat</div>
5480 </div>
5481 <div class="locked_to_character_label avatar_state has_hover_label menu_button menu_button_icon disabled " title="Persona is locked to the current character" data-i18n="[title]Persona is locked to the current character">
5482 <i class="icon fa-solid fa-lock fa-fw"></i>
5483 <i class="label_icon icon fa-solid fa-user fa-fw"></i>
5484 <div class="label" data-i18n="Character">Character</div>
5485 </div>
5486 </div>
5494 </div>5487 </div>
5495 </div>5488 </div>
5496 </div>5489 </div>
public/scripts/personas.js+92 -45
@@ -10,7 +10,6 @@ import {
10 getRequestHeaders,10 getRequestHeaders,
11 getThumbnailUrl,11 getThumbnailUrl,
12 groupToEntity,12 groupToEntity,
13 menu_type,
14 name1,13 name1,
15 name2,14 name2,
16 reloadCurrentChat,15 reloadCurrentChat,
@@ -40,6 +39,15 @@ import { saveMetadataDebounced } from './extensions.js';
4039
41/** @typedef {'chat' | 'character' | 'default'} PersonaLockType Type of the persona lock */40/** @typedef {'chat' | 'character' | 'default'} PersonaLockType Type of the persona lock */
4241
42/**
43 * @typedef {object} PersonaState
44 * @property {string} avatarId - The avatar id of the persona
45 * @property {boolean} default - Whether this persona is the default one for all new chats
46 * @property {object} locked - An object containing the lock states
47 * @property {boolean} locked.chat - Whether the persona is locked to the currently open chat
48 * @property {boolean} locked.character - Whether the persona is locked to the currently open character or group
49 */
50
43const USER_AVATAR_PATH = 'User Avatars/';51const USER_AVATAR_PATH = 'User Avatars/';
4452
45let savePersonasPage = 0;53let savePersonasPage = 0;
@@ -66,7 +74,7 @@ export function getUserAvatar(avatarImg) {
66export function initUserAvatar(avatar) {74export function initUserAvatar(avatar) {
67 user_avatar = avatar;75 user_avatar = avatar;
68 reloadUserAvatar();76 reloadUserAvatar();
69 highlightSelectedAvatar();77 updatePersonaUIStates();
70}78}
7179
72/**80/**
@@ -74,19 +82,14 @@ export function initUserAvatar(avatar) {
74 * @param {string} imgfile Link to an image file82 * @param {string} imgfile Link to an image file
75 */83 */
76export function setUserAvatar(imgfile, { toastPersonaNameChange = true } = {}) {84export function setUserAvatar(imgfile, { toastPersonaNameChange = true } = {}) {
77 user_avatar = imgfile && typeof imgfile === 'string' ? imgfile : $(this).attr('imgfile');85 user_avatar = imgfile && typeof imgfile === 'string' ? imgfile : $(this).attr('data-avatar-id');
78 reloadUserAvatar();86 reloadUserAvatar();
79 highlightSelectedAvatar();87 updatePersonaUIStates();
80 selectCurrentPersona({ toastPersonaNameChange: toastPersonaNameChange });88 selectCurrentPersona({ toastPersonaNameChange: toastPersonaNameChange });
81 saveSettingsDebounced();89 saveSettingsDebounced();
82 $('.zoomed_avatar[forchar]').remove();90 $('.zoomed_avatar[forchar]').remove();
83}91}
8492
85function highlightSelectedAvatar() {
86 $('#user_avatar_block .avatar-container').removeClass('selected');
87 $(`#user_avatar_block .avatar-container[imgfile="${user_avatar}"]`).addClass('selected');
88}
89
90function reloadUserAvatar(force = false) {93function reloadUserAvatar(force = false) {
91 $('.mes').each(function () {94 $('.mes').each(function () {
92 const avatarImg = $(this).find('.avatar img');95 const avatarImg = $(this).find('.avatar img');
@@ -146,24 +149,32 @@ function verifyPersonaSearchSortRule() {
146149
147/**150/**
148 * Gets a rendered avatar block.151 * Gets a rendered avatar block.
149 * @param {string} name Avatar file name152 * @param {string} avatarId Avatar file name
150 * @returns {JQuery<HTMLElement>} Avatar block153 * @returns {JQuery<HTMLElement>} Avatar block
151 */154 */
152function getUserAvatarBlock(name) {155function getUserAvatarBlock(avatarId) {
153 const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;156 const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
154 const template = $('#user_avatar_template .avatar-container').clone();157 const template = $('#user_avatar_template .avatar-container').clone();
155 const personaName = power_user.personas[name];158 const personaName = power_user.personas[avatarId];
156 const personaDescription = power_user.persona_descriptions[name]?.description;159 const personaDescription = power_user.persona_descriptions[avatarId]?.description;
160
157 template.find('.ch_name').text(personaName || '[Unnamed Persona]');161 template.find('.ch_name').text(personaName || '[Unnamed Persona]');
158 template.find('.ch_description').text(personaDescription || $('#user_avatar_block').attr('no_desc_text')).toggleClass('text_muted', !personaDescription);162 template.find('.ch_description').text(personaDescription || $('#user_avatar_block').attr('no_desc_text')).toggleClass('text_muted', !personaDescription);
159 template.attr('imgfile', name);163 template.attr('data-avatar-id', avatarId);
160 template.find('.avatar').attr('imgfile', name).attr('title', name);164 template.find('.avatar').attr('data-avatar-id', avatarId).attr('title', avatarId);
161 template.toggleClass('default_persona', name === power_user.default_persona);165 template.toggleClass('default_persona', avatarId === power_user.default_persona);
162 let avatarUrl = getUserAvatar(name);166 let avatarUrl = getUserAvatar(avatarId);
163 if (isFirefox) {167 if (isFirefox) {
164 avatarUrl += '?t=' + Date.now();168 avatarUrl += '?t=' + Date.now();
165 }169 }
166 template.find('img').attr('src', avatarUrl);170 template.find('img').attr('src', avatarUrl);
171
172 // Make sure description block has at least three rows. Otherwise height looks inconsistent. I don't have a better idea for this.
173 const currentText = template.find('.ch_description').text();
174 if (currentText.split('\n').length < 3) {
175 template.find('.ch_description').text(currentText + '\n\xa0\n\xa0');
176 }
177
167 $('#user_avatar_block').append(template);178 $('#user_avatar_block').append(template);
168 return template;179 return template;
169}180}
@@ -218,7 +229,7 @@ export async function getUserAvatars(doRender = true, openPageAt = '') {
218 for (const item of data) {229 for (const item of data) {
219 $(listId).append(getUserAvatarBlock(item));230 $(listId).append(getUserAvatarBlock(item));
220 }231 }
221 highlightSelectedAvatar();232 updatePersonaUIStates();
222 },233 },
223 afterSizeSelectorChange: function (e) {234 afterSizeSelectorChange: function (e) {
224 localStorage.setItem(storageKey, e.target.value);235 localStorage.setItem(storageKey, e.target.value);
@@ -486,7 +497,7 @@ export function setPersonaDescription() {
486 $('#persona_lore_button').toggleClass('world_set', !!power_user.persona_description_lorebook);497 $('#persona_lore_button').toggleClass('world_set', !!power_user.persona_description_lorebook);
487 countPersonaDescriptionTokens();498 countPersonaDescriptionTokens();
488499
489 updatePersonaLockIcons();500 updatePersonaUIStates();
490 updatePersonaConnectionsAvatarList();501 updatePersonaConnectionsAvatarList();
491}502}
492503
@@ -780,7 +791,7 @@ function selectCurrentPersona({ toastPersonaNameChange = true } = {}) {
780 toastr.success(`Persona ${personaName} selected and auto-locked to current chat`, t`Persona Selected`);791 toastr.success(`Persona ${personaName} selected and auto-locked to current chat`, t`Persona Selected`);
781 }792 }
782 saveMetadataDebounced();793 saveMetadataDebounced();
783 updatePersonaLockIcons();794 updatePersonaUIStates();
784 }795 }
785796
786 // As the last step, inform user if the persona is only temporarily chosen797 // As the last step, inform user if the persona is only temporarily chosen
@@ -806,8 +817,8 @@ function selectCurrentPersona({ toastPersonaNameChange = true } = {}) {
806 * @returns {boolean} Whether the connection is locked817 * @returns {boolean} Whether the connection is locked
807 */818 */
808export function isPersonaConnectionLocked(connection) {819export function isPersonaConnectionLocked(connection) {
809 return (menu_type === 'character_edit' && connection.type === 'character' && connection.id === characters[this_chid]?.avatar)820 return (!selected_group && connection.type === 'character' && connection.id === characters[this_chid]?.avatar)
810 || (menu_type === 'group_edit' && connection.type === 'group' && connection.id === selected_group);821 || (selected_group && connection.type === 'group' && connection.id === selected_group);
811}822}
812823
813/**824/**
@@ -894,7 +905,7 @@ async function unlockPersona(type = 'chat') {
894 throw new Error(`Unknown persona lock type: ${type}`);905 throw new Error(`Unknown persona lock type: ${type}`);
895 }906 }
896907
897 updatePersonaLockIcons();908 updatePersonaUIStates();
898}909}
899910
900/**911/**
@@ -969,7 +980,7 @@ async function lockPersona(type = 'chat') {
969 throw new Error(`Unknown persona lock type: ${type}`);980 throw new Error(`Unknown persona lock type: ${type}`);
970 }981 }
971982
972 updatePersonaLockIcons();983 updatePersonaUIStates();
973}984}
974985
975986
@@ -1149,7 +1160,7 @@ function getOrCreatePersonaDescriptor() {
11491160
1150async function toggleDefaultPersonaClicked(e) {1161async function toggleDefaultPersonaClicked(e) {
1151 e?.stopPropagation();1162 e?.stopPropagation();
1152 const avatarId = $(e.currentTarget).closest('.avatar-container').find('.avatar').attr('imgfile');1163 const avatarId = $(e.currentTarget).closest('.avatar-container').find('.avatar').attr('data-avatar-id');
1153 if (avatarId) {1164 if (avatarId) {
1154 await toggleDefaultPersona(avatarId);1165 await toggleDefaultPersona(avatarId);
1155 } else {1166 } else {
@@ -1213,26 +1224,62 @@ async function toggleDefaultPersona(avatarId, { quiet: quiet = false } = {}) {
12131224
1214 saveSettingsDebounced();1225 saveSettingsDebounced();
1215 await getUserAvatars(true, avatarId);1226 await getUserAvatars(true, avatarId);
1216 updatePersonaLockIcons();1227 updatePersonaUIStates();
1217}1228}
12181229
1219function updatePersonaLockIcons() {1230/**
1220 const isDefaultPersona = power_user.default_persona === user_avatar;1231 * Returns an object with 3 properties that describe the state of the given persona
1221 $('#lock_persona_default').toggleClass('locked', isDefaultPersona);1232 *
12221233 * - default: Whether this persona is the default one for all new chats
1223 const hasChatLock = chat_metadata['persona'] == user_avatar;1234 * - locked: An object containing the lock states
1224 $('#lock_user_name').toggleClass('locked', hasChatLock);1235 * - chat: Whether the persona is locked to the currently open chat
1225 $('#lock_user_name i.icon').toggleClass('fa-lock', hasChatLock);1236 * - character: Whether the persona is locked to the currently open character or group
1226 $('#lock_user_name i.icon').toggleClass('fa-unlock', !hasChatLock);1237 * @param {string} avatarId - The avatar id of the persona to get the state for
1238 * @returns {PersonaState} An object describing the state of the given persona
1239 */
1240function getPersonaStates(avatarId) {
1241 const isDefaultPersona = power_user.default_persona === avatarId;
1242 const hasChatLock = chat_metadata['persona'] == avatarId;
12271243
1228 /** @type {PersonaConnection[]} */1244 /** @type {PersonaConnection[]} */
1229 const connections = power_user.persona_descriptions[user_avatar]?.connections;1245 const connections = power_user.persona_descriptions[avatarId]?.connections;
1230 const hasCharLock = !!connections?.some(c =>1246 const hasCharLock = !!connections?.some(c =>
1231 (menu_type === 'character_edit' && c.type === 'character' && c.id === characters[this_chid]?.avatar)1247 (!selected_group && c.type === 'character' && c.id === characters[this_chid]?.avatar)
1232 || (menu_type === 'group_edit' && c.type === 'group' && c.id === selected_group));1248 || (selected_group && c.type === 'group' && c.id === selected_group));
1233 $('#lock_persona_to_char').toggleClass('locked', hasCharLock);1249
1234 $('#lock_persona_to_char i.icon').toggleClass('fa-lock', hasCharLock);1250 return {
1235 $('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !hasCharLock);1251 avatarId: avatarId,
1252 default: isDefaultPersona,
1253 locked: {
1254 chat: hasChatLock,
1255 character: hasCharLock,
1256 },
1257 };
1258}
1259
1260function updatePersonaUIStates() {
1261 // Update the persona list
1262 $('#user_avatar_block .avatar-container').each(function () {
1263 const avatarId = $(this).attr('data-avatar-id');
1264 const states = getPersonaStates(avatarId);
1265 $(this).toggleClass('default_persona', states.default);
1266 $(this).toggleClass('locked_to_chat', states.locked.chat);
1267 $(this).toggleClass('locked_to_character', states.locked.character);
1268 $(this).toggleClass('selected', avatarId === user_avatar);
1269 });
1270
1271 // Buttons for the persona panel on the right
1272 const personaStates = getPersonaStates(user_avatar);
1273
1274 $('#lock_persona_default').toggleClass('locked', personaStates.default);
1275
1276 $('#lock_user_name').toggleClass('locked', personaStates.locked.chat);
1277 $('#lock_user_name i.icon').toggleClass('fa-lock', personaStates.locked.chat);
1278 $('#lock_user_name i.icon').toggleClass('fa-unlock', !personaStates.locked.chat);
1279
1280 $('#lock_persona_to_char').toggleClass('locked', personaStates.locked.character);
1281 $('#lock_persona_to_char i.icon').toggleClass('fa-lock', personaStates.locked.character);
1282 $('#lock_persona_to_char i.icon').toggleClass('fa-unlock', !personaStates.locked.character);
1236}1283}
12371284
1238async function loadPersonaForCurrentChat({ doRender = false } = {}) {1285async function loadPersonaForCurrentChat({ doRender = false } = {}) {
@@ -1315,7 +1362,7 @@ async function loadPersonaForCurrentChat({ doRender = false } = {}) {
1315 }1362 }
1316 }1363 }
13171364
1318 updatePersonaLockIcons();1365 updatePersonaUIStates();
1319}1366}
13201367
1321/**1368/**
@@ -1325,7 +1372,7 @@ async function loadPersonaForCurrentChat({ doRender = false } = {}) {
1325 * @returns {string[]} - An array of persona keys that are connected to the given character key1372 * @returns {string[]} - An array of persona keys that are connected to the given character key
1326 */1373 */
1327export function getConnectedPersonas(characterKey = undefined) {1374export function getConnectedPersonas(characterKey = undefined) {
1328 characterKey ??= menu_type === 'group_edit' ? selected_group : characters[this_chid]?.avatar;1375 characterKey ??= selected_group || characters[this_chid]?.avatar;
1329 const connectedPersonas = Object.entries(power_user.persona_descriptions)1376 const connectedPersonas = Object.entries(power_user.persona_descriptions)
1330 .filter(([_, desc]) => desc.connections?.some(conn => conn.type === 'character' && conn.id === characterKey))1377 .filter(([_, desc]) => desc.connections?.some(conn => conn.type === 'character' && conn.id === characterKey))
1331 .map(([key, _]) => key);1378 .map(([key, _]) => key);
@@ -1339,9 +1386,9 @@ export function getConnectedPersonas(characterKey = undefined) {
1339 */1386 */
13401387
1341export function getCurrentConnectionObj() {1388export function getCurrentConnectionObj() {
1342 if (menu_type === 'group_edit')1389 if (selected_group)
1343 return { type: 'group', id: selected_group };1390 return { type: 'group', id: selected_group };
1344 if (menu_type == 'character_edit')1391 if (characters[this_chid]?.avatar)
1345 return { type: 'character', id: characters[this_chid]?.avatar };1392 return { type: 'character', id: characters[this_chid]?.avatar };
1346 return null;1393 return null;
1347}1394}
@@ -1538,7 +1585,7 @@ export function initPersonas() {
1538 $('#avatar_upload_file').on('change', changeUserAvatar);1585 $('#avatar_upload_file').on('change', changeUserAvatar);
15391586
1540 $(document).on('click', '#user_avatar_block .avatar-container', function () {1587 $(document).on('click', '#user_avatar_block .avatar-container', function () {
1541 const imgfile = $(this).attr('imgfile');1588 const imgfile = $(this).attr('data-avatar-id');
1542 setUserAvatar(imgfile);1589 setUserAvatar(imgfile);
15431590
1544 // force firstMes {{user}} update on persona switch1591 // force firstMes {{user}} update on persona switch
public/style.css+58 -30
@@ -222,6 +222,37 @@ table.responsiveTable {
222 animation-name: flash;222 animation-name: flash;
223}223}
224224
225.has_hover_label .label_icon {
226 transition: opacity var(--animation-duration) ease, max-width var(--animation-duration) ease;
227}
228.has_hover_label .label {
229 transition: opacity var(--animation-duration-slow) ease, max-width var(--animation-duration-slow) ease;
230 /* Prevent double gap on hidden icon */
231 margin-left: -5px;
232}
233
234.has_hover_label .label_icon,
235.has_hover_label .label {
236 transition-delay: var(--animation-duration-slow);
237}
238.has_hover_label.fast .label_icon,
239.has_hover_label.fast .label {
240 transition-delay: var(--animation-duration);
241}
242
243.has_hover_label .label_icon,
244.has_hover_label:hover .label {
245 opacity: 1;
246 max-width: 100px;
247}
248
249.has_hover_label:hover .label_icon,
250.has_hover_label .label {
251 opacity: 0;
252 max-width: 0;
253 overflow: hidden;
254}
255
225/* Keyboard/focus navigation styling */256/* Keyboard/focus navigation styling */
226/* Mimic the outline of keyboard navigation for most most focusable controls */257/* Mimic the outline of keyboard navigation for most most focusable controls */
227.interactable {258.interactable {
@@ -2805,6 +2836,7 @@ select option:not(:checked) {
2805.menu_button.disabled {2836.menu_button.disabled {
2806 filter: brightness(75%) grayscale(1);2837 filter: brightness(75%) grayscale(1);
2807 opacity: 0.5;2838 opacity: 0.5;
2839 cursor: inherit;
2808 pointer-events: none;2840 pointer-events: none;
2809}2841}
28102842
@@ -2880,8 +2912,7 @@ select option:not(:checked) {
2880}2912}
28812913
2882#form_character_search_form .menu_button,2914#form_character_search_form .menu_button,
2883#GroupFavDelOkBack .menu_button,2915#GroupFavDelOkBack .menu_button {
2884.avatar-container .menu_button {
2885 margin: 0;2916 margin: 0;
2886 height: fit-content;2917 height: fit-content;
2887 padding: 5px;2918 padding: 5px;
@@ -2915,8 +2946,9 @@ select option:not(:checked) {
2915 width: max-content;2946 width: max-content;
2916}2947}
29172948
2918#persona-management-block .menu_button {2949#persona-management-block .avatar_container_states .menu_button {
2919 filter: grayscale(0.5);2950 padding: 3px 5px;
2951 pointer-events: initial;
2920}2952}
29212953
2922#persona_controls .persona_name {2954#persona_controls .persona_name {
@@ -3321,28 +3353,6 @@ grammarly-extension {
3321 z-index: 35;3353 z-index: 35;
3322}3354}
33233355
3324.avatar-container .avatar-buttons {
3325 display: flex;
3326 flex-direction: row;
3327 gap: 3px;
3328 opacity: 0.3;
3329 transition: opacity 0.25s ease-in-out;
3330}
3331
3332.avatar-container .avatar-buttons:hover {
3333 opacity: 1;
3334}
3335
3336.avatar-container .avatar-buttons .menu_button {
3337 padding: 3px;
3338}
3339
3340/* Ross should be able to handle this later */
3341/*.big-avatars .avatar-buttons{
3342 justify-content: center;
3343 width: fit-content;
3344}*/
3345
3346.avatar_div .avatar {3356.avatar_div .avatar {
3347 /* margin-left: 4px;3357 /* margin-left: 4px;
3348 margin-right: 10px;3358 margin-right: 10px;
@@ -3603,6 +3613,7 @@ grammarly-extension {
36033613
3604.menu_button {3614.menu_button {
3605 color: var(--SmartThemeBodyColor);3615 color: var(--SmartThemeBodyColor);
3616 filter: grayscale(0.5);
3606 background-color: var(--SmartThemeBlurTintColor);3617 background-color: var(--SmartThemeBlurTintColor);
3607 border: 1px solid var(--SmartThemeBorderColor);3618 border: 1px solid var(--SmartThemeBorderColor);
3608 border-radius: 5px;3619 border-radius: 5px;
@@ -3622,8 +3633,8 @@ grammarly-extension {
3622 min-width: calc(1.25em + 12px);3633 min-width: calc(1.25em + 12px);
3623}3634}
36243635
3625.menu_button:hover,3636.menu_button:not(.disabled):hover,
3626.menu_button.active {3637.menu_button:not(.disabled).active {
3627 background-color: var(--white30a);3638 background-color: var(--white30a);
3628}3639}
36293640
@@ -3876,11 +3887,28 @@ input[type='checkbox'].del_checkbox {
3876 color: var(--golden);3887 color: var(--golden);
3877}3888}
38783889
3890.avatar-container .avatar_state .fa-lock {
3891 color: var(--active);
3892}
3893
3894.avatar-container:not(.locked_to_chat) .locked_to_chat_label {
3895 display: none;
3896}
3897.avatar-container:not(.locked_to_character) .locked_to_character_label {
3898 display: none;
3899}
3900
3879#lock_persona_default.locked i.icon {3901#lock_persona_default.locked i.icon {
3880 color: var(--golden);3902 color: var(--golden);
3881}3903}
3882#lock_user_name.locked i.icon,3904
3883#lock_persona_to_char.locked i.icon {3905#lock_user_name.locked .icon,
3906.avatar-container.locked_to_chat .locked_to_chat_label .icon {
3907 color: var(--SmartThemeQuoteColor);
3908}
3909
3910#lock_persona_to_char.locked .icon,
3911.avatar-container.locked_to_character .locked_to_character_label .icon {
3884 color: var(--active);3912 color: var(--active);
3885}3913}
38863914