From 7dfbdd221ac0f7a839dd049e3e82b6a84c316860 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 13 Aug 2026 15:20:59 -0600 Subject: [PATCH] refac --- src/lib/components/chat/FileNav.svelte | 627 +++++++++++------- .../chat/FileNav/BulkActionBar.svelte | 57 +- .../chat/FileNav/FileEntryRow.svelte | 186 ++++-- .../chat/FileNav/FileNavToolbar.svelte | 156 +++-- .../components/chat/FileNav/PortList.svelte | 53 +- 5 files changed, 632 insertions(+), 447 deletions(-) diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index 6b14ee6c62..3548140179 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -1,6 +1,8 @@ -
- +
+ {$i18n.t('{{count}} selected', { count })}
diff --git a/src/lib/components/chat/FileNav/FileEntryRow.svelte b/src/lib/components/chat/FileNav/FileEntryRow.svelte index defdaab477..d172d53397 100644 --- a/src/lib/components/chat/FileNav/FileEntryRow.svelte +++ b/src/lib/components/chat/FileNav/FileEntryRow.svelte @@ -6,16 +6,18 @@ import Dropdown from '$lib/components/common/Dropdown.svelte'; import DropdownMenu from '$lib/components/common/DropdownMenu.svelte'; - import EllipsisHorizontal from '../../icons/EllipsisHorizontal.svelte'; - import GarbageBin from '../../icons/GarbageBin.svelte'; - import Pencil from '../../icons/Pencil.svelte'; - import Clipboard from '../../icons/Clipboard.svelte'; import FileTypeIcon from './FileTypeIcon.svelte'; + import Icon from './Icon.svelte'; const i18n: any = getContext('i18n'); export let entry: FileEntry; export let currentPath: string; + export let fullPath: string | null = null; + export let depth = 0; + export let rowIndex = 0; + export let expanded = false; + export let loadingChildren = false; export let terminalUrl: string = ''; export let terminalKey: string = ''; @@ -29,13 +31,23 @@ export let selected: boolean = false; export let selectionMode: boolean = false; export let selectedPaths: Set = new Set(); - export let onSelect: (entry: FileEntry, event: MouseEvent) => void = () => {}; + export let onSelect: ( + entry: FileEntry, + event: MouseEvent, + path: string, + index: number + ) => void = () => {}; export let onLongPress: () => void = () => {}; + export let onToggleExpand: (path: string) => void = () => {}; export let showDate: boolean = false; export let parentWritable = true; + $: entryPath = + fullPath ?? (entry.type === 'directory' ? `${currentPath}${entry.name}/` : `${currentPath}${entry.name}`); + $: directoryPath = entryPath.endsWith('/') ? entryPath : `${entryPath}/`; $: writable = entry.writable !== false; $: canMutate = parentWritable && writable; + $: rowIndent = `${12 + depth * 16}px`; const formatRelativeTime = (epoch: number): string => { const diff = Math.floor(Date.now() / 1000) - epoch; @@ -48,6 +60,13 @@ }; let dragOverFolder = false; + let expandTimer: ReturnType | null = null; + + const clearExpandTimer = () => { + if (!expandTimer) return; + clearTimeout(expandTimer); + expandTimer = null; + }; // ── Rename state ───────────────────────────────────────────────────── let renaming = false; @@ -71,7 +90,7 @@ const newName = renameValue.trim(); renaming = false; if (!newName || newName === entry.name) return; - onRename(`${currentPath}${entry.name}`, newName); + onRename(entryPath.replace(/\/$/, ''), newName); }; const cancelRename = () => { @@ -89,7 +108,7 @@ longPressTimer = setTimeout(() => { didLongPress = true; onLongPress(); - onSelect(entry, e as any); + onSelect(entry, e as any, entryPath, rowIndex); }, 500); }; @@ -109,6 +128,7 @@ onDestroy(() => { if (longPressTimer) clearTimeout(longPressTimer); + clearExpandTimer(); }); // ── Click handler ──────────────────────────────────────────────────── @@ -122,13 +142,13 @@ // Modifier click → toggle/range select if (e.metaKey || e.ctrlKey || e.shiftKey) { e.preventDefault(); - onSelect(entry, e); + onSelect(entry, e, entryPath, rowIndex); return; } // In selection mode (touch) → toggle select if (selectionMode) { - onSelect(entry, e); + onSelect(entry, e, entryPath, rowIndex); return; } @@ -137,14 +157,13 @@ }; -
  • +
  • { if (entry.type !== 'directory') return; if (!writable) return; @@ -152,11 +171,18 @@ e.preventDefault(); e.stopPropagation(); dragOverFolder = true; + if (!expanded && !expandTimer) { + expandTimer = setTimeout(() => { + onToggleExpand(directoryPath); + expandTimer = null; + }, 600); + } }} on:dragleave={(e) => { if (entry.type !== 'directory') return; e.stopPropagation(); dragOverFolder = false; + clearExpandTimer(); }} on:drop={(e) => { if (entry.type !== 'directory') return; @@ -166,10 +192,11 @@ e.preventDefault(); e.stopPropagation(); dragOverFolder = false; + clearExpandTimer(); try { const data = JSON.parse(raw); const paths = data.paths || (data.path ? [data.path] : []); - const destFolder = `${currentPath}${entry.name}/`; + const destFolder = directoryPath; for (const p of paths) { if (p + '/' === destFolder || p === destFolder) continue; onMove(p, destFolder); @@ -177,15 +204,35 @@ } catch {} }} > + {#if entry.type === 'directory'} + + {:else} + + {/if} +
    + {#if entry.type === 'directory'} + + {:else} + + {/if} + diff --git a/src/lib/components/chat/FileNav/FileNavToolbar.svelte b/src/lib/components/chat/FileNav/FileNavToolbar.svelte index 83dbb0afe3..4399f7dbf7 100644 --- a/src/lib/components/chat/FileNav/FileNavToolbar.svelte +++ b/src/lib/components/chat/FileNav/FileNavToolbar.svelte @@ -20,11 +20,13 @@ export let onUploadFiles: (files: File[]) => void = () => {}; export let onDownloadDir: () => void = () => {}; export let onMove: (source: string, destFolder: string) => void = () => {}; + export let showHidden = false; + export let onToggleHidden: () => void = () => {}; // Sort controls - export let sortBy: 'name' | 'date' = 'name'; + export let sortBy: 'name' | 'size' | 'date' = 'name'; export let sortAsc: boolean = true; - export let onSort: (mode: 'name' | 'date') => void = () => {}; + export let onSort: (mode: 'name' | 'size' | 'date') => void = () => {}; // Back / forward navigation export let canGoBack = false; @@ -46,45 +48,45 @@ }); -
    +
    {#each breadcrumbs as crumb, i} {#if showSeparator(i)} - / + / {/if} @@ -144,10 +146,10 @@ @@ -155,7 +157,7 @@ +
    - - - - - - - - - - - - + + + + + +
    + + + + + + + +
    +
    (); @@ -55,21 +56,15 @@
    @@ -111,7 +95,7 @@ {:else} {#each ports as port}