From 9aa914a704ce62bbeb58703596e1e31191a215ec Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 22 Oct 2025 23:05:11 +0200 Subject: [PATCH] feat(reading): add save suppression to useReadingPosition Add suppressSavesFor(ms) API to temporarily block auto-saves after programmatic scrolls, preventing feedback loops where restore triggers save which triggers restore. --- src/hooks/useReadingPosition.ts | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/hooks/useReadingPosition.ts b/src/hooks/useReadingPosition.ts index 3c76f53c..8c9b7cf6 100644 --- a/src/hooks/useReadingPosition.ts +++ b/src/hooks/useReadingPosition.ts @@ -30,6 +30,12 @@ export const useReadingPosition = ({ const hasSavedOnce = useRef(false) const completionTimerRef = useRef | null>(null) const lastSavedAtRef = useRef(0) + const suppressUntilRef = useRef(0) + + // Suppress auto-saves for a given duration (used after programmatic restore) + const suppressSavesFor = useCallback((ms: number) => { + suppressUntilRef.current = Date.now() + ms + }, []) // Debounced save function const scheduleSave = useCallback((currentPosition: number) => { @@ -136,8 +142,10 @@ export const useReadingPosition = ({ positionRef.current = clampedProgress onPositionChange?.(clampedProgress) - // Schedule auto-save if sync is enabled - scheduleSave(clampedProgress) + // Schedule auto-save if sync is enabled (unless suppressed) + if (Date.now() >= suppressUntilRef.current) { + scheduleSave(clampedProgress) + } // Completion detection with 2s hold at 100% if (!hasTriggeredComplete.current) { @@ -208,6 +216,7 @@ export const useReadingPosition = ({ position, isReadingComplete, progressPercentage: Math.round(position * 100), - saveNow + saveNow, + suppressSavesFor } }