Show more recent chats

This commit is contained in:
Cohee
2025-05-12 20:16:56 +03:00
parent d5c56fa405
commit c45f1ceaff
4 changed files with 41 additions and 7 deletions

View File

@ -6,6 +6,10 @@
width: 100%; width: 100%;
} }
.welcomePanel:has(.showMoreChats) {
padding-bottom: 5px;
}
body.bubblechat .welcomePanel { body.bubblechat .welcomePanel {
border-radius: 10px; border-radius: 10px;
background-color: var(--SmartThemeBotMesBlurTintColor); background-color: var(--SmartThemeBotMesBlurTintColor);
@ -22,7 +26,7 @@ body.bubblechat .welcomePanel {
.welcomePanel .recentChatsTitle { .welcomePanel .recentChatsTitle {
flex-grow: 1; flex-grow: 1;
font-size: calc(var(--mainFontSize) * 1.1); font-size: calc(var(--mainFontSize) * 1.15);
font-weight: 600; font-weight: 600;
} }
@ -36,7 +40,7 @@ body.bubblechat .welcomePanel {
} }
.welcomePanel .welcomeHeaderVersionDisplay { .welcomePanel .welcomeHeaderVersionDisplay {
font-size: calc(var(--mainFontSize) * 1.2); font-size: calc(var(--mainFontSize) * 1.3);
font-weight: 600; font-weight: 600;
} }
@ -174,6 +178,14 @@ body.big-avatars .welcomeRecent .recentChatList .recentChat .chatMessageContaine
font-size: calc(var(--mainFontSize) * 0.95); font-size: calc(var(--mainFontSize) * 0.95);
} }
.welcomeRecent .recentChatList .recentChat.hidden {
display: none;
}
.welcomeRecent .recentChatList .showMoreChats {
align-self: center;
}
@media screen and (max-width: 1000px) { @media screen and (max-width: 1000px) {
.welcomePanel .welcomeShortcuts a span { .welcomePanel .welcomeShortcuts a span {
display: none; display: none;

View File

@ -37,7 +37,7 @@
{{/if}} {{/if}}
{{#each chats}} {{#each chats}}
{{#with this}} {{#with this}}
<div class="recentChat" data-file="{{chat_name}}" data-avatar="{{avatar}}"> <div class="recentChat {{#if hidden}}hidden{{/if}}" data-file="{{chat_name}}" data-avatar="{{avatar}}">
<div class="avatar" title="{{char_name}}"> <div class="avatar" title="{{char_name}}">
<img src="{{char_thumbnail}}" alt="{{char_name}}"> <img src="{{char_thumbnail}}" alt="{{char_name}}">
</div> </div>
@ -66,6 +66,13 @@
</div> </div>
{{/with}} {{/with}}
{{/each}} {{/each}}
{{#if more}}
<button class="menu_button menu_button_icon showMoreChats">
<small data-i18n="Show more">
Show more
</small>
</button>
{{/if}}
</div> </div>
</div> </div>
</div> </div>

View File

@ -62,6 +62,7 @@ async function sendWelcomePanel() {
chats, chats,
empty: !chats.length, empty: !chats.length,
version: displayVersion, version: displayVersion,
more: chats.some(chat => chat.hidden),
}; };
const template = await renderTemplateAsync('welcomePanel', templateData); const template = await renderTemplateAsync('welcomePanel', templateData);
const fragment = document.createRange().createContextualFragment(template); const fragment = document.createRange().createContextualFragment(template);
@ -74,8 +75,19 @@ async function sendWelcomePanel() {
} }
}); });
}); });
fragment.querySelector('button.openTemporaryChat').addEventListener('click', () => { const hiddenChats = fragment.querySelectorAll('.recentChat.hidden');
void newAssistantChat({ temporary: true }); fragment.querySelectorAll('button.showMoreChats').forEach((button) => {
button.addEventListener('click', () => {
hiddenChats.forEach((chatItem) => {
chatItem.classList.remove('hidden');
});
button.remove();
});
});
fragment.querySelectorAll('button.openTemporaryChat').forEach((button) => {
button.addEventListener('click', () => {
void newAssistantChat({ temporary: true });
});
}); });
chatElement.append(fragment.firstChild); chatElement.append(fragment.firstChild);
} catch (error) { } catch (error) {
@ -125,6 +137,7 @@ async function openRecentChat(avatarId, fileName) {
* @property {string} char_name Character name * @property {string} char_name Character name
* @property {string} date_short Date in short format * @property {string} date_short Date in short format
* @property {string} date_long Date in long format * @property {string} date_long Date in long format
* @property {boolean} hidden Chat will be hidden by default
*/ */
async function getRecentChats() { async function getRecentChats() {
const response = await fetch('/api/characters/recent', { const response = await fetch('/api/characters/recent', {
@ -141,13 +154,15 @@ async function getRecentChats() {
data.sort((a, b) => b.last_mes - a.last_mes) data.sort((a, b) => b.last_mes - a.last_mes)
.map(chat => ({ chat, character: characters.find(x => x.avatar === chat.avatar) })) .map(chat => ({ chat, character: characters.find(x => x.avatar === chat.avatar) }))
.filter(t => t.character) .filter(t => t.character)
.forEach(({ chat, character }) => { .forEach(({ chat, character }, index) => {
const DEFAULT_DISPLAYED = 5;
const chatTimestamp = timestampToMoment(chat.last_mes); const chatTimestamp = timestampToMoment(chat.last_mes);
chat.char_name = character.name; chat.char_name = character.name;
chat.date_short = chatTimestamp.format('l'); chat.date_short = chatTimestamp.format('l');
chat.date_long = chatTimestamp.format('LL LT'); chat.date_long = chatTimestamp.format('LL LT');
chat.chat_name = chat.file_name.replace('.jsonl', ''); chat.chat_name = chat.file_name.replace('.jsonl', '');
chat.char_thumbnail = getThumbnailUrl('avatar', character.avatar); chat.char_thumbnail = getThumbnailUrl('avatar', character.avatar);
chat.hidden = index >= DEFAULT_DISPLAYED;
}); });
return data; return data;

View File

@ -1312,7 +1312,7 @@ router.post('/recent', async function (request, response) {
} }
} }
const recentChats = allChatFiles.sort((a, b) => b.mtime - a.mtime).slice(0, 5); const recentChats = allChatFiles.sort((a, b) => b.mtime - a.mtime).slice(0, 15);
const jsonFilesPromise = recentChats.map((file) => { const jsonFilesPromise = recentChats.map((file) => {
return getChatInfo(file.filePath, { avatar: file.pngFile }); return getChatInfo(file.filePath, { avatar: file.pngFile });
}); });