diff --git a/public/css/welcome.css b/public/css/welcome.css index dfb6cf504..06795dad5 100644 --- a/public/css/welcome.css +++ b/public/css/welcome.css @@ -6,6 +6,10 @@ width: 100%; } +.welcomePanel:has(.showMoreChats) { + padding-bottom: 5px; +} + body.bubblechat .welcomePanel { border-radius: 10px; background-color: var(--SmartThemeBotMesBlurTintColor); @@ -22,7 +26,7 @@ body.bubblechat .welcomePanel { .welcomePanel .recentChatsTitle { flex-grow: 1; - font-size: calc(var(--mainFontSize) * 1.1); + font-size: calc(var(--mainFontSize) * 1.15); font-weight: 600; } @@ -36,7 +40,7 @@ body.bubblechat .welcomePanel { } .welcomePanel .welcomeHeaderVersionDisplay { - font-size: calc(var(--mainFontSize) * 1.2); + font-size: calc(var(--mainFontSize) * 1.3); font-weight: 600; } @@ -174,6 +178,14 @@ body.big-avatars .welcomeRecent .recentChatList .recentChat .chatMessageContaine 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) { .welcomePanel .welcomeShortcuts a span { display: none; diff --git a/public/scripts/templates/welcomePanel.html b/public/scripts/templates/welcomePanel.html index e58292aa4..77d20f98a 100644 --- a/public/scripts/templates/welcomePanel.html +++ b/public/scripts/templates/welcomePanel.html @@ -37,7 +37,7 @@ {{/if}} {{#each chats}} {{#with this}} -
+
{{char_name}}
@@ -66,6 +66,13 @@
{{/with}} {{/each}} + {{#if more}} + + {{/if}}
diff --git a/public/scripts/welcome-screen.js b/public/scripts/welcome-screen.js index 5ea15aaac..3d43fa893 100644 --- a/public/scripts/welcome-screen.js +++ b/public/scripts/welcome-screen.js @@ -62,6 +62,7 @@ async function sendWelcomePanel() { chats, empty: !chats.length, version: displayVersion, + more: chats.some(chat => chat.hidden), }; const template = await renderTemplateAsync('welcomePanel', templateData); const fragment = document.createRange().createContextualFragment(template); @@ -74,8 +75,19 @@ async function sendWelcomePanel() { } }); }); - fragment.querySelector('button.openTemporaryChat').addEventListener('click', () => { - void newAssistantChat({ temporary: true }); + const hiddenChats = fragment.querySelectorAll('.recentChat.hidden'); + 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); } catch (error) { @@ -125,6 +137,7 @@ async function openRecentChat(avatarId, fileName) { * @property {string} char_name Character name * @property {string} date_short Date in short format * @property {string} date_long Date in long format + * @property {boolean} hidden Chat will be hidden by default */ async function getRecentChats() { const response = await fetch('/api/characters/recent', { @@ -141,13 +154,15 @@ async function getRecentChats() { data.sort((a, b) => b.last_mes - a.last_mes) .map(chat => ({ chat, character: characters.find(x => x.avatar === chat.avatar) })) .filter(t => t.character) - .forEach(({ chat, character }) => { + .forEach(({ chat, character }, index) => { + const DEFAULT_DISPLAYED = 5; const chatTimestamp = timestampToMoment(chat.last_mes); chat.char_name = character.name; chat.date_short = chatTimestamp.format('l'); chat.date_long = chatTimestamp.format('LL LT'); chat.chat_name = chat.file_name.replace('.jsonl', ''); chat.char_thumbnail = getThumbnailUrl('avatar', character.avatar); + chat.hidden = index >= DEFAULT_DISPLAYED; }); return data; diff --git a/src/endpoints/characters.js b/src/endpoints/characters.js index fd29fc2c3..0ea9caf12 100644 --- a/src/endpoints/characters.js +++ b/src/endpoints/characters.js @@ -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) => { return getChatInfo(file.filePath, { avatar: file.pngFile }); });