Performance optimizations for character edit / chat opening

This commit is contained in:
Cohee1207 2023-08-19 15:58:17 +03:00
parent 3acd0a590e
commit 991ff98eaa
8 changed files with 62 additions and 86 deletions

View File

@ -3267,16 +3267,6 @@
</div> </div>
<div id="rm_print_characters_block" class="flexFlowColumn"></div> <div id="rm_print_characters_block" class="flexFlowColumn"></div>
</div> </div>
<!-- only displays after creating/deleting a character/group -->
<div id="rm_info_block" class="right_menu">
<div id="rm_info_panel">
<div id="rm_info_avatar"></div>
<div id="rm_info_text"></div>
<div id="rm_info_button" class="menu_button" data-i18n="Back">Back</div>
</div>
</div>
</nav> </nav>
</div> </div>

View File

@ -1089,6 +1089,30 @@ export function getEntitiesList({ doFilter } = {}) {
return entities; return entities;
} }
async function getOneCharacter(avatarUrl) {
const response = await fetch("/getonecharacter", {
method: "POST",
headers: getRequestHeaders(),
body: JSON.stringify({
avatar_url: avatarUrl,
}),
});
if (response.ok) {
const getData = await response.json();
getData['name'] = DOMPurify.sanitize(getData['name']);
getData['chat'] = String(getData['chat']);
const indexOf = characters.findIndex(x => x.avatar === avatarUrl);
if (indexOf !== -1) {
characters[indexOf] = getData;
} else {
toastr.error(`Character ${avatarUrl} not found in the list`, "Error", { timeOut: 5000, preventDuplicates: true });
}
}
}
async function getCharacters() { async function getCharacters() {
var response = await fetch("/getcharacters", { var response = await fetch("/getcharacters", {
method: "POST", method: "POST",
@ -4541,10 +4565,9 @@ async function getChat() {
chat_create_date = humanizedDateTime(); chat_create_date = humanizedDateTime();
} }
await getChatResult(); await getChatResult();
await saveChat(); saveChatDebounced();
eventSource.emit('chatLoaded', { detail: { id: this_chid, character: characters[this_chid] } }); eventSource.emit('chatLoaded', { detail: { id: this_chid, character: characters[this_chid] } });
setTimeout(function () { setTimeout(function () {
$('#send_textarea').click(); $('#send_textarea').click();
$('#send_textarea').focus(); $('#send_textarea').focus();
@ -4596,7 +4619,7 @@ async function openCharacterChat(file_name) {
chat_metadata = {}; chat_metadata = {};
await getChat(); await getChat();
$("#selected_chat_pole").val(file_name); $("#selected_chat_pole").val(file_name);
$("#create_button").click(); await createOrEditCharacter();
} }
////////// OPTIMZED MAIN API CHANGE FUNCTION //////////// ////////// OPTIMZED MAIN API CHANGE FUNCTION ////////////
@ -5602,12 +5625,12 @@ async function messageEditDone(div) {
/** /**
* Fetches the chat content for each chat file from the server and compiles them into a dictionary. * Fetches the chat content for each chat file from the server and compiles them into a dictionary.
* The function iterates over a provided list of chat metadata and requests the actual chat content * The function iterates over a provided list of chat metadata and requests the actual chat content
* for each chat, either as an individual chat or a group chat based on the context. * for each chat, either as an individual chat or a group chat based on the context.
* *
* @param {Array} data - An array containing metadata about each chat such as file_name. * @param {Array} data - An array containing metadata about each chat such as file_name.
* @param {boolean} isGroupChat - A flag indicating if the chat is a group chat. * @param {boolean} isGroupChat - A flag indicating if the chat is a group chat.
* @returns {Object} chat_dict - A dictionary where each key is a file_name and the value is the * @returns {Object} chat_dict - A dictionary where each key is a file_name and the value is the
* corresponding chat content fetched from the server. * corresponding chat content fetched from the server.
*/ */
export async function getChatsFromFiles(data, isGroupChat) { export async function getChatsFromFiles(data, isGroupChat) {
@ -5654,10 +5677,10 @@ export async function getChatsFromFiles(data, isGroupChat) {
/** /**
* Fetches the metadata of all past chats related to a specific character based on its avatar URL. * Fetches the metadata of all past chats related to a specific character based on its avatar URL.
* The function sends a POST request to the server to retrieve all chats for the character. It then * 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. * processes the received data, sorts it by the file name, and returns the sorted data.
* *
* @returns {Array} - An array containing metadata of all past chats of the character, sorted * @returns {Array} - 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. * in descending order by file name. Returns `undefined` if the fetch request is unsuccessful.
*/ */
async function getPastCharacterChats() { async function getPastCharacterChats() {
@ -5679,8 +5702,8 @@ async function getPastCharacterChats() {
/** /**
* Displays the past chats for a character or a group based on the selected context. * Displays the past chats for a character or a group based on the selected context.
* The function first fetches the chats, processes them, and then displays them in * The function first fetches the chats, processes them, and then displays them in
* the HTML. It also has a built-in search functionality that allows filtering the * the HTML. It also has a built-in search functionality that allows filtering the
* displayed chats based on a search query. * displayed chats based on a search query.
*/ */
export async function displayPastChats() { export async function displayPastChats() {
@ -5742,7 +5765,7 @@ export async function displayPastChats() {
} }
} }
} }
} }
displayChats(''); // Display all by default displayChats(''); // Display all by default
@ -5797,11 +5820,11 @@ async function getStatusNovel() {
function selectRightMenuWithAnimation(selectedMenuId) { function selectRightMenuWithAnimation(selectedMenuId) {
const displayModes = { const displayModes = {
'rm_info_block': 'flex',
'rm_group_chats_block': 'flex', 'rm_group_chats_block': 'flex',
'rm_api_block': 'grid', 'rm_api_block': 'grid',
'rm_characters_block': 'flex', 'rm_characters_block': 'flex',
}; };
$('#hideCharPanelAvatarButton').toggle(selectedMenuId === 'rm_ch_create_block');
document.querySelectorAll('#right-nav-panel .right_menu').forEach((menu) => { document.querySelectorAll('#right-nav-panel .right_menu').forEach((menu) => {
$(menu).css('display', 'none'); $(menu).css('display', 'none');
@ -5855,7 +5878,6 @@ function select_rm_info(type, charId, previousCharId = null) {
toastr.success(`Character Imported: ${displayName}`); toastr.success(`Character Imported: ${displayName}`);
} }
getCharacters();
selectRightMenuWithAnimation('rm_characters_block'); selectRightMenuWithAnimation('rm_characters_block');
setTimeout(function () { setTimeout(function () {
@ -6263,10 +6285,10 @@ function hideSwipeButtons() {
async function saveMetadata() { async function saveMetadata() {
if (selected_group) { if (selected_group) {
await editGroup(selected_group, true, false); await editGroup(selected_group, false, false);
} }
else { else {
await saveChat(); saveChatDebounced();
} }
} }
@ -6670,12 +6692,8 @@ async function createOrEditCharacter(e) {
createTagMapFromList("#tagList", html); createTagMapFromList("#tagList", html);
await getCharacters(); await getCharacters();
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
var $prev_img = $("#avatar_div_div").clone();
$("#rm_info_avatar").append($prev_img);
select_rm_info(`char_create`, html, oldSelectedChar); select_rm_info(`char_create`, html, oldSelectedChar);
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
crop_data = undefined; crop_data = undefined;
}, },
error: function (jqXHR, exception) { error: function (jqXHR, exception) {
@ -6764,7 +6782,8 @@ async function createOrEditCharacter(e) {
} }
} }
$("#create_button").removeAttr("disabled"); $("#create_button").removeAttr("disabled");
await getCharacters();
await getOneCharacter(formData.get('avatar_url'));
$("#add_avatar_button").replaceWith( $("#add_avatar_button").replaceWith(
$("#add_avatar_button").val("").clone(true) $("#add_avatar_button").val("").clone(true)
@ -7221,12 +7240,6 @@ function importCharacter(file) {
if (data.file_name !== undefined) { if (data.file_name !== undefined) {
$('#character_search_bar').val('').trigger('input'); $('#character_search_bar').val('').trigger('input');
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
var $prev_img = $("#avatar_div_div").clone();
$prev_img
.children("img")
.attr("src", "characters/" + data.file_name + ".png");
$("#rm_info_avatar").append($prev_img);
let oldSelectedChar = null; let oldSelectedChar = null;
if (this_chid != undefined && this_chid != "invalid-safety-id") { if (this_chid != undefined && this_chid != "invalid-safety-id") {
@ -7241,7 +7254,6 @@ function importCharacter(file) {
let importedCharacter = currentContext.characters.find(character => character.avatar === avatarFileName); let importedCharacter = currentContext.characters.find(character => character.avatar === avatarFileName);
await importTags(importedCharacter); await importTags(importedCharacter);
} }
$("#rm_info_block").transition({ opacity: 1, duration: 1000 });
} }
}, },
error: function (jqXHR, exception) { error: function (jqXHR, exception) {
@ -7709,7 +7721,7 @@ $(document).ready(function () {
setTimeout(function () { setTimeout(function () {
$("#option_select_chat").click(); $("#option_select_chat").click();
$("#options").hide(); $("#options").hide();
}, 200); }, 2000);
} }
if (popup_type == "del_ch") { if (popup_type == "del_ch") {
const deleteChats = !!$("#del_char_checkbox").prop("checked"); const deleteChats = !!$("#del_char_checkbox").prop("checked");
@ -7808,11 +7820,6 @@ $(document).ready(function () {
); );
}); });
$("#rm_info_button").on('click', function () {
$("#rm_info_avatar").html("");
select_rm_characters();
});
//////// OPTIMIZED ALL CHAR CREATION/EDITING TEXTAREA LISTENERS /////////////// //////// OPTIMIZED ALL CHAR CREATION/EDITING TEXTAREA LISTENERS ///////////////
$("#character_name_pole").on("input", function () { $("#character_name_pole").on("input", function () {
@ -9216,8 +9223,7 @@ $(document).ready(function () {
doCharListDisplaySwitch(); doCharListDisplaySwitch();
}); });
$("#hideCharPanelAvatarButton").on('click', () => { $("#hideCharPanelAvatarButton").hide().on('click', () => {
$('#avatar-and-name-block').slideToggle() $('#avatar-and-name-block').slideToggle()
}) });
}); });

View File

@ -175,6 +175,7 @@ export async function getGroupChat(groupId) {
addOneMessage(mes); addOneMessage(mes);
} }
} }
await saveGroupChat(groupId, false);
} }
if (group) { if (group) {
@ -182,7 +183,6 @@ export async function getGroupChat(groupId) {
updateChatMetadata(metadata, true); updateChatMetadata(metadata, true);
} }
await saveGroupChat(groupId, true);
eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId()); eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
} }
@ -802,10 +802,7 @@ async function deleteGroup(id) {
printMessages(); printMessages();
await getCharacters(); await getCharacters();
$("#rm_info_avatar").html("");
$("#rm_info_block").transition({ opacity: 0, duration: 0 });
select_rm_info("group_delete", id); select_rm_info("group_delete", id);
$("#rm_info_block").transition({ opacity: 1.0, duration: 2000 });
$("#rm_button_selected_ch").children("h2").text(''); $("#rm_button_selected_ch").children("h2").text('');
setRightTabSelectedClass(); setRightTabSelectedClass();

View File

@ -351,7 +351,8 @@ function setupChatCompletionPromptManager(openAiSettings) {
}; };
promptManager.saveServiceSettings = () => { promptManager.saveServiceSettings = () => {
return saveSettings(); saveSettingsDebounced();
return new Promise((resolve) => eventSource.once(event_types.SETTINGS_UPDATED, resolve));
} }
promptManager.tryGenerate = () => { promptManager.tryGenerate = () => {

View File

@ -812,7 +812,7 @@ function loadPowerUserSettings(settings, data) {
} }
async function loadCharListState() { async function loadCharListState() {
if (document.getElementById('CharID0') !== null) { if (document.querySelector('.character_select') !== null) {
console.debug('setting charlist state to...') console.debug('setting charlist state to...')
if (power_user.charListGrid === true) { if (power_user.charListGrid === true) {
console.debug('..to grid') console.debug('..to grid')

View File

@ -149,9 +149,6 @@ function setWorldInfoSettings(settings, data) {
}); });
$("#world_editor_select").trigger("change"); $("#world_editor_select").trigger("change");
// Update settings
saveSettingsDebounced();
} }
// World Info Editor // World Info Editor

View File

@ -1275,6 +1275,7 @@ input[type="file"] {
flex-direction: row; flex-direction: row;
gap: 5px; gap: 5px;
justify-content: center; justify-content: center;
align-items: center;
} }
#rm_print_characters_block { #rm_print_characters_block {
@ -1985,35 +1986,6 @@ grammarly-extension {
align-items: center; align-items: center;
} }
#rm_info_block {
display: none;
width: 100%;
height: 80%;
justify-content: center;
flex-direction: column;
}
#rm_info_panel {
font-size: calc(var(--mainFontSize) + .5rem);
display: block;
text-align: center;
}
#rm_info_button {
width: min-content;
margin: 0 auto;
}
#rm_info_avatar {
display: flex;
column-gap: 10px;
width: fit-content;
text-align: center;
margin-left: auto;
margin-right: auto;
}
#delete_button, #delete_button,
.redWarningBG { .redWarningBG {
background-color: var(--crimson70a) !important; background-color: var(--crimson70a) !important;
@ -5696,4 +5668,4 @@ body.waifuMode .zoomed_avatar {
font-size: 16px; font-size: 16px;
z-index: 10; z-index: 10;
margin-left: 10px; /* Give some space between the button and search box */ margin-left: 10px; /* Give some space between the button and search box */
} }

View File

@ -618,7 +618,7 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r
websocket.close(); websocket.close();
return; return;
} }
let rawMessage = null; let rawMessage = null;
try { try {
// This lunacy is because the websocket can fail to connect AFTER we're awaiting 'message'... so 'message' never triggers. // This lunacy is because the websocket can fail to connect AFTER we're awaiting 'message'... so 'message' never triggers.
@ -1373,7 +1373,20 @@ app.post("/getcharacters", jsonParser, function (request, response) {
}); });
}); });
app.post("/getonecharacter", jsonParser, async function (request, response) {
if (!request.body) return response.sendStatus(400);
const item = request.body.avatar_url;
const filePath = path.join(charactersPath, item);
if (!fs.existsSync(filePath)) {
return response.sendStatus(404);
}
characters = {};
await processCharacter(item, 0);
return response.send(characters[0]);
});
/** /**
* Handle a POST request to get the stats object * Handle a POST request to get the stats object
@ -3649,7 +3662,7 @@ const setupTasks = async function () {
console.log('Launching...'); console.log('Launching...');
if (autorun) open(autorunUrl.toString()); if (autorun) open(autorunUrl.toString());
console.log('\x1b[32mSillyTavern is listening on: ' + tavernUrl + '\x1b[0m'); console.log('\x1b[32mSillyTavern is listening on: ' + tavernUrl + '\x1b[0m');
if (listen) { if (listen) {