import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import useExamEditorStore from "@/stores/examEditor"; import { Module } from "@/interfaces"; import { debounce } from "lodash"; import { SectionSettings } from "@/stores/examEditor/types"; // Since all the other components have a local state // that then gets updated all at once, if the keydowns // aren't here aren't throttled things can get messy const useSettingsState = ( module: Module, sectionId: number, ) => { const globalSettings = useExamEditorStore((state) => { const settings = state.modules[module].sections.find( (section) => section.sectionId === sectionId )?.settings; return settings as T; }); const dispatch = useExamEditorStore((state) => state.dispatch); const [localSettings, setLocalSettings] = useState(() => globalSettings || {} as T ); const pendingUpdatesRef = useRef>({}); useEffect(() => { if (globalSettings) { setLocalSettings(globalSettings); } }, [globalSettings]); const debouncedUpdateGlobal = useMemo(() => { const debouncedFn = debounce(() => { if (Object.keys(pendingUpdatesRef.current).length > 0) { dispatch({ type: 'UPDATE_SECTION_SETTINGS', payload: { sectionId, update: pendingUpdatesRef.current} }); pendingUpdatesRef.current = {}; } }, 1000); return debouncedFn; }, [dispatch, sectionId]); useEffect(() => { return () => { if (Object.keys(pendingUpdatesRef.current).length > 0) { dispatch({ type: 'UPDATE_SECTION_SETTINGS', payload: {sectionId, update: pendingUpdatesRef.current} }); } }; }, [dispatch, module, sectionId]); const updateLocalAndScheduleGlobal = useCallback((updates: Partial, schedule: boolean = true) => { setLocalSettings(prev => ({ ...prev, ...updates })); pendingUpdatesRef.current = { ...pendingUpdatesRef.current, ...updates }; if (schedule) { debouncedUpdateGlobal(); } }, [debouncedUpdateGlobal]); return { localSettings, updateLocalAndScheduleGlobal }; }; export default useSettingsState;