From 31b9c2b8a4598dcff8dc02a84ed094a9d124ea3a Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sat, 20 May 2023 17:11:40 -0400 Subject: [PATCH] Improve data prefetching, less false positives --- .../Sidebar/components/CollectionLink.tsx | 4 +-- .../Sidebar/components/DocumentLink.tsx | 4 +-- .../Sidebar/components/SidebarLink.tsx | 32 +++++++++++++++++-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/app/components/Sidebar/components/CollectionLink.tsx b/app/components/Sidebar/components/CollectionLink.tsx index 7890351db..acfe7e321 100644 --- a/app/components/Sidebar/components/CollectionLink.tsx +++ b/app/components/Sidebar/components/CollectionLink.tsx @@ -118,7 +118,7 @@ const CollectionLink: React.FC = ({ setIsEditing(isEditing); }, []); - const handleMouseEnter = React.useCallback(() => { + const handlePrefetch = React.useCallback(() => { void collection.fetchDocuments(); }, [collection]); @@ -138,7 +138,7 @@ const CollectionLink: React.FC = ({ }} expanded={expanded} onDisclosureClick={onDisclosureClick} - onMouseEnter={handleMouseEnter} + onClickIntent={handlePrefetch} icon={ } diff --git a/app/components/Sidebar/components/DocumentLink.tsx b/app/components/Sidebar/components/DocumentLink.tsx index 2374d0dae..937332382 100644 --- a/app/components/Sidebar/components/DocumentLink.tsx +++ b/app/components/Sidebar/components/DocumentLink.tsx @@ -114,7 +114,7 @@ function InnerDocumentLink( [expanded] ); - const handleMouseEnter = React.useCallback(() => { + const handlePrefetch = React.useCallback(() => { prefetchDocument?.(node.id); }, [prefetchDocument, node]); @@ -317,7 +317,7 @@ function InnerDocumentLink( & { to?: LocationDescriptor; innerRef?: (ref: HTMLElement | null | undefined) => void; onClick?: React.MouseEventHandler; - onMouseEnter?: React.MouseEventHandler; + /* Callback when we expect the user to click on the link. Used for prefetching data. */ + onClickIntent?: () => void; onDisclosureClick?: React.MouseEventHandler; icon?: React.ReactNode; label?: React.ReactNode; @@ -44,7 +46,7 @@ function SidebarLink( { icon, onClick, - onMouseEnter, + onClickIntent, to, label, active, @@ -63,6 +65,7 @@ function SidebarLink( }: Props, ref: React.RefObject ) { + const timer = React.useRef(); const theme = useTheme(); const style = React.useMemo( () => ({ @@ -81,6 +84,28 @@ function SidebarLink( [theme.text, theme.sidebarActiveBackground, style] ); + const handleMouseEnter = React.useCallback(() => { + if (timer.current) { + clearTimeout(timer.current); + } + + if (onClickIntent) { + timer.current = window.setTimeout(onClickIntent, 100); + } + }, [onClickIntent]); + + const handleMouseLeave = React.useCallback(() => { + if (timer.current) { + clearTimeout(timer.current); + } + }, []); + + useUnmount(() => { + if (timer.current) { + clearTimeout(timer.current); + } + }); + return ( <>