From ba3966e1488cc0ad0ff0e081bf0e51fa747c08ff Mon Sep 17 00:00:00 2001 From: artisticMink Date: Sat, 9 Dec 2023 13:21:46 +0100 Subject: [PATCH 1/5] Only refresh character list after all deletions have been processed. --- public/script.js | 5 +++-- public/scripts/BulkEditOverlay.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/public/script.js b/public/script.js index 79fb6a917..082e44c39 100644 --- a/public/script.js +++ b/public/script.js @@ -7652,8 +7652,9 @@ export async function handleDeleteCharacter(popup_type, this_chid, delete_chats) * * @param {string} name - The name of the character to be deleted. * @param {string} avatar - The avatar URL of the character to be deleted. + * @param {boolean} reloadCharacters - Whether the character list should be refreshed after deletion. */ -export async function deleteCharacter(name, avatar) { +export async function deleteCharacter(name, avatar, reloadCharacters = true) { await clearChat(); $('#character_cross').click(); this_chid = 'invalid-safety-id'; @@ -7664,7 +7665,7 @@ export async function deleteCharacter(name, avatar) { $(document.getElementById('rm_button_selected_ch')).children('h2').text(''); this_chid = undefined; delete tag_map[avatar]; - await getCharacters(); + if (reloadCharacters) await getCharacters(); select_rm_info('char_delete', name); await printMessages(); saveSettingsDebounced(); diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index cbf80ba7a..5e2e65a2e 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -123,9 +123,9 @@ class CharacterContextMenu { cache: 'no-cache', }).then(response => { if (response.ok) { - deleteCharacter(character.name, character.avatar).then(() => { + return deleteCharacter(character.name, character.avatar, false).then(() => { if (deleteChats) { - fetch('/api/characters/chats', { + return fetch('/api/characters/chats', { method: 'POST', body: JSON.stringify({ avatar_url: character.avatar }), headers: getRequestHeaders(), From 46924509753b9b4c2f2ce61f41fd05e00a05c830 Mon Sep 17 00:00:00 2001 From: artisticMink Date: Sat, 9 Dec 2023 14:36:15 +0100 Subject: [PATCH 2/5] Enable getPastCharacterChats to work with specific character ids --- public/script.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/public/script.js b/public/script.js index 082e44c39..a89a9ce46 100644 --- a/public/script.js +++ b/public/script.js @@ -5921,20 +5921,23 @@ export async function getChatsFromFiles(data, isGroupChat) { * The function sends a POST request to the server to retrieve all chats for the character. It then * processes the received data, sorts it by the file name, and returns the sorted data. * + * @param {null|number} [characterId=null] - When set, the function will use this character id instead of this_chid. + * * @returns {Promise} - An array containing metadata of all past chats of the character, sorted * in descending order by file name. Returns `undefined` if the fetch request is unsuccessful. */ -async function getPastCharacterChats() { - if (!characters[this_chid]) return; +export async function getPastCharacterChats(characterId = null) { + characterId = characterId || this_chid; + if (!characters[characterId]) return []; const response = await fetch('/api/characters/chats', { method: 'POST', - body: JSON.stringify({ avatar_url: characters[this_chid].avatar }), + body: JSON.stringify({ avatar_url: characters[characterId].avatar }), headers: getRequestHeaders(), }); if (!response.ok) { - return; + return []; } let data = await response.json(); From dfd41a110a0fd881d9577fcf751a36d8442c4425 Mon Sep 17 00:00:00 2001 From: artisticMink Date: Sat, 9 Dec 2023 14:36:37 +0100 Subject: [PATCH 3/5] Prevent 'no such file or directory' error when mass deleting characters --- public/scripts/BulkEditOverlay.js | 54 ++++++++++++------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index 5e2e65a2e..62a2091e2 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -6,7 +6,7 @@ import { deleteCharacter, event_types, eventSource, - getCharacters, + getCharacters, getPastCharacterChats, getRequestHeaders, printCharacters, this_chid, @@ -119,31 +119,20 @@ class CharacterContextMenu { return fetch('/api/characters/delete', { method: 'POST', headers: getRequestHeaders(), - body: JSON.stringify({ avatar_url: character.avatar, delete_chats: deleteChats }), + body: JSON.stringify({avatar_url: character.avatar, delete_chats: deleteChats}), cache: 'no-cache', }).then(response => { if (response.ok) { return deleteCharacter(character.name, character.avatar, false).then(() => { - if (deleteChats) { - return fetch('/api/characters/chats', { - method: 'POST', - body: JSON.stringify({ avatar_url: character.avatar }), - headers: getRequestHeaders(), - }).then((response) => { - let data = response.json(); - data = Object.values(data); - const pastChats = data.sort((a, b) => a['file_name'].localeCompare(b['file_name'])).reverse(); - - for (const chat of pastChats) { - const name = chat.file_name.replace('.jsonl', ''); - eventSource.emit(event_types.CHAT_DELETED, name); - } - }); - } + eventSource.emit('characterDeleted', {id: characterId, character: characters[characterId]}); + if (deleteChats) getPastCharacterChats(characterId).then(pastChats => { + for (const chat of pastChats) { + const name = chat.file_name.replace('.jsonl', ''); + eventSource.emit(event_types.CHAT_DELETED, name); + } + }); }); } - - eventSource.emit('characterDeleted', { id: this_chid, character: characters[this_chid] }); }); }; @@ -473,18 +462,18 @@ class BulkEditOverlay { this.isLongPress = true; setTimeout(() => { - if (this.isLongPress && !cancel) { - if (this.state === BulkEditOverlayState.browse) { - this.selectState(); - } else if (this.state === BulkEditOverlayState.select) { - this.#contextMenuOpen = true; - CharacterContextMenu.show(...this.#getContextMenuPosition(event)); + if (this.isLongPress && !cancel) { + if (this.state === BulkEditOverlayState.browse) { + this.selectState(); + } else if (this.state === BulkEditOverlayState.select) { + this.#contextMenuOpen = true; + CharacterContextMenu.show(...this.#getContextMenuPosition(event)); + } } - } - this.container.removeEventListener('mouseup', cancelHold); - this.container.removeEventListener('touchend', cancelHold); - }, + this.container.removeEventListener('mouseup', cancelHold); + this.container.removeEventListener('touchend', cancelHold); + }, BulkEditOverlay.longPressDelay); }; @@ -626,12 +615,11 @@ class BulkEditOverlay { showLoader(); toastr.info('We\'re deleting your characters, please wait...', 'Working on it'); - Promise.all(this.selectedCharacters.map(async characterId => CharacterContextMenu.delete(characterId, deleteChats))) + Promise.allSettled(this.selectedCharacters.map(async characterId => CharacterContextMenu.delete(characterId, deleteChats))) .then(() => getCharacters()) .then(() => this.browseState()) .finally(() => hideLoader()); - }, - ); + }); }; /** From 04c83eae71a72a885225fec257484ff99c2bc1e1 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:07:55 +0200 Subject: [PATCH 4/5] Use null coalescing operator --- public/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/script.js b/public/script.js index a89a9ce46..64cb41752 100644 --- a/public/script.js +++ b/public/script.js @@ -5927,7 +5927,7 @@ export async function getChatsFromFiles(data, isGroupChat) { * in descending order by file name. Returns `undefined` if the fetch request is unsuccessful. */ export async function getPastCharacterChats(characterId = null) { - characterId = characterId || this_chid; + characterId = characterId ?? this_chid; if (!characters[characterId]) return []; const response = await fetch('/api/characters/chats', { From b915b89ca9a43baf489b636b9339ca08489dba9b Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sat, 9 Dec 2023 16:09:10 +0200 Subject: [PATCH 5/5] Fix ESLint --- public/scripts/BulkEditOverlay.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index 62a2091e2..d12e1599e 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -6,10 +6,10 @@ import { deleteCharacter, event_types, eventSource, - getCharacters, getPastCharacterChats, + getCharacters, + getPastCharacterChats, getRequestHeaders, printCharacters, - this_chid, } from '../script.js'; import { favsToHotswap } from './RossAscends-mods.js'; @@ -119,12 +119,12 @@ class CharacterContextMenu { return fetch('/api/characters/delete', { method: 'POST', headers: getRequestHeaders(), - body: JSON.stringify({avatar_url: character.avatar, delete_chats: deleteChats}), + body: JSON.stringify({ avatar_url: character.avatar, delete_chats: deleteChats }), cache: 'no-cache', }).then(response => { if (response.ok) { return deleteCharacter(character.name, character.avatar, false).then(() => { - eventSource.emit('characterDeleted', {id: characterId, character: characters[characterId]}); + eventSource.emit('characterDeleted', { id: characterId, character: characters[characterId] }); if (deleteChats) getPastCharacterChats(characterId).then(pastChats => { for (const chat of pastChats) { const name = chat.file_name.replace('.jsonl', ''); @@ -462,18 +462,18 @@ class BulkEditOverlay { this.isLongPress = true; setTimeout(() => { - if (this.isLongPress && !cancel) { - if (this.state === BulkEditOverlayState.browse) { - this.selectState(); - } else if (this.state === BulkEditOverlayState.select) { - this.#contextMenuOpen = true; - CharacterContextMenu.show(...this.#getContextMenuPosition(event)); - } + if (this.isLongPress && !cancel) { + if (this.state === BulkEditOverlayState.browse) { + this.selectState(); + } else if (this.state === BulkEditOverlayState.select) { + this.#contextMenuOpen = true; + CharacterContextMenu.show(...this.#getContextMenuPosition(event)); } + } - this.container.removeEventListener('mouseup', cancelHold); - this.container.removeEventListener('touchend', cancelHold); - }, + this.container.removeEventListener('mouseup', cancelHold); + this.container.removeEventListener('touchend', cancelHold); + }, BulkEditOverlay.longPressDelay); };