From 6bdc2ffa79d72daf78981209c9c5292c697cbfe5 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sat, 9 May 2026 01:31:42 +0900 Subject: [PATCH] refac --- src/lib/components/chat/FileNav.svelte | 38 ++++++++++++-- .../chat/FileNav/FileEntryRow.svelte | 16 ++++++ .../chat/FileNav/FileNavToolbar.svelte | 49 +++++++++++++++++++ src/lib/i18n/locales/en-US/translation.json | 3 ++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 2e81a94294..1bd204398c 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -92,6 +92,35 @@ let loading = false; let error: string | null = null; + // ── Sort state ────────────────────────────────────────────────────── + type SortMode = 'name' | 'date'; + let sortBy: SortMode = 'name'; + let sortAsc = true; + + const sortEntries = (items: FileEntry[]): FileEntry[] => { + return [...items].sort((a, b) => { + // Directories always first + if (a.type !== b.type) return a.type === 'directory' ? -1 : 1; + if (sortBy === 'date') { + const aTime = a.modified ?? 0; + const bTime = b.modified ?? 0; + return sortAsc ? aTime - bTime : bTime - aTime; + } + const cmp = a.name.localeCompare(b.name); + return sortAsc ? cmp : -cmp; + }); + }; + + const toggleSort = (mode: SortMode) => { + if (sortBy === mode) { + sortAsc = !sortAsc; + } else { + sortBy = mode; + sortAsc = mode === 'name'; // name defaults asc, date defaults asc (oldest first) + } + entries = sortEntries(entries); + }; + // ── Navigation history ────────────────────────────────────────────── type NavEntry = { path: string; file: string | null }; let navHistory: NavEntry[] = []; @@ -341,10 +370,7 @@ 'Failed to load directory. Check your Terminal connection in Settings → Integrations.'; entries = []; } else { - entries = result.sort((a, b) => { - if (a.type !== b.type) return a.type === 'directory' ? -1 : 1; - return a.name.localeCompare(b.name); - }); + entries = sortEntries(result); } }; @@ -918,6 +944,8 @@ {loading} {canGoBack} {canGoForward} + {sortBy} + {sortAsc} onGoBack={goBack} onGoForward={goForward} onNavigate={loadDir} @@ -934,6 +962,7 @@ onUploadFiles={handleUploadFiles} onDownloadDir={() => downloadFile(currentPath)} onMove={handleMove} + onSort={toggleSort} > {#if fileImageUrl !== null || (fileOfficeSlides !== null && fileOfficeSlides.length > 0)} @@ -1355,6 +1384,7 @@ onRename={handleRename} onSelect={handleSelect} onLongPress={enterSelectionMode} + showDate={sortBy === 'date'} /> {/each} diff --git a/src/lib/components/chat/FileNav/FileEntryRow.svelte b/src/lib/components/chat/FileNav/FileEntryRow.svelte index ef56c2c6b5..cd4c90f8a1 100644 --- a/src/lib/components/chat/FileNav/FileEntryRow.svelte +++ b/src/lib/components/chat/FileNav/FileEntryRow.svelte @@ -30,6 +30,17 @@ export let selectedPaths: Set = new Set(); export let onSelect: (entry: FileEntry, event: MouseEvent) => void = () => {}; export let onLongPress: () => void = () => {}; + export let showDate: boolean = false; + + const formatRelativeTime = (epoch: number): string => { + const diff = Math.floor(Date.now() / 1000) - epoch; + if (diff < 60) return 'just now'; + if (diff < 3600) return `${Math.floor(diff / 60)}m ago`; + if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`; + if (diff < 2592000) return `${Math.floor(diff / 86400)}d ago`; + if (diff < 31536000) return `${Math.floor(diff / 2592000)}mo ago`; + return `${Math.floor(diff / 31536000)}y ago`; + }; let dragOverFolder = false; @@ -271,7 +282,12 @@ {/if} {#if entry.type === 'file' && entry.size !== undefined && !renaming} + {#if showDate && entry.modified} + {formatRelativeTime(entry.modified)} + {/if} {formatFileSize(entry.size)} + {:else if entry.type === 'directory' && showDate && entry.modified && !renaming} + {formatRelativeTime(entry.modified)} {/if} diff --git a/src/lib/components/chat/FileNav/FileNavToolbar.svelte b/src/lib/components/chat/FileNav/FileNavToolbar.svelte index 6b705a98d6..0983995676 100644 --- a/src/lib/components/chat/FileNav/FileNavToolbar.svelte +++ b/src/lib/components/chat/FileNav/FileNavToolbar.svelte @@ -6,6 +6,7 @@ import FilePlusAlt from '../../icons/FilePlusAlt.svelte'; import Spinner from '../../common/Spinner.svelte'; import Tooltip from '../../common/Tooltip.svelte'; + import Dropdown from '$lib/components/common/Dropdown.svelte'; const i18n = getContext('i18n'); @@ -21,6 +22,11 @@ export let onDownloadDir: () => void = () => {}; export let onMove: (source: string, destFolder: string) => void = () => {}; + // Sort controls + export let sortBy: 'name' | 'date' = 'name'; + export let sortAsc: boolean = true; + export let onSort: (mode: 'name' | 'date') => void = () => {}; + // Back / forward navigation export let canGoBack = false; export let canGoForward = false; @@ -161,6 +167,49 @@ {#if !selectedFile} + + + + + +
+
+ + +
+
+