From 5200654d0f5d884a1f132bde7712df43d89912b1 Mon Sep 17 00:00:00 2001 From: Elijah Date: Fri, 22 May 2026 19:40:08 -0700 Subject: [PATCH] New context menu, info pane fixes, pinned item syncing, and navigation bug fixes --- backend/Dockerfile | 1 + backend/handlers/settings.go | 9 +-- frontend/src/components/FileExplorer.tsx | 88 +++++++++++++++++------ frontend/src/components/FileInfoModal.tsx | 38 +++++++++- frontend/src/lib/api.ts | 2 +- 5 files changed, 111 insertions(+), 27 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index f584588..df9b0f8 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -21,6 +21,7 @@ RUN apk add --no-cache \ ffmpeg \ sqlite \ ca-certificates \ + mailcap \ tzdata # Create non-root user diff --git a/backend/handlers/settings.go b/backend/handlers/settings.go index b550426..56000c9 100644 --- a/backend/handlers/settings.go +++ b/backend/handlers/settings.go @@ -39,10 +39,11 @@ func (h *SettingsHandler) UpdateSettings(c *fiber.Ctx) error { } allowedKeys := map[string]bool{ - "theme": true, - "thumbnail_images": true, - "thumbnail_videos": true, - "trash_auto_purge_days": true, + "theme": true, + "thumbnail_images": true, + "thumbnail_videos": true, + "trash_auto_purge_days": true, + "pinned_sidebar_expanded": true, } for key, value := range body { diff --git a/frontend/src/components/FileExplorer.tsx b/frontend/src/components/FileExplorer.tsx index 7935496..135fd3a 100644 --- a/frontend/src/components/FileExplorer.tsx +++ b/frontend/src/components/FileExplorer.tsx @@ -76,6 +76,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) { const [searchResults, setSearchResults] = useState(null); const [selectedFiles, setSelectedFiles] = useState>(new Set()); const [contextMenu, setContextMenu] = useState<{ x: number; y: number; file: FileItem } | null>(null); + const [bgContextMenu, setBgContextMenu] = useState<{ x: number; y: number } | null>(null); const [renaming, setRenaming] = useState(null); const [newName, setNewName] = useState(''); const [showNewFolder, setShowNewFolder] = useState(false); @@ -109,6 +110,7 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) { if (s) { if (s.grid_size) setGridSize(s.grid_size); if (s.trash_auto_purge_days) setTrashAutoPurgeDays(parseInt(s.trash_auto_purge_days, 10)); + if (s.pinned_sidebar_expanded === 'true') setPinnedExpanded(true); if (s.pinned_order) { try { setPinnedOrder(JSON.parse(s.pinned_order)); @@ -214,11 +216,12 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) { // Close context menu on click outside useEffect(() => { - function handleClick() { + const handleClickOutside = () => { setContextMenu(null); - } - window.addEventListener('click', handleClick); - return () => window.removeEventListener('click', handleClick); + setBgContextMenu(null); + }; + window.addEventListener('click', handleClickOutside); + return () => window.removeEventListener('click', handleClickOutside); }, []); async function loadPinned() { @@ -339,6 +342,14 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) { } } + function handleBgContextMenu(e: React.MouseEvent) { + // Only show if the click was on the container itself, not on a file item + if ((e.target as HTMLElement).closest('[data-file-item]')) return; + e.preventDefault(); + setContextMenu(null); + setBgContextMenu({ x: e.clientX, y: e.clientY }); + } + function handleContextMenu(e: React.MouseEvent, file: FileItem) { e.preventDefault(); setContextMenu({ x: e.clientX, y: e.clientY, file }); @@ -724,7 +735,11 @@ export default function FileExplorer({ onLogout }: FileExplorerProps) { {/* Pinned Collapsible Section */}