prefetch history

This commit is contained in:
Philipinho
2026-01-31 23:33:25 +00:00
parent 718ca2b674
commit 4873f7b9ff
2 changed files with 68 additions and 12 deletions
@@ -3,18 +3,40 @@ import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import { formattedDate } from "@/lib/time";
import classes from "./history.module.css";
import clsx from "clsx";
import { IPageHistory } from "@/features/page-history/types/page.types";
import { memo, useCallback } from "react";
interface HistoryItemProps {
historyItem: any;
onSelect: (id: string) => void;
historyItem: IPageHistory;
index: number;
onSelect: (id: string, index: number) => void;
onHover?: (id: string) => void;
onHoverEnd?: () => void;
isActive: boolean;
}
function HistoryItem({ historyItem, onSelect, isActive }: HistoryItemProps) {
const HistoryItem = memo(function HistoryItem({
historyItem,
index,
onSelect,
onHover,
onHoverEnd,
isActive,
}: HistoryItemProps) {
const handleClick = useCallback(() => {
onSelect(historyItem.id, index);
}, [onSelect, historyItem.id, index]);
const handleMouseEnter = useCallback(() => {
onHover?.(historyItem.id);
}, [onHover, historyItem.id]);
return (
<UnstyledButton
p="xs"
onClick={() => onSelect(historyItem.id)}
onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={onHoverEnd}
className={clsx(classes.history, { [classes.active]: isActive })}
>
<Group wrap="nowrap">
@@ -27,11 +49,11 @@ function HistoryItem({ historyItem, onSelect, isActive }: HistoryItemProps) {
<Group gap={4} wrap="nowrap">
<CustomAvatar
size="sm"
avatarUrl={historyItem.lastUpdatedBy.avatarUrl}
name={historyItem.lastUpdatedBy.name}
avatarUrl={historyItem.lastUpdatedBy?.avatarUrl}
name={historyItem.lastUpdatedBy?.name}
/>
<Text size="sm" c="dimmed" lineClamp={1}>
{historyItem.lastUpdatedBy.name}
{historyItem.lastUpdatedBy?.name}
</Text>
</Group>
</div>
@@ -39,6 +61,6 @@ function HistoryItem({ historyItem, onSelect, isActive }: HistoryItemProps) {
</Group>
</UnstyledButton>
);
}
});
export default HistoryItem;
@@ -2,6 +2,8 @@ import {
usePageHistoryListQuery,
usePageHistoryQuery,
} from "@/features/page-history/queries/page-history-query";
import { getPageHistoryById } from "@/features/page-history/services/page-history-service";
import { queryClient } from "@/main";
import HistoryItem from "@/features/page-history/components/history-item";
import {
activeHistoryIdAtom,
@@ -34,6 +36,8 @@ import {
SpaceCaslSubject,
} from "@/features/space/permissions/permissions.type.ts";
const PREFETCH_DELAY_MS = 300;
interface Props {
pageId: string;
}
@@ -58,6 +62,7 @@ function HistoryList({ pageId }: Props) {
);
const loadMoreRef = useRef<HTMLDivElement>(null);
const prefetchTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const [mainEditor] = useAtom(pageEditorAtom);
const [mainEditorTitle] = useAtom(titleEditorAtom);
@@ -99,6 +104,35 @@ function HistoryList({ pageId }: Props) {
}
}, [activeHistoryData]);
const clearPrefetchTimeout = useCallback(() => {
if (prefetchTimeoutRef.current) {
clearTimeout(prefetchTimeoutRef.current);
prefetchTimeoutRef.current = null;
}
}, []);
const handleHover = useCallback((historyId: string) => {
clearPrefetchTimeout();
prefetchTimeoutRef.current = setTimeout(() => {
queryClient.prefetchQuery({
queryKey: ["page-history", historyId],
queryFn: () => getPageHistoryById(historyId),
});
}, PREFETCH_DELAY_MS);
}, [clearPrefetchTimeout]);
useEffect(() => {
return clearPrefetchTimeout;
}, [clearPrefetchTimeout]);
const handleSelect = useCallback(
(id: string, index: number) => {
setActiveHistoryId(id);
setActiveHistoryPrevId(historyItems[index + 1]?.id ?? "");
},
[historyItems, setActiveHistoryId, setActiveHistoryPrevId],
);
useEffect(() => {
if (historyItems.length > 0 && !activeHistoryId) {
setActiveHistoryId(historyItems[0].id);
@@ -142,10 +176,10 @@ function HistoryList({ pageId }: Props) {
<HistoryItem
key={historyItem.id}
historyItem={historyItem}
onSelect={(id) => {
setActiveHistoryId(id);
setActiveHistoryPrevId(historyItems[index + 1]?.id ?? "");
}}
index={index}
onSelect={handleSelect}
onHover={handleHover}
onHoverEnd={clearPrefetchTimeout}
isActive={historyItem.id === activeHistoryId}
/>
))}