From a00caa90521da44fa6885d19f1fd35b05fda258e Mon Sep 17 00:00:00 2001 From: Richard R Date: Wed, 27 May 2026 15:48:46 -0600 Subject: [PATCH] refactor(ui): streamline document cleanup and navigation logic in doc pages Remove redundant clearCurrDoc calls from navigation links and ensure document cleanup occurs on component unmount for EPUB, HTML, and PDF pages. Simplify PDF back navigation by eliminating sidebar delay logic. Refactor DocumentListItem to avoid unnecessary router usage and consolidate document link handling. These changes improve maintainability and consistency in document lifecycle management across the UI. --- src/app/(app)/epub/[id]/page.tsx | 8 ++++++-- src/app/(app)/html/[id]/page.tsx | 8 ++++++-- src/app/(app)/pdf/[id]/page.tsx | 15 ++------------- src/components/doclist/DocumentListItem.tsx | 13 +++++-------- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/app/(app)/epub/[id]/page.tsx b/src/app/(app)/epub/[id]/page.tsx index 5d7904d..bfa5d6d 100644 --- a/src/app/(app)/epub/[id]/page.tsx +++ b/src/app/(app)/epub/[id]/page.tsx @@ -102,6 +102,12 @@ export default function EPUBPage() { loadDocument(); }, [loadDocument, isLoading]); + useEffect(() => { + return () => { + clearCurrDoc(); + }; + }, [clearCurrDoc]); + // Compute available height = viewport - (header height + tts bar height) useEffect(() => { const compute = () => { @@ -170,7 +176,6 @@ export default function EPUBPage() {

{error}

clearCurrDoc()} className="inline-flex items-center px-3 py-1 bg-base text-foreground rounded-lg hover:bg-offbase transition-all duration-200 ease-in-out hover:scale-[1.04] hover:text-accent" > @@ -188,7 +193,6 @@ export default function EPUBPage() { left={ clearCurrDoc()} className="inline-flex items-center py-1 px-2 rounded-md border border-offbase bg-base text-foreground text-xs hover:bg-offbase transition-all duration-200 ease-in-out hover:scale-[1.04] hover:text-accent" aria-label="Back to documents" > diff --git a/src/app/(app)/html/[id]/page.tsx b/src/app/(app)/html/[id]/page.tsx index 83dbdcd..76f6d11 100644 --- a/src/app/(app)/html/[id]/page.tsx +++ b/src/app/(app)/html/[id]/page.tsx @@ -102,6 +102,12 @@ export default function HTMLPage() { loadDocument(); }, [loadDocument, isLoading]); + useEffect(() => { + return () => { + clearCurrDoc(); + }; + }, [clearCurrDoc]); + // Compute available height = viewport - (header height + tts bar height) useEffect(() => { const compute = () => { @@ -157,7 +163,6 @@ export default function HTMLPage() {

{error}

{ clearCurrDoc(); }} className="inline-flex items-center px-3 py-1 bg-base text-foreground rounded-lg hover:bg-offbase transition-all duration-200 ease-in-out hover:scale-[1.04] hover:text-accent" > @@ -175,7 +180,6 @@ export default function HTMLPage() { left={ clearCurrDoc()} className="inline-flex items-center py-1 px-2 rounded-md border border-offbase bg-base text-foreground text-xs hover:bg-offbase transition-all duration-200 ease-in-out hover:scale-[1.04] hover:text-accent" aria-label="Back to documents" > diff --git a/src/app/(app)/pdf/[id]/page.tsx b/src/app/(app)/pdf/[id]/page.tsx index 30a6a6f..7413087 100644 --- a/src/app/(app)/pdf/[id]/page.tsx +++ b/src/app/(app)/pdf/[id]/page.tsx @@ -72,7 +72,6 @@ export default function PDFViewerPage() { const [containerHeight, setContainerHeight] = useState('auto'); const inFlightDocIdRef = useRef(null); const loadedDocIdRef = useRef(null); - const backNavTimeoutRef = useRef | null>(null); const clearCurrDocRef = useRef(clearCurrDoc); const [isNavigatingBack, setIsNavigatingBack] = useState(false); const parseUiState: NonNullable = parseStatus ?? 'pending'; @@ -160,9 +159,6 @@ export default function PDFViewerPage() { useEffect(() => { return () => { - if (backNavTimeoutRef.current) { - clearTimeout(backNavTimeoutRef.current); - } clearCurrDocRef.current(); }; }, []); @@ -222,16 +218,9 @@ export default function PDFViewerPage() { if (isNavigatingBack) return; setIsNavigatingBack(true); stop(); - const hadOpenSidebar = activeSidebar !== null; setActiveSidebar(null); - const delayMs = hadOpenSidebar ? 220 : 0; - if (backNavTimeoutRef.current) { - clearTimeout(backNavTimeoutRef.current); - } - backNavTimeoutRef.current = setTimeout(() => { - router.push('/app'); - }, delayMs); - }, [isNavigatingBack, stop, activeSidebar, router]); + router.push('/app'); + }, [isNavigatingBack, stop, router]); const requestForceReparse = useCallback(() => { if (forceReparseDisabled) return; diff --git a/src/components/doclist/DocumentListItem.tsx b/src/components/doclist/DocumentListItem.tsx index 1c56d51..8cb029c 100644 --- a/src/components/doclist/DocumentListItem.tsx +++ b/src/components/doclist/DocumentListItem.tsx @@ -1,6 +1,5 @@ import Link from 'next/link'; import { DragEvent, useState } from 'react'; -import { useRouter } from 'next/navigation'; import { Button } from '@headlessui/react'; import { PDFIcon, EPUBIcon, FileIcon } from '@/components/icons/Icons'; import { DocumentListDocument } from '@/types/documents'; @@ -35,9 +34,9 @@ export function DocumentListItem({ viewMode, }: DocumentListItemProps) { const [loading, setLoading] = useState(false); - const router = useRouter(); const { authEnabled } = useAuthConfig(); const { data: session } = useAuthSession(); + const href = `/${doc.type}/${encodeURIComponent(doc.id)}`; // Only allow drag and drop interactions for documents not in folders const isDraggable = dragEnabled && !doc.folderId; @@ -45,10 +44,8 @@ export function DocumentListItem({ const isAnonymousAuthed = Boolean(authEnabled && session?.user?.isAnonymous); const showDeleteButton = !(isAnonymousAuthed && doc.scope === 'unclaimed'); - const handleDocumentClick = (e: React.MouseEvent) => { - e.preventDefault(); + const handleDocumentClick = () => { setLoading(true); - router.push(`/${doc.type}/${encodeURIComponent(doc.id)}`); }; return ( @@ -81,7 +78,7 @@ export function DocumentListItem({ {viewMode === 'grid' ? ( <>