diff --git a/src/lib/components/chat/Tags.svelte b/src/lib/components/chat/Tags.svelte index 47e63198f..cb4e54641 100644 --- a/src/lib/components/chat/Tags.svelte +++ b/src/lib/components/chat/Tags.svelte @@ -8,7 +8,7 @@ getTagsById, updateChatById } from '$lib/apis/chats'; - import { tags as _tags, chats } from '$lib/stores'; + import { tags as _tags, chats, pinnedChats } from '$lib/stores'; import { createEventDispatcher, onMount } from 'svelte'; const dispatch = createEventDispatcher(); @@ -19,9 +19,11 @@ let tags = []; const getTags = async () => { - return await getTagsById(localStorage.token, chatId).catch(async (error) => { - return []; - }); + return ( + await getTagsById(localStorage.token, chatId).catch(async (error) => { + return []; + }) + ).filter((tag) => tag.name !== 'pinned'); }; const addTag = async (tagName) => { @@ -33,6 +35,7 @@ }); _tags.set(await getAllChatTags(localStorage.token)); + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); }; const deleteTag = async (tagName) => { @@ -44,19 +47,23 @@ }); console.log($_tags); - await _tags.set(await getAllChatTags(localStorage.token)); console.log($_tags); if ($_tags.map((t) => t.name).includes(tagName)) { - await chats.set(await getChatListByTagName(localStorage.token, tagName)); + if (tagName === 'pinned') { + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); + } else { + await chats.set(await getChatListByTagName(localStorage.token, tagName)); + } if ($chats.find((chat) => chat.id === chatId)) { dispatch('close'); } } else { await chats.set(await getChatList(localStorage.token)); + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); } }; diff --git a/src/lib/components/icons/Bookmark.svelte b/src/lib/components/icons/Bookmark.svelte new file mode 100644 index 000000000..ea8028457 --- /dev/null +++ b/src/lib/components/icons/Bookmark.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/icons/BookmarkSlash.svelte b/src/lib/components/icons/BookmarkSlash.svelte new file mode 100644 index 000000000..6b80ea3ca --- /dev/null +++ b/src/lib/components/icons/BookmarkSlash.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/icons/ChatMenu.svelte b/src/lib/components/icons/ChatMenu.svelte new file mode 100644 index 000000000..673e643b1 --- /dev/null +++ b/src/lib/components/icons/ChatMenu.svelte @@ -0,0 +1,124 @@ + + + { + if (e.detail === false) { + onClose(); + } + }} +> + + + + +
+ + { + pinHandler(); + }} + > + +
{$i18n.t('Pin')}
+
+ + { + renameHandler(); + }} + > + +
{$i18n.t('Rename')}
+
+ + { + cloneChatHandler(); + }} + > + +
{$i18n.t('Clone')}
+
+ + { + archiveChatHandler(); + }} + > + +
{$i18n.t('Archive')}
+
+ + { + shareHandler(); + }} + > + +
{$i18n.t('Share')}
+
+ + { + deleteHandler(); + }} + > + +
{$i18n.t('Delete')}
+
+ +
+ +
+ { + show = false; + onClose(); + }} + /> +
+
+
+
diff --git a/src/lib/components/icons/Star.svelte b/src/lib/components/icons/Star.svelte new file mode 100644 index 000000000..45faf808b --- /dev/null +++ b/src/lib/components/icons/Star.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 0cd6afa28..193fe41ff 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -10,7 +10,8 @@ tags, showSidebar, mobile, - showArchivedChats + showArchivedChats, + pinnedChats } from '$lib/stores'; import { onMount, getContext, tick } from 'svelte'; @@ -46,6 +47,7 @@ let showDeleteConfirm = false; let showDropdown = false; + let filteredChatList = []; $: filteredChatList = $chats.filter((chat) => { @@ -80,6 +82,8 @@ }); showSidebar.set(window.innerWidth > BREAKPOINT); + + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); await chats.set(await getChatList(localStorage.token)); let touchstart; @@ -412,7 +416,7 @@ - {#if $tags.length > 0} + {#if $tags.filter((t) => t.name !== 'pinned').length > 0}
- {#each $tags as tag} + {#each $tags.filter((t) => t.name !== 'pinned') as tag}
{/if} + {#if $pinnedChats.length > 0} +
+
+
+ {$i18n.t('Pinned')} +
+ + {#each $pinnedChats as chat, idx} + { + selectedChatId = chat.id; + }} + on:unselect={() => { + selectedChatId = null; + }} + on:delete={(e) => { + if ((e?.detail ?? '') === 'shift') { + deleteChatHandler(chat.id); + } else { + deleteChat = chat; + showDeleteConfirm = true; + } + }} + /> + {/each} +
+
+ {/if} +
{#each filteredChatList as chat, idx} {#if idx === 0 || (idx > 0 && chat.time_range !== filteredChatList[idx - 1].time_range)} diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 742c69a61..129c653fa 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -11,9 +11,10 @@ cloneChatById, deleteChatById, getChatList, + getChatListByTagName, updateChatById } from '$lib/apis/chats'; - import { chatId, chats, mobile, showSidebar } from '$lib/stores'; + import { chatId, chats, mobile, pinnedChats, showSidebar } from '$lib/stores'; import ChatMenu from './ChatMenu.svelte'; import ShareChatModal from '$lib/components/chat/ShareChatModal.svelte'; @@ -40,6 +41,7 @@ title: _title }); await chats.set(await getChatList(localStorage.token)); + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); } }; @@ -52,12 +54,14 @@ if (res) { goto(`/c/${res.id}`); await chats.set(await getChatList(localStorage.token)); + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); } }; const archiveChatHandler = async (id) => { await archiveChatById(localStorage.token, id); await chats.set(await getChatList(localStorage.token)); + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); }; const focusEdit = async (node: HTMLInputElement) => { @@ -233,6 +237,9 @@ onClose={() => { dispatch('unselect'); }} + on:change={async () => { + await pinnedChats.set(await getChatListByTagName(localStorage.token, 'pinned')); + }} >