返回 presentation-ai
useSlideChangeWatcher.ts
根目录 / src / hooks / presentation / useSlideChangeWatcher.ts
1 import { useEffect, useRef } from "react";
2
3 import { type PlateSlide } from "@/components/notebook/presentation/utils/parser";
4 import { usePresentationState } from "@/states/presentation-state";
5 import { useDebouncedSave } from "./useDebouncedSave";
6
7 interface UseSlideChangeWatcherOptions {
8 /**
9 * The delay in milliseconds before triggering a save.
10 * @default 1000
11 */
12 debounceDelay?: number;
13 /**
14 * Whether the watcher should be active
15 * @default true
16 */
17 enabled?: boolean;
18 }
19
20 /**
21 * A hook that watches for changes to the slides and triggers
22 * a debounced save function whenever changes are detected.
23 */
24 export const useSlideChangeWatcher = (
25 options: UseSlideChangeWatcherOptions = {},
26 ) => {
27 const { debounceDelay = 1000, enabled = true } = options;
28 const currentPresentationId = usePresentationState(
29 (s) => s.currentPresentationId,
30 );
31 const contentVersion = usePresentationState((s) => s.contentVersion);
32 const slides = usePresentationState((s) => s.slides);
33 const { save, saveImmediately } = useDebouncedSave({ delay: debounceDelay });
34
35 const baselineKeyRef = useRef<string | null>(null);
36 const prevSlidesRef = useRef<PlateSlide[]>([]);
37
38 // Watch for changes to the slides array and trigger save
39 useEffect(() => {
40 if (!enabled) {
41 return;
42 }
43 const { isGeneratingPresentation } = usePresentationState.getState();
44 if (isGeneratingPresentation) {
45 return;
46 }
47
48 if (!currentPresentationId || slides.length === 0) {
49 baselineKeyRef.current = null;
50 prevSlidesRef.current = slides;
51 return;
52 }
53
54 const nextBaselineKey = `${currentPresentationId}:${contentVersion}`;
55 if (baselineKeyRef.current !== nextBaselineKey) {
56 baselineKeyRef.current = nextBaselineKey;
57 prevSlidesRef.current = slides;
58 return;
59 }
60
61 if (JSON.stringify(slides) === JSON.stringify(prevSlidesRef.current)) {
62 return;
63 }
64
65 prevSlidesRef.current = slides;
66 save();
67 }, [contentVersion, currentPresentationId, enabled, save, slides]);
68
69 return {
70 saveImmediately,
71 };
72 };
73
73 lines TYPESCRIPT