From 0fcfd200a42b16394d806c8a930e12b55187695b Mon Sep 17 00:00:00 2001 From: Gigi Date: Thu, 23 Oct 2025 00:33:55 +0200 Subject: [PATCH] fix(reading-position): fix throttle logic to work with slow scrolling Previous fix didn't work because after a save, the 5% check would prevent scheduling a new timer during slow scrolling. Changes: - Always update pendingPositionRef (line 62) - Schedule timer if significant change OR 3s has passed since last save - Check 5% delta again when timer fires before actually saving This ensures continuous slow scrolling triggers saves every 3s. --- src/hooks/useReadingPosition.ts | 37 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/hooks/useReadingPosition.ts b/src/hooks/useReadingPosition.ts index 790ca466..3f6c0213 100644 --- a/src/hooks/useReadingPosition.ts +++ b/src/hooks/useReadingPosition.ts @@ -58,15 +58,7 @@ export const useReadingPosition = ({ return } - // Require at least 5% progress change to consider saving - const MIN_DELTA = 0.05 - const hasSignificantChange = Math.abs(currentPosition - lastSavedPosition.current) >= MIN_DELTA - - if (!hasSignificantChange) { - return - } - - // Update the pending position (latest position to save) + // Always update the pending position (latest position to save) pendingPositionRef.current = currentPosition // Throttle: only schedule a save if one isn't already pending @@ -75,15 +67,30 @@ export const useReadingPosition = ({ return // Already have a save scheduled, don't reset the timer } - const THROTTLE_MS = 3000 // Save every 3 seconds during scrolling + // Check if enough time has passed since last save OR if there's a significant change + const MIN_DELTA = 0.05 + const hasSignificantChange = Math.abs(currentPosition - lastSavedPosition.current) >= MIN_DELTA + const THROTTLE_MS = 3000 + const timeSinceLastSave = Date.now() - lastSavedAtRef.current + const enoughTimePassed = timeSinceLastSave >= THROTTLE_MS + + // Only schedule a save if there's a significant change or enough time has passed + if (!hasSignificantChange && !enoughTimePassed) { + return + } + saveTimerRef.current = setTimeout(() => { // Save the latest position, not the one from when timer was scheduled const positionToSave = pendingPositionRef.current - console.log(`[reading-position] [${new Date().toISOString()}] 💾 Auto-save at ${Math.round(positionToSave * 100)}%`) - lastSavedPosition.current = positionToSave - hasSavedOnce.current = true - lastSavedAtRef.current = Date.now() - onSave(positionToSave) + // Only save if there's been a significant change from last saved position + const finalDelta = Math.abs(positionToSave - lastSavedPosition.current) + if (finalDelta >= MIN_DELTA) { + console.log(`[reading-position] [${new Date().toISOString()}] 💾 Auto-save at ${Math.round(positionToSave * 100)}%`) + lastSavedPosition.current = positionToSave + hasSavedOnce.current = true + lastSavedAtRef.current = Date.now() + onSave(positionToSave) + } saveTimerRef.current = null }, THROTTLE_MS) }, [syncEnabled, onSave])