mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add search filtering for past chats
This commit is contained in:
@ -3403,6 +3403,7 @@
|
|||||||
|
|
||||||
<div id="shadow_select_chat_popup">
|
<div id="shadow_select_chat_popup">
|
||||||
<div id="select_chat_popup">
|
<div id="select_chat_popup">
|
||||||
|
<input type="text" id="select_chat_search" placeholder="Search..." autocomplete="off">
|
||||||
<div id="select_chat_import"> <!-- import chat popup header -->
|
<div id="select_chat_import"> <!-- import chat popup header -->
|
||||||
<div id="chat_import_button" class="fa-solid fa-file-arrow-up menu_button"></div>
|
<div id="chat_import_button" class="fa-solid fa-file-arrow-up menu_button"></div>
|
||||||
<div id="selectChatPopupHeaderText" class="TxtLrgBoldCenter">
|
<div id="selectChatPopupHeaderText" class="TxtLrgBoldCenter">
|
||||||
|
@ -5577,6 +5577,66 @@ async function messageEditDone(div) {
|
|||||||
await saveChatConditional();
|
await saveChatConditional();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* 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 {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
|
||||||
|
* corresponding chat content fetched from the server.
|
||||||
|
*/
|
||||||
|
export async function getChatsFromFiles(data, isGroupChat) {
|
||||||
|
const context = getContext();
|
||||||
|
let chat_dict = {};
|
||||||
|
let chat_list = Object.values(data).sort((a, b) => a["file_name"].localeCompare(b["file_name"])).reverse();
|
||||||
|
|
||||||
|
for (const { file_name } of chat_list) {
|
||||||
|
try {
|
||||||
|
const endpoint = isGroupChat ? '/getgroupchat' : '/getchat';
|
||||||
|
const requestBody = isGroupChat
|
||||||
|
? JSON.stringify({ id: file_name })
|
||||||
|
: JSON.stringify({
|
||||||
|
ch_name: characters[context.characterId].name,
|
||||||
|
file_name: file_name.replace('.jsonl', ''),
|
||||||
|
avatar_url: characters[context.characterId].avatar
|
||||||
|
});
|
||||||
|
|
||||||
|
const chatResponse = await fetch(endpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: getRequestHeaders(),
|
||||||
|
body: requestBody,
|
||||||
|
cache: 'no-cache',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!chatResponse.ok) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentChat = await chatResponse.json();
|
||||||
|
if (!isGroupChat) {
|
||||||
|
// remove the first message, which is metadata, only for individual chats
|
||||||
|
currentChat.shift();
|
||||||
|
}
|
||||||
|
chat_dict[file_name] = currentChat;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chat_dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* 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
|
||||||
|
* in descending order by file name. Returns `undefined` if the fetch request is unsuccessful.
|
||||||
|
*/
|
||||||
async function getPastCharacterChats() {
|
async function getPastCharacterChats() {
|
||||||
const response = await fetch("/getallchatsofcharacter", {
|
const response = await fetch("/getallchatsofcharacter", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -5594,6 +5654,12 @@ async function getPastCharacterChats() {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 HTML. It also has a built-in search functionality that allows filtering the
|
||||||
|
* displayed chats based on a search query.
|
||||||
|
*/
|
||||||
export async function displayPastChats() {
|
export async function displayPastChats() {
|
||||||
$("#select_chat_div").empty();
|
$("#select_chat_div").empty();
|
||||||
|
|
||||||
@ -5602,15 +5668,27 @@ export async function displayPastChats() {
|
|||||||
const currentChat = selected_group ? group?.chat_id : characters[this_chid]["chat"];
|
const currentChat = selected_group ? group?.chat_id : characters[this_chid]["chat"];
|
||||||
const displayName = selected_group ? group?.name : characters[this_chid].name;
|
const displayName = selected_group ? group?.name : characters[this_chid].name;
|
||||||
const avatarImg = selected_group ? group?.avatar_url : getThumbnailUrl('avatar', characters[this_chid]['avatar']);
|
const avatarImg = selected_group ? group?.avatar_url : getThumbnailUrl('avatar', characters[this_chid]['avatar']);
|
||||||
|
const rawChats = await getChatsFromFiles(data, selected_group);
|
||||||
// Sort by last message date descending
|
// Sort by last message date descending
|
||||||
data.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes)));
|
data.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes)));
|
||||||
|
console.log(data);
|
||||||
$("#load_select_chat_div").css("display", "none");
|
$("#load_select_chat_div").css("display", "none");
|
||||||
$("#ChatHistoryCharName").text(displayName);
|
$("#ChatHistoryCharName").text(displayName);
|
||||||
for (const key in data) {
|
|
||||||
|
const displayChats = (searchQuery) => {
|
||||||
|
$("#select_chat_div").empty(); // Clear the current chats before appending filtered chats
|
||||||
|
|
||||||
|
const filteredData = data.filter(chat => {
|
||||||
|
const fileName = chat['file_name'];
|
||||||
|
const chatContent = rawChats[fileName];
|
||||||
|
|
||||||
|
return chatContent && Object.values(chatContent).some(message => message.mes.toLowerCase().includes(searchQuery.toLowerCase()));
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(filteredData);
|
||||||
|
for (const key in filteredData) {
|
||||||
let strlen = 300;
|
let strlen = 300;
|
||||||
let mes = data[key]["mes"];
|
let mes = filteredData[key]["mes"];
|
||||||
|
|
||||||
if (mes !== undefined) {
|
if (mes !== undefined) {
|
||||||
if (mes.length > strlen) {
|
if (mes.length > strlen) {
|
||||||
@ -5641,6 +5719,19 @@ export async function displayPastChats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
displayChats(''); // Display all by default
|
||||||
|
|
||||||
|
const debouncedDisplay = debounce((searchQuery) => {
|
||||||
|
displayChats(searchQuery);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
// Define the search input listener
|
||||||
|
$("#select_chat_search").on("input", function () {
|
||||||
|
const searchQuery = $(this).val();
|
||||||
|
debouncedDisplay(searchQuery);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//************************************************************
|
//************************************************************
|
||||||
|
@ -5684,3 +5684,16 @@ body.waifuMode .zoomed_avatar {
|
|||||||
font-size: calc(var(--mainFontSize) * .8);
|
font-size: calc(var(--mainFontSize) * .8);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#select_chat_search {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
color: white;
|
||||||
|
display: inline-block; /* Change display to inline-block */
|
||||||
|
vertical-align: middle; /* Align to middle if there's a height discrepancy */
|
||||||
|
width: 200px;
|
||||||
|
font-size: 16px;
|
||||||
|
z-index: 10;
|
||||||
|
margin-left: 10px; /* Give some space between the button and search box */
|
||||||
|
}
|
Reference in New Issue
Block a user