#2558 Add persona duping
| @@ -6440,6 +6440,9 @@ | ||
| 6440 | 6440 | <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."> |
| 6441 | 6441 | <i class="fa-fw fa-solid fa-crown"></i> |
| 6442 | 6442 | </button> |
| 6443 | + <button class="menu_button duplicate_persona" title="Duplicate persona" data-i18n="[title]Duplicate persona"> | |
| 6444 | + <i class="fa-fw fa-solid fa-clone"></i> | |
| 6445 | + </button> | |
| 6443 | 6446 | <button class="menu_button delete_avatar" title="Delete persona" data-i18n="[title]Delete persona"> |
| 6444 | 6447 | <i class="fa-fw fa-solid fa-trash-alt"></i> |
| 6445 | 6448 | </button> |
| @@ -1001,6 +1001,42 @@ export function retriggerFirstMessageOnEmptyChat() { | ||
| 1001 | 1001 | } |
| 1002 | 1002 | } |
| 1003 | 1003 | |
| 1004 | +/** | |
| 1005 | + * Duplicates a persona. | |
| 1006 | + * @param {string} avatarId | |
| 1007 | + * @returns {Promise<void>} | |
| 1008 | + */ | |
| 1009 | +async function duplicatePersona(avatarId) { | |
| 1010 | + const personaName = power_user.personas[avatarId]; | |
| 1011 | + | |
| 1012 | + if (!personaName) { | |
| 1013 | + toastr.warning('Current avatar is not a persona'); | |
| 1014 | + return; | |
| 1015 | + } | |
| 1016 | + | |
| 1017 | + const confirm = await Popup.show.confirm('Are you sure you want to duplicate this persona?', personaName); | |
| 1018 | + | |
| 1019 | + if (!confirm) { | |
| 1020 | + console.debug('User cancelled duplicating persona'); | |
| 1021 | + return; | |
| 1022 | + } | |
| 1023 | + | |
| 1024 | + const newAvatarId = `${Date.now()}-${personaName.replace(/[^a-zA-Z0-9]/g, '')}.png`; | |
| 1025 | + const descriptor = power_user.persona_descriptions[avatarId]; | |
| 1026 | + | |
| 1027 | + power_user.personas[newAvatarId] = personaName; | |
| 1028 | + power_user.persona_descriptions[newAvatarId] = { | |
| 1029 | + description: descriptor?.description || '', | |
| 1030 | + position: descriptor?.position || persona_description_positions.IN_PROMPT, | |
| 1031 | + depth: descriptor?.depth || DEFAULT_DEPTH, | |
| 1032 | + role: descriptor?.role || DEFAULT_ROLE, | |
| 1033 | + }; | |
| 1034 | + | |
| 1035 | + await uploadUserAvatar(getUserAvatar(avatarId), newAvatarId); | |
| 1036 | + await getUserAvatars(true, newAvatarId); | |
| 1037 | + saveSettingsDebounced(); | |
| 1038 | +} | |
| 1039 | + | |
| 1004 | 1040 | export function initPersonas() { |
| 1005 | 1041 | $(document).on('click', '.bind_user_name', bindUserNameToPersona); |
| 1006 | 1042 | $(document).on('click', '.set_default_persona', setDefaultPersona); |
| @@ -1059,6 +1095,18 @@ export function initPersonas() { | ||
| 1059 | 1095 | $('#avatar_upload_file').trigger('click'); |
| 1060 | 1096 | }); |
| 1061 | 1097 | |
| 1098 | + $(document).on('click', '#user_avatar_block .duplicate_persona', function (e) { | |
| 1099 | + e.stopPropagation(); | |
| 1100 | + const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile'); | |
| 1101 | + | |
| 1102 | + if (!avatarId) { | |
| 1103 | + console.log('no imgfile'); | |
| 1104 | + return; | |
| 1105 | + } | |
| 1106 | + | |
| 1107 | + duplicatePersona(avatarId); | |
| 1108 | + }); | |
| 1109 | + | |
| 1062 | 1110 | $(document).on('click', '#user_avatar_block .set_persona_image', function (e) { |
| 1063 | 1111 | e.stopPropagation(); |
| 1064 | 1112 | const avatarId = $(this).closest('.avatar-container').find('.avatar').attr('imgfile'); |
| @@ -3032,6 +3032,10 @@ grammarly-extension { | ||
| 3032 | 3032 | opacity: 1; |
| 3033 | 3033 | } |
| 3034 | 3034 | |
| 3035 | +.avatar-container .avatar-buttons .menu_button { | |
| 3036 | + padding: 3px; | |
| 3037 | +} | |
| 3038 | + | |
| 3035 | 3039 | /* Ross should be able to handle this later */ |
| 3036 | 3040 | /*.big-avatars .avatar-buttons{ |
| 3037 | 3041 | justify-content: center; |