From 53a5a64df06cae6a4d7da78fec1a33503f7137e2 Mon Sep 17 00:00:00 2001 From: j4rviscmd Date: Sat, 28 Mar 2026 15:54:04 +0900 Subject: [PATCH] fix: prevent save status indicator from persisting on note switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove isTimerActiveRef guard that caused a deadlock when status transitioned from 'saved' to 'idle' during note navigation — the timer was cleared but the ref was never reset, leaving the checkmark visible indefinitely. Add cleanup function to clear timer on unmount. Co-Authored-By: Claude Opus 4.6 --- src/shared/ui/SaveStatusIndicator.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/shared/ui/SaveStatusIndicator.tsx b/src/shared/ui/SaveStatusIndicator.tsx index d985455..b50d93a 100644 --- a/src/shared/ui/SaveStatusIndicator.tsx +++ b/src/shared/ui/SaveStatusIndicator.tsx @@ -14,33 +14,37 @@ const SAVED_DISPLAY_MS = 3000 * - `saved` – check icon only (fades out after 3 s) * - `error` – warning icon + "Save failed" * - `idle` – hidden + * + * @param props - Component props. + * @param props.status - The current save state to render. */ export function SaveStatusIndicator({ status }: { status: SaveStatus }) { const [display, setDisplay] = useState(null) const savedTimerRef = useRef | undefined>( undefined ) - const isTimerActiveRef = useRef(false) + // Synchronise the local display state with the upstream save status. + // Any previous auto-hide timer is cleared first to prevent stale callbacks. useEffect(() => { clearTimeout(savedTimerRef.current) + // "idle" means no save activity – hide the indicator immediately. if (status === 'idle') { - if (!isTimerActiveRef.current) { - setDisplay(null) - } + setDisplay(null) return } setDisplay(status) + // After showing the "saved" check icon, start a timer to fade it out. if (status === 'saved') { - isTimerActiveRef.current = true savedTimerRef.current = setTimeout(() => { setDisplay(null) - isTimerActiveRef.current = false }, SAVED_DISPLAY_MS) } + + return () => clearTimeout(savedTimerRef.current) }, [status]) return ( @@ -56,10 +60,10 @@ export function SaveStatusIndicator({ status }: { status: SaveStatus }) { )} {display === 'saved' && } {display === 'error' && ( - <> - - Save failed - + + + Save failed + )} )