diff --git a/src/components/doclist/DocumentList.tsx b/src/components/doclist/DocumentList.tsx index 5d9118a..2233e90 100644 --- a/src/components/doclist/DocumentList.tsx +++ b/src/components/doclist/DocumentList.tsx @@ -36,6 +36,8 @@ import { ListView } from './views/ListView'; import { ColumnsView } from './views/ColumnsView'; import { GalleryView } from './views/GalleryView'; +let cachedDocumentListState: DocumentListState | null = null; + type DocumentToDelete = { id: string; name: string; @@ -116,22 +118,25 @@ interface DocumentListInnerProps { } function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { - const [sortBy, setSortBy] = useState(DEFAULT_STATE.sortBy); + const cachedState = cachedDocumentListState; + const [sortBy, setSortBy] = useState(cachedState?.sortBy ?? DEFAULT_STATE.sortBy); const [sortDirection, setSortDirection] = useState( - DEFAULT_STATE.sortDirection, + cachedState?.sortDirection ?? DEFAULT_STATE.sortDirection, ); - const [viewMode, setViewMode] = useState(DEFAULT_STATE.viewMode); - const [iconSize, setIconSize] = useState(DEFAULT_STATE.iconSize); - const [folders, setFolders] = useState(DEFAULT_STATE.folders); - const [showHint, setShowHint] = useState(true); - const [sidebarWidth, setSidebarWidth] = useState(DEFAULT_STATE.sidebarWidth); - const [sidebarFilter, setSidebarFilter] = useState('all'); - const [sidebarOpen, setSidebarOpen] = useState(true); + const [viewMode, setViewMode] = useState( + normalizeViewMode(cachedState?.viewMode ?? DEFAULT_STATE.viewMode), + ); + const [iconSize, setIconSize] = useState(cachedState?.iconSize ?? DEFAULT_STATE.iconSize); + const [folders, setFolders] = useState(cachedState?.folders ?? DEFAULT_STATE.folders); + const [showHint, setShowHint] = useState(cachedState?.showHint ?? true); + const [sidebarWidth, setSidebarWidth] = useState(cachedState?.sidebarWidth ?? DEFAULT_STATE.sidebarWidth); + const [sidebarFilter, setSidebarFilter] = useState(cachedState?.sidebarFilter ?? 'all'); + const [sidebarOpen, setSidebarOpen] = useState(!(cachedState?.sidebarCollapsed ?? false)); const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); const [query, setQuery] = useState(''); const [recentlyOpenedById, setRecentlyOpenedById] = useState>({}); - const [isInitialized, setIsInitialized] = useState(false); + const [isInitialized, setIsInitialized] = useState(cachedState !== null); const [documentToDelete, setDocumentToDelete] = useState(null); const [pendingMerge, setPendingMerge] = useState< @@ -164,6 +169,7 @@ function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { const saved = await getDocumentListState(); if (cancelled) return; if (saved) { + cachedDocumentListState = saved; setSortBy(saved.sortBy); setSortDirection(saved.sortDirection); setFolders(saved.folders ?? []); @@ -173,6 +179,17 @@ function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { setSidebarWidth(saved.sidebarWidth ?? DEFAULT_STATE.sidebarWidth); setSidebarFilter(saved.sidebarFilter ?? 'all'); setSidebarOpen(!(saved.sidebarCollapsed ?? false)); + } else { + cachedDocumentListState = null; + setSortBy(DEFAULT_STATE.sortBy); + setSortDirection(DEFAULT_STATE.sortDirection); + setFolders(DEFAULT_STATE.folders); + setShowHint(DEFAULT_STATE.showHint); + setViewMode(DEFAULT_STATE.viewMode); + setIconSize(DEFAULT_STATE.iconSize); + setSidebarWidth(DEFAULT_STATE.sidebarWidth); + setSidebarFilter(DEFAULT_STATE.sidebarFilter); + setSidebarOpen(!DEFAULT_STATE.sidebarCollapsed); } setIsInitialized(true); })(); @@ -196,6 +213,7 @@ function DocumentListInner({ brand, appActions }: DocumentListInnerProps) { sidebarFilter, sidebarCollapsed: !sidebarOpen, }; + cachedDocumentListState = state; void saveDocumentListState(state); }, [ sortBy, diff --git a/src/components/doclist/views/ColumnsView.tsx b/src/components/doclist/views/ColumnsView.tsx index 4c1ba9c..922c07a 100644 --- a/src/components/doclist/views/ColumnsView.tsx +++ b/src/components/doclist/views/ColumnsView.tsx @@ -102,6 +102,9 @@ export function ColumnsView({ }: ColumnsViewProps) { const { setVisibleOrder } = useDocumentSelection(); const [selectedDoc, setSelectedDoc] = useState(null); + const openHref = selectedDoc + ? `/${selectedDoc.type}/${encodeURIComponent(selectedDoc.id)}` + : null; useEffect(() => { setVisibleOrder(documents); @@ -154,7 +157,8 @@ export function ColumnsView({

Open diff --git a/src/components/doclist/views/DocumentTile.tsx b/src/components/doclist/views/DocumentTile.tsx index 4263a86..832612d 100644 --- a/src/components/doclist/views/DocumentTile.tsx +++ b/src/components/doclist/views/DocumentTile.tsx @@ -1,7 +1,6 @@ 'use client'; import Link from 'next/link'; -import { useEffect, useState } from 'react'; import { useDrag, useDrop, type DragSourceMonitor } from 'react-dnd'; import { Button } from '@headlessui/react'; import { PDFIcon, EPUBIcon, FileIcon } from '@/components/icons/Icons'; @@ -70,7 +69,6 @@ export function DocumentTile({ onDelete, onMergeIntoFolder, }: DocumentTileProps) { - const [loading, setLoading] = useState(false); const { authEnabled } = useAuthConfig(); const { data: session } = useAuthSession(); const href = `/${doc.type}/${encodeURIComponent(doc.id)}`; @@ -136,19 +134,9 @@ export function DocumentTile({ if (e.shiftKey || e.metaKey || e.ctrlKey) { e.preventDefault(); selection.select(doc, { shift: e.shiftKey, meta: e.metaKey || e.ctrlKey }); - return; } - selection.replace([doc]); - setLoading(true); }; - // Cap any stuck loading flag if the user navigates back. - useEffect(() => { - if (!loading) return; - const t = setTimeout(() => setLoading(false), 2500); - return () => clearTimeout(t); - }, [loading]); - return (
(null); const [activeIdx, setActiveIdx] = useState(0); const activeDoc = useMemo(() => documents[activeIdx], [documents, activeIdx]); + const openHref = activeDoc ? `/${activeDoc.type}/${encodeURIComponent(activeDoc.id)}` : null; useEffect(() => { setVisibleOrder(documents); @@ -163,7 +164,8 @@ export function GalleryView({
Open diff --git a/src/components/doclist/views/ListView.tsx b/src/components/doclist/views/ListView.tsx index 89870d2..3b08d2c 100644 --- a/src/components/doclist/views/ListView.tsx +++ b/src/components/doclist/views/ListView.tsx @@ -1,7 +1,7 @@ 'use client'; import Link from 'next/link'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { useDrag, useDrop } from 'react-dnd'; import { Button } from '@headlessui/react'; import type { @@ -87,7 +87,6 @@ function DocRow({ const selection = useDocumentSelection(); const isSelected = selection.isSelected(doc); const isInFolder = Boolean(doc.folderId); - const [loading, setLoading] = useState(false); const href = `/${doc.type}/${encodeURIComponent(doc.id)}`; const [{ isDragging }, dragRef] = useDrag(() => ({ @@ -117,22 +116,13 @@ function DocRow({ dropRef(node); }; - useEffect(() => { - if (!loading) return; - const t = setTimeout(() => setLoading(false), 2500); - return () => clearTimeout(t); - }, [loading]); - const isTarget = isOver && canDrop; const handleClick: React.MouseEventHandler = (e) => { if (e.shiftKey || e.metaKey || e.ctrlKey) { e.preventDefault(); selection.select(doc, { shift: e.shiftKey, meta: e.metaKey || e.ctrlKey }); - return; } - selection.replace([doc]); - setLoading(true); }; return ( @@ -146,12 +136,12 @@ function DocRow({ ? 'bg-offbase text-accent' : 'text-foreground hover:bg-offbase') + (isTarget ? ' ring-1 ring-accent ring-inset' : '') + - (isDragging ? ' opacity-50' : '') + - (loading ? ' prism-outline' : '') + (isDragging ? ' opacity-50' : '') } >