refac: collapsible pinned chat list

This commit is contained in:
Timothy J. Baek 2024-10-14 19:33:32 -07:00
parent bc75870289
commit 90b7754cd6
2 changed files with 68 additions and 73 deletions

View File

@ -49,6 +49,9 @@
import AddFilesPlaceholder from '../AddFilesPlaceholder.svelte';
import { select } from 'd3-selection';
import SearchInput from './Sidebar/SearchInput.svelte';
import ChevronDown from '../icons/ChevronDown.svelte';
import ChevronUp from '../icons/ChevronUp.svelte';
import ChevronRight from '../icons/ChevronRight.svelte';
const BREAKPOINT = 768;
@ -65,6 +68,8 @@
let selectedTagName = null;
let showPinnedChat = true;
// Pagination variables
let chatListLoading = false;
let allChatsLoaded = false;
@ -257,6 +262,8 @@
};
onMount(async () => {
showPinnedChat = localStorage?.showPinnedChat ? localStorage.showPinnedChat === 'true' : true;
mobile.subscribe((e) => {
if ($showSidebar && e) {
showSidebar.set(false);
@ -476,11 +483,7 @@
</div>
{/if}
<div
class="relative flex flex-col flex-1 overflow-y-auto {$temporaryChatEnabled
? 'opacity-20'
: ''}"
>
<div class="relative {$temporaryChatEnabled ? 'opacity-20' : ''}">
{#if $temporaryChatEnabled}
<div class="absolute z-40 w-full h-full flex justify-center"></div>
{/if}
@ -490,78 +493,71 @@
on:input={searchDebounceHandler}
placeholder={$i18n.t('Search')}
/>
</div>
<!-- {#if $tags.length > 0}
<div class="px-3.5 mb-2.5 flex gap-0.5 flex-wrap">
<button
class="px-2.5 py-[1px] text-xs transition {selectedTagName === null
? 'bg-gray-100 dark:bg-gray-900'
: ' '} rounded-md font-medium"
on:click={async () => {
selectedTagName = null;
await initChatList();
}}
>
{$i18n.t('all')}
</button>
{#each $tags as tag}
<button
class="px-2.5 py-[1px] text-xs transition {selectedTagName === tag.name
? 'bg-gray-100 dark:bg-gray-900'
: ''} rounded-md font-medium"
on:click={async () => {
selectedTagName = tag.name;
scrollPaginationEnabled.set(false);
let taggedChatList = await getChatListByTagName(localStorage.token, tag.name);
if (taggedChatList.length === 0) {
await tags.set(await getAllChatTags(localStorage.token));
// if the tag we deleted is no longer a valid tag, return to main chat list view
await initChatList();
} else {
await chats.set(taggedChatList);
}
chatListLoading = false;
}}
>
{tag.name}
</button>
{/each}
</div>
{/if} -->
<div
class="relative flex flex-col flex-1 overflow-y-auto {$temporaryChatEnabled
? 'opacity-20'
: ''}"
>
{#if $temporaryChatEnabled}
<div class="absolute z-40 w-full h-full flex justify-center"></div>
{/if}
{#if !search && $pinnedChats.length > 0}
<div class="pl-2 pb-2 flex flex-col space-y-1">
<div class=" pb-2 flex flex-col space-y-1">
<div class="">
<div class="w-full pl-2.5 text-xs text-gray-500 dark:text-gray-500 font-medium pb-1.5">
{$i18n.t('Pinned')}
<div class="px-2">
<button
class="w-full py-0.5 px-1.5 rounded flex items-center gap-1 text-xs text-gray-500 dark:text-gray-500 font-medium hover:bg-gray-100 dark:hover:bg-gray-900 transition"
on:click={() => {
showPinnedChat = !showPinnedChat;
localStorage.setItem('showPinnedChat', showPinnedChat);
}}
>
<div class="text-gray-300">
{#if showPinnedChat}
<ChevronDown className=" size-3" strokeWidth="2.5" />
{:else}
<ChevronRight className=" text-gra size-3" strokeWidth="2.5" />
{/if}
</div>
<div class=" translate-y-[0.5px]">
{$i18n.t('Pinned')}
</div>
</button>
</div>
{#each $pinnedChats as chat, idx}
<ChatItem
{chat}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:delete={(e) => {
if ((e?.detail ?? '') === 'shift') {
deleteChatHandler(chat.id);
} else {
deleteChat = chat;
showDeleteConfirm = true;
}
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
{#if showPinnedChat}
<div class="pl-2 mt-1 flex flex-col overflow-y-auto scrollbar-hidden">
{#each $pinnedChats as chat, idx}
<ChatItem
{chat}
{shiftKey}
selected={selectedChatId === chat.id}
on:select={() => {
selectedChatId = chat.id;
}}
on:unselect={() => {
selectedChatId = null;
}}
on:delete={(e) => {
if ((e?.detail ?? '') === 'shift') {
deleteChatHandler(chat.id);
} else {
deleteChat = chat;
showDeleteConfirm = true;
}
}}
on:tag={(e) => {
const { type, name } = e.detail;
tagEventHandler(type, name, chat.id);
}}
/>
{/each}
</div>
{/if}
</div>
</div>
{/if}

View File

@ -71,7 +71,7 @@
});
</script>
<div class="px-2 mt-0.5 mb-2 flex justify-center space-x-2 relative" id="search-container">
<div class="px-2 mb-1 flex justify-center space-x-2 relative z-10" id="search-container">
<div class="flex w-full rounded-xl" id="chat-search">
<div class="self-center pl-3 py-2 rounded-l-xl bg-transparent">
<svg
@ -89,7 +89,6 @@
</div>
<input
id="search-input"
class="w-full rounded-r-xl py-1.5 pl-2.5 pr-4 text-sm bg-transparent dark:text-gray-300 outline-none"
placeholder={placeholder ? placeholder : $i18n.t('Search')}
bind:value