diff options
Diffstat (limited to 'frontend/src/components/document/AutoSavePlugin.tsx')
| -rw-r--r-- | frontend/src/components/document/AutoSavePlugin.tsx | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/frontend/src/components/document/AutoSavePlugin.tsx b/frontend/src/components/document/AutoSavePlugin.tsx deleted file mode 100644 index d3d0eb5..0000000 --- a/frontend/src/components/document/AutoSavePlugin.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import { useEffect, useRef, useState, useCallback } from 'react'; -import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; -import { UNDO_COMMAND } from 'lexical'; - -const COUNTDOWN_DURATION_MS = 3000; -const TICK_INTERVAL_MS = 50; - -interface AutoSavePluginProps { - onAutoSave: (content: string) => void; - getContent: () => string; - enabled?: boolean; -} - -export default function AutoSavePlugin({ - onAutoSave, - getContent, - enabled = true, -}: AutoSavePluginProps) { - const [editor] = useLexicalComposerContext(); - const [countdown, setCountdown] = useState<number | null>(null); - const timerRef = useRef<ReturnType<typeof setInterval> | null>(null); - const startTimeRef = useRef<number>(0); - const pendingContentRef = useRef<string>(''); - const lastSavedContentRef = useRef<string>(''); - - const clearTimer = useCallback(() => { - if (timerRef.current !== null) { - clearInterval(timerRef.current); - timerRef.current = null; - } - setCountdown(null); - }, []); - - const cancelCountdown = useCallback(() => { - clearTimer(); - }, [clearTimer]); - - const startCountdown = useCallback( - (content: string) => { - pendingContentRef.current = content; - clearTimer(); - - startTimeRef.current = Date.now(); - setCountdown(COUNTDOWN_DURATION_MS); - - timerRef.current = setInterval(() => { - const elapsed = Date.now() - startTimeRef.current; - const remaining = COUNTDOWN_DURATION_MS - elapsed; - - if (remaining <= 0) { - clearTimer(); - lastSavedContentRef.current = pendingContentRef.current; - onAutoSave(pendingContentRef.current); - } else { - setCountdown(remaining); - } - }, TICK_INTERVAL_MS); - }, - [clearTimer, onAutoSave] - ); - - // Listen for editor updates (content changes) - useEffect(() => { - if (!enabled) return; - - const unregister = editor.registerUpdateListener(({ editorState, dirtyElements, dirtyLeaves }) => { - // Only trigger on actual content changes - if (dirtyElements.size === 0 && dirtyLeaves.size === 0) return; - - const content = getContent(); - if (content !== lastSavedContentRef.current) { - startCountdown(content); - } - }); - - return unregister; - }, [editor, enabled, getContent, startCountdown]); - - // Listen for undo command to cancel countdown - useEffect(() => { - const unregister = editor.registerCommand( - UNDO_COMMAND, - () => { - cancelCountdown(); - return false; // Don't prevent the undo from executing - }, - 1 // COMMAND_PRIORITY_LOW - ); - - return unregister; - }, [editor, cancelCountdown]); - - // Listen for Escape key to cancel countdown - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'Escape' && countdown !== null) { - e.preventDefault(); - cancelCountdown(); - } - }; - - document.addEventListener('keydown', handleKeyDown); - return () => document.removeEventListener('keydown', handleKeyDown); - }, [countdown, cancelCountdown]); - - // Cleanup on unmount - useEffect(() => { - return () => { - if (timerRef.current !== null) { - clearInterval(timerRef.current); - } - }; - }, []); - - if (countdown === null) return null; - - const progressPercent = (countdown / COUNTDOWN_DURATION_MS) * 100; - const secondsLeft = Math.ceil(countdown / 1000); - - return ( - <div className="autosave-bar"> - <span className="autosave-bar-text"> - Saving in {secondsLeft}s... <kbd>Esc</kbd> to cancel - </span> - <div className="autosave-bar-progress-track"> - <div - className="autosave-bar-progress-fill" - style={{ width: `${progressPercent}%` }} - /> - </div> - <button - className="autosave-bar-cancel" - onClick={cancelCountdown} - type="button" - > - Cancel - </button> - </div> - ); -} |
