Improve data prefetching, less false positives

This commit is contained in:
Tom Moor
2023-05-20 17:11:40 -04:00
parent dbad4a9b84
commit 31b9c2b8a4
3 changed files with 33 additions and 7 deletions

View File

@@ -118,7 +118,7 @@ const CollectionLink: React.FC<Props> = ({
setIsEditing(isEditing); setIsEditing(isEditing);
}, []); }, []);
const handleMouseEnter = React.useCallback(() => { const handlePrefetch = React.useCallback(() => {
void collection.fetchDocuments(); void collection.fetchDocuments();
}, [collection]); }, [collection]);
@@ -138,7 +138,7 @@ const CollectionLink: React.FC<Props> = ({
}} }}
expanded={expanded} expanded={expanded}
onDisclosureClick={onDisclosureClick} onDisclosureClick={onDisclosureClick}
onMouseEnter={handleMouseEnter} onClickIntent={handlePrefetch}
icon={ icon={
<CollectionIcon collection={collection} expanded={expanded} /> <CollectionIcon collection={collection} expanded={expanded} />
} }

View File

@@ -114,7 +114,7 @@ function InnerDocumentLink(
[expanded] [expanded]
); );
const handleMouseEnter = React.useCallback(() => { const handlePrefetch = React.useCallback(() => {
prefetchDocument?.(node.id); prefetchDocument?.(node.id);
}, [prefetchDocument, node]); }, [prefetchDocument, node]);
@@ -317,7 +317,7 @@ function InnerDocumentLink(
<SidebarLink <SidebarLink
expanded={hasChildren ? isExpanded : undefined} expanded={hasChildren ? isExpanded : undefined}
onDisclosureClick={handleDisclosureClick} onDisclosureClick={handleDisclosureClick}
onMouseEnter={handleMouseEnter} onClickIntent={handlePrefetch}
to={{ to={{
pathname: node.url, pathname: node.url,
state: { state: {

View File

@@ -6,6 +6,7 @@ import { s } from "@shared/styles";
import { NavigationNode } from "@shared/types"; import { NavigationNode } from "@shared/types";
import EventBoundary from "~/components/EventBoundary"; import EventBoundary from "~/components/EventBoundary";
import NudeButton from "~/components/NudeButton"; import NudeButton from "~/components/NudeButton";
import useUnmount from "~/hooks/useUnmount";
import { undraggableOnDesktop } from "~/styles"; import { undraggableOnDesktop } from "~/styles";
import Disclosure from "./Disclosure"; import Disclosure from "./Disclosure";
import NavLink, { Props as NavLinkProps } from "./NavLink"; import NavLink, { Props as NavLinkProps } from "./NavLink";
@@ -20,7 +21,8 @@ type Props = Omit<NavLinkProps, "to"> & {
to?: LocationDescriptor; to?: LocationDescriptor;
innerRef?: (ref: HTMLElement | null | undefined) => void; innerRef?: (ref: HTMLElement | null | undefined) => void;
onClick?: React.MouseEventHandler<HTMLAnchorElement>; onClick?: React.MouseEventHandler<HTMLAnchorElement>;
onMouseEnter?: React.MouseEventHandler<HTMLAnchorElement>; /* Callback when we expect the user to click on the link. Used for prefetching data. */
onClickIntent?: () => void;
onDisclosureClick?: React.MouseEventHandler<HTMLButtonElement>; onDisclosureClick?: React.MouseEventHandler<HTMLButtonElement>;
icon?: React.ReactNode; icon?: React.ReactNode;
label?: React.ReactNode; label?: React.ReactNode;
@@ -44,7 +46,7 @@ function SidebarLink(
{ {
icon, icon,
onClick, onClick,
onMouseEnter, onClickIntent,
to, to,
label, label,
active, active,
@@ -63,6 +65,7 @@ function SidebarLink(
}: Props, }: Props,
ref: React.RefObject<HTMLAnchorElement> ref: React.RefObject<HTMLAnchorElement>
) { ) {
const timer = React.useRef<number>();
const theme = useTheme(); const theme = useTheme();
const style = React.useMemo( const style = React.useMemo(
() => ({ () => ({
@@ -81,6 +84,28 @@ function SidebarLink(
[theme.text, theme.sidebarActiveBackground, style] [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 ( return (
<> <>
<Link <Link
@@ -90,7 +115,8 @@ function SidebarLink(
activeStyle={isActiveDrop ? activeDropStyle : activeStyle} activeStyle={isActiveDrop ? activeDropStyle : activeStyle}
style={active ? activeStyle : style} style={active ? activeStyle : style}
onClick={onClick} onClick={onClick}
onMouseEnter={onMouseEnter} onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
// @ts-expect-error exact does not exist on div // @ts-expect-error exact does not exist on div
exact={exact !== false} exact={exact !== false}
to={to} to={to}