On char rename, update auxiliary connections - Move WI char lore (additional lorebooks) based on rename - Move character-bound Author's Note based on rename - Extend core `getCharFilename` to be able to take an avatarKey, instead of just uid
| @@ -493,6 +493,7 @@ export const event_types = { | |||
| 493 | // TODO: Naming convention is inconsistent with other events | 493 | // TODO: Naming convention is inconsistent with other events |
| 494 | CHARACTER_DELETED: 'characterDeleted', | 494 | CHARACTER_DELETED: 'characterDeleted', |
| 495 | CHARACTER_DUPLICATED: 'character_duplicated', | 495 | CHARACTER_DUPLICATED: 'character_duplicated', |
| 496 | CHARACTER_RENAMED: 'character_renamed', | ||
| 496 | /** @deprecated The event is aliased to STREAM_TOKEN_RECEIVED. */ | 497 | /** @deprecated The event is aliased to STREAM_TOKEN_RECEIVED. */ |
| 497 | SMOOTH_STREAM_TOKEN_RECEIVED: 'stream_token_received', | 498 | SMOOTH_STREAM_TOKEN_RECEIVED: 'stream_token_received', |
| 498 | STREAM_TOKEN_RECEIVED: 'stream_token_received', | 499 | STREAM_TOKEN_RECEIVED: 'stream_token_received', |
| @@ -6241,9 +6242,29 @@ export async function renameCharacter(name = null, { silent = false, renameChats | |||
| 6241 | const data = await response.json(); | 6242 | const data = await response.json(); |
| 6242 | const newAvatar = data.avatar; | 6243 | const newAvatar = data.avatar; |
| 6243 | 6244 | ||
| 6244 | // Replace tags list | 6245 | const oldName = getCharaFilename(null, { manualAvatarKey: oldAvatar }); |
| 6246 | const newName = getCharaFilename(null, { manualAvatarKey: newAvatar }); | ||
| 6247 | |||
| 6248 | // Replace other auxillery fields where was referenced by avatar key | ||
| 6249 | // Tag List | ||
| 6245 | renameTagKey(oldAvatar, newAvatar); | 6250 | renameTagKey(oldAvatar, newAvatar); |
| 6246 | 6251 | ||
| 6252 | // Addtional lore books | ||
| 6253 | const charLore = world_info.charLore?.find(x => x.name == oldName); | ||
| 6254 | if (charLore) { | ||
| 6255 | charLore.name = newName; | ||
| 6256 | saveSettingsDebounced(); | ||
| 6257 | } | ||
| 6258 | |||
| 6259 | // Char-bound Author's Notes | ||
| 6260 | const charNote = extension_settings.note.chara?.find(x => x.name == oldName); | ||
| 6261 | if (charNote) { | ||
| 6262 | charNote.name = newName; | ||
| 6263 | saveSettingsDebounced(); | ||
| 6264 | } | ||
| 6265 | |||
| 6266 | eventSource.emit(event_types.CHARACTER_RENAMED, oldAvatar, newAvatar); | ||
| 6267 | |||
| 6247 | // Reload characters list | 6268 | // Reload characters list |
| 6248 | await getCharacters(); | 6269 | await getCharacters(); |
| 6249 | 6270 | ||
| @@ -994,13 +994,18 @@ export function getImageSizeFromDataURL(dataUrl) { | |||
| 994 | }); | 994 | }); |
| 995 | } | 995 | } |
| 996 | 996 | ||
| 997 | export function getCharaFilename(chid) { | 997 | /** |
| 998 | * Gets the filename of the character avatar without extension | ||
| 999 | * @param {number?} [chid=null] - Character ID. If not provided, uses the current character ID | ||
| 1000 | * @param {object} [options={}] - Options arguments | ||
| 1001 | * @param {string?} [options.manualAvatarKey=null] - Manually take the following avatar key, instead of using the chid to determine the name | ||
| 1002 | * @returns {string?} The filename of the character avatar without extension, or null if the character ID is invalid | ||
| 1003 | */ | ||
| 1004 | export function getCharaFilename(chid = null, { manualAvatarKey = null } = {}) { | ||
| 998 | const context = getContext(); | 1005 | const context = getContext(); |
| 999 | const fileName = context.characters[chid ?? context.characterId]?.avatar; | 1006 | const fileName = manualAvatarKey ?? context.characters[chid ?? context.characterId]?.avatar; |
| 1000 | 1007 | ||
| 1001 | if (fileName) { | 1008 | return fileName?.replace(/\.[^/.]+$/, '') ?? null; |
| 1002 | return fileName.replace(/\.[^/.]+$/, ''); | ||
| 1003 | } | ||
| 1004 | } | 1009 | } |
| 1005 | 1010 | ||
| 1006 | /** | 1011 | /** |