diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index c9ee74aa2..73b480796 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -111,7 +111,8 @@ $: if (chatIdProp) { (async () => { - if (await loadChat()) { + console.log(chatIdProp); + if (chatIdProp && (await loadChat())) { await tick(); loaded = true; @@ -126,7 +127,11 @@ onMount(async () => { if (!$chatId) { - await initNewChat(); + chatId.subscribe(async (value) => { + if (!value) { + await initNewChat(); + } + }); } else { if (!($settings.saveChatHistory ?? true)) { await goto('/'); diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 8d13c7efb..3b32e6016 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -38,7 +38,10 @@ let navElement; let search = ''; + let shiftKey = false; + let selectedChatId = null; + let showDropdown = false; let filteredChatList = []; @@ -102,10 +105,28 @@ checkDirection(); }; + const onKeyDown = (e) => { + if (e.key === 'Shift') { + shiftKey = true; + } + }; + + const onKeyUp = (e) => { + if (e.key === 'Shift') { + shiftKey = false; + } + }; + + document.addEventListener('keydown', onKeyDown); + document.addEventListener('keyup', onKeyUp); + window.addEventListener('touchstart', onTouchStart); window.addEventListener('touchend', onTouchEnd); return () => { + window.removeEventListener('keydown', onKeyDown); + window.removeEventListener('keyup', onKeyUp); + window.removeEventListener('touchstart', onTouchStart); window.removeEventListener('touchend', onTouchEnd); }; @@ -407,6 +428,7 @@ <ChatItem {chat} + {shiftKey} selected={selectedChatId === chat.id} on:select={() => { selectedChatId = chat.id; diff --git a/src/lib/components/layout/Sidebar/ChatItem.svelte b/src/lib/components/layout/Sidebar/ChatItem.svelte index 6a5c5b3ba..1273def18 100644 --- a/src/lib/components/layout/Sidebar/ChatItem.svelte +++ b/src/lib/components/layout/Sidebar/ChatItem.svelte @@ -1,7 +1,7 @@ <script lang="ts"> import { toast } from 'svelte-sonner'; - import { goto } from '$app/navigation'; - import { onMount, getContext, createEventDispatcher } from 'svelte'; + import { goto, invalidate, invalidateAll } from '$app/navigation'; + import { onMount, getContext, createEventDispatcher, tick } from 'svelte'; const i18n = getContext('i18n'); const dispatch = createEventDispatcher(); @@ -18,9 +18,15 @@ import ChatMenu from './ChatMenu.svelte'; import ShareChatModal from '$lib/components/chat/ShareChatModal.svelte'; import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte'; + import GarbageBin from '$lib/components/icons/GarbageBin.svelte'; + import Tooltip from '$lib/components/common/Tooltip.svelte'; + import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte'; export let chat; export let selected = false; + export let shiftKey = false; + + let mouseOver = false; let showDeleteConfirmDialog = false; let showShareChatModal = false; @@ -43,12 +49,13 @@ const deleteChat = async (id) => { const res = await deleteChatById(localStorage.token, id).catch((error) => { toast.error(error); - return null; }); if (res) { if ($chatId === id) { + await chatId.set(''); + await tick(); goto('/'); } await chats.set(await getChatList(localStorage.token)); @@ -125,11 +132,11 @@ chatTitle = chat.title; confirmEdit = true; }} - on:mouseover={(e) => { - if (e.shiftKey) { - // Your code here - console.log('hi'); - } + on:mouseenter={(e) => { + mouseOver = true; + }} + on:mouseleave={(e) => { + mouseOver = false; }} on:focus={(e) => {}} draggable="false" @@ -142,9 +149,9 @@ </a> {/if} + <!-- svelte-ignore a11y-no-static-element-interactions --> <div class=" - {chat.id === $chatId || confirmEdit ? 'from-gray-200 dark:from-gray-900' : selected @@ -153,48 +160,85 @@ absolute right-[10px] top-[10px] pr-2 pl-5 bg-gradient-to-l from-80% to-transparent" + on:mouseenter={(e) => { + mouseOver = true; + }} + on:mouseleave={(e) => { + mouseOver = false; + }} > {#if confirmEdit} <div class="flex self-center space-x-1.5 z-10"> - <button - class=" self-center dark:hover:text-white transition" - on:click={() => { - editChatTitle(chat.id, chatTitle); - confirmEdit = false; - chatTitle = ''; - }} - > - <svg - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 20 20" - fill="currentColor" - class="w-4 h-4" + <Tooltip content="Confirm"> + <button + class=" self-center dark:hover:text-white transition" + on:click={() => { + editChatTitle(chat.id, chatTitle); + confirmEdit = false; + chatTitle = ''; + }} > - <path - fill-rule="evenodd" - d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" - clip-rule="evenodd" - /> - </svg> - </button> - <button - class=" self-center dark:hover:text-white transition" - on:click={() => { - confirmEdit = false; - chatTitle = ''; - }} - > - <svg - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 20 20" - fill="currentColor" - class="w-4 h-4" + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 20" + fill="currentColor" + class="w-4 h-4" + > + <path + fill-rule="evenodd" + d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" + clip-rule="evenodd" + /> + </svg> + </button> + </Tooltip> + + <Tooltip content="Cancel"> + <button + class=" self-center dark:hover:text-white transition" + on:click={() => { + confirmEdit = false; + chatTitle = ''; + }} > - <path - d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" - /> - </svg> - </button> + <svg + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 20 20" + fill="currentColor" + class="w-4 h-4" + > + <path + d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" + /> + </svg> + </button> + </Tooltip> + </div> + {:else if shiftKey && mouseOver} + <div class=" flex items-center self-center space-x-1.5"> + <Tooltip content="Archive" className="flex items-center"> + <button + class=" self-center dark:hover:text-white transition" + on:click={() => { + archiveChatHandler(chat.id); + }} + type="button" + > + <ArchiveBox className="size-4 translate-y-[0.5px]" strokeWidth="2" /> + </button> + </Tooltip> + + <Tooltip content="Delete"> + <button + class=" self-center dark:hover:text-white transition" + on:click={() => { + deleteChat(chat.id); + }} + type="button" + > + <GarbageBin strokeWidth="2" /> + </button> + </Tooltip> </div> {:else} <div class="flex self-center space-x-1 z-10">