From b20bcdbba72707e3b0cf2b9a6a5f3168b464ba3c Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Mon, 10 Aug 2026 20:22:29 -0600 Subject: [PATCH] refac --- .../components/common/MobileSwipePanel.svelte | 274 +++ src/lib/components/layout/Sidebar.svelte | 1578 +++++++++-------- .../components/layout/Sidebar/ChatItem.svelte | 9 + 3 files changed, 1079 insertions(+), 782 deletions(-) create mode 100644 src/lib/components/common/MobileSwipePanel.svelte diff --git a/src/lib/components/common/MobileSwipePanel.svelte b/src/lib/components/common/MobileSwipePanel.svelte new file mode 100644 index 0000000000..538cf6b1ee --- /dev/null +++ b/src/lib/components/common/MobileSwipePanel.svelte @@ -0,0 +1,274 @@ + + + + + diff --git a/src/lib/components/layout/Sidebar.svelte b/src/lib/components/layout/Sidebar.svelte index 8e20c83d96..6691938abe 100644 --- a/src/lib/components/layout/Sidebar.svelte +++ b/src/lib/components/layout/Sidebar.svelte @@ -92,9 +92,13 @@ import DropdownMenu from '../common/DropdownMenu.svelte'; import CheckIcon from '../icons/Check.svelte'; import MoreHorizontalIcon from './Sidebar/icons/MoreHorizontal.svelte'; + import MobileSwipePanel from '../common/MobileSwipePanel.svelte'; const BREAKPOINT = 768; const DEFAULT_PINNED_ITEMS = ['notes', 'workspace']; + const MOBILE_SIDEBAR_SETTLE_MS = 210; + const sidebarMountTransition = (node: Element, params: Record) => + $mobile ? { duration: 0, css: () => '' } : slide(node, params); let scrollTop = 0; @@ -554,32 +558,6 @@ draggedOver = false; // Reset draggedOver status after drop }; - let touchstart; - let touchend; - - function checkDirection() { - const screenWidth = window.innerWidth; - const swipeDistance = Math.abs(touchend.screenX - touchstart.screenX); - if (touchstart.clientX < 40 && swipeDistance >= screenWidth / 8) { - if (touchend.screenX < touchstart.screenX) { - showSidebar.set(false); - } - if (touchend.screenX > touchstart.screenX) { - showSidebar.set(true); - } - } - } - - const onTouchStart = (e) => { - touchstart = e.changedTouches[0]; - console.log(touchstart.clientX); - }; - - const onTouchEnd = (e) => { - touchend = e.changedTouches[0]; - checkDirection(); - }; - const onKeyDown = (e) => { if (e.key === 'Shift') { shiftKey = true; @@ -599,6 +577,21 @@ selectedChatId = null; }; + const focusChatInputSoon = () => { + setTimeout(() => { + document.getElementById('chat-input')?.focus({ preventScroll: true }); + }, MOBILE_SIDEBAR_SETTLE_MS); + }; + + const closeMobileSidebar = (focusChatInput = false) => { + if ($mobile) { + showSidebar.set(false); + if (focusChatInput) { + focusChatInputSoon(); + } + } + }; + const MIN_WIDTH = 220; const MAX_WIDTH = 480; @@ -701,9 +694,6 @@ window.addEventListener('keydown', onKeyDown); window.addEventListener('keyup', onKeyUp); - window.addEventListener('touchstart', onTouchStart); - window.addEventListener('touchend', onTouchEnd); - window.addEventListener('focus', onFocus); window.addEventListener('blur', onBlur); @@ -739,9 +729,6 @@ window.removeEventListener('keydown', onKeyDown); window.removeEventListener('keyup', onKeyUp); - window.removeEventListener('touchstart', onTouchStart); - window.removeEventListener('touchend', onTouchEnd); - window.removeEventListener('focus', onFocus); window.removeEventListener('blur', onBlur); @@ -811,27 +798,20 @@ const newChatHandler = async () => { selectedChatId = null; selectedFolder.set(null); + closeMobileSidebar(true); if ($user?.role !== 'admin' && $user?.permissions?.chat?.temporary_enforced) { await temporaryChatEnabled.set(true); } else { await temporaryChatEnabled.set(false); } - - setTimeout(() => { - if ($mobile) { - showSidebar.set(false); - } - }, 0); }; const itemClickHandler = async () => { selectedChatId = null; chatId.set(''); - if ($mobile) { - showSidebar.set(false); - } + closeMobileSidebar(); await tick(); }; @@ -887,37 +867,6 @@ }} /> - - -{#if $showSidebar} -
{ - showSidebar.set(!$showSidebar); - }} - /> -{/if} - - { - if ($mobile) { - showSidebar.set(false); - } - }} -/> - - - -
- - - - -
-
-
- {#if $user !== undefined && $user !== null} - - - - {/if} -
-
-
- -{/if} - - - - -{#if $showSidebar} - - -
{ - if (e.target.scrollTop === 0) { - scrollTop = 0; - } else { - scrollTop = e.target.scrollTop; - } + + +
+ +
+
+ + { + e.stopImmediatePropagation(); + e.preventDefault(); + + goto('/'); + newChatHandler(); + }} + aria-label={$i18n.t('New Chat')} + > +
+ +
+
+
-
- {#each pinnedItems as itemId (itemId)} - {@const meta = getMenuItemMeta(itemId)} - {#if meta && isMenuItemVisible(itemId)} +
+ + + +
+ + {#each pinnedItems as itemId (itemId)} + {@const meta = getMenuItemMeta(itemId)} + {#if meta && isMenuItemVisible(itemId)} + + {/if} + {/each} +
+ + +
+
+
+ {#if $user !== undefined && $user !== null} + + + + {/if}
+
+
+ {/if} - {#if ($models ?? []).length > 0 && (($settings?.pinnedModels ?? []).length > 0 || $config?.default_pinned_models)} - + + + {#if visible} + + + - - {#if !$mobile} -