返回 DeepSeek-Reasonix
useWorkspaceTreeScrollPersistence.ts
根目录 / desktop / frontend / src / lib / useWorkspaceTreeScrollPersistence.ts
1 import { useCallback, useEffect, type RefObject, type UIEvent } from "react";
2 import { flushWorkspaceTreeMemory, rememberWorkspaceTreeScroll } from "./workspaceViewMemory";
3
4 export function useWorkspaceTreeScrollPersistence<T extends HTMLElement>({
5 memoryKey,
6 open,
7 scrollRef,
8 }: {
9 memoryKey: string;
10 open: boolean;
11 scrollRef: RefObject<T | null>;
12 }) {
13 useEffect(() => {
14 if (!open) return;
15 const element = scrollRef.current;
16 const flush = () => flushWorkspaceTreeMemory();
17 const flushWhenHidden = () => {
18 if (document.visibilityState === "hidden") flush();
19 };
20 element?.addEventListener("scrollend", flush);
21 window.addEventListener("pagehide", flush);
22 document.addEventListener("visibilitychange", flushWhenHidden);
23 return () => {
24 element?.removeEventListener("scrollend", flush);
25 window.removeEventListener("pagehide", flush);
26 document.removeEventListener("visibilitychange", flushWhenHidden);
27 flush();
28 };
29 }, [memoryKey, open, scrollRef]);
30
31 return useCallback((event: UIEvent<T>) => {
32 // Only user-initiated scrolling is persisted: tree rebuilds reset the
33 // container to scrollTop 0 via script (isTrusted=false), and persisting
34 // that 0 would clobber the saved offset so restoration jumps back to top.
35 if (!event.nativeEvent.isTrusted) return;
36 rememberWorkspaceTreeScroll(memoryKey, event.currentTarget.scrollTop);
37 }, [memoryKey]);
38 }
39
39 lines TYPESCRIPT