mirror of
https://github.com/dergigi/boris.git
synced 2025-12-22 09:04:27 +01:00
fix: improve reading position calculation to reach 100%
- Add 5px threshold to detect when scrolled to bottom - Set position to exactly 1.0 (100%) when within 5px of bottom - Remove upper limit on saving positions (now saves 100% completion) - Always save when reaching 100% completion (important milestone) - Don't restore position for completed articles (100%), start from top - Better handling of edge cases in position detection - Matches ReadingProgressIndicator calculation logic
This commit is contained in:
@@ -224,7 +224,7 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
|||||||
articleIdentifier
|
articleIdentifier
|
||||||
)
|
)
|
||||||
|
|
||||||
if (savedPosition && savedPosition.position > 0.05 && savedPosition.position < 0.95) {
|
if (savedPosition && savedPosition.position > 0.05 && savedPosition.position < 1) {
|
||||||
console.log('🎯 [ContentPanel] Restoring position:', Math.round(savedPosition.position * 100) + '%')
|
console.log('🎯 [ContentPanel] Restoring position:', Math.round(savedPosition.position * 100) + '%')
|
||||||
// Wait for content to be fully rendered before scrolling
|
// Wait for content to be fully rendered before scrolling
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -240,7 +240,11 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
|||||||
console.log('✅ [ContentPanel] Restored to position:', Math.round(savedPosition.position * 100) + '%', 'scrollTop:', scrollTop)
|
console.log('✅ [ContentPanel] Restored to position:', Math.round(savedPosition.position * 100) + '%', 'scrollTop:', scrollTop)
|
||||||
}, 500) // Give content time to render
|
}, 500) // Give content time to render
|
||||||
} else if (savedPosition) {
|
} else if (savedPosition) {
|
||||||
console.log('⏭️ [ContentPanel] Position out of range (5-95%):', Math.round(savedPosition.position * 100) + '%')
|
if (savedPosition.position === 1) {
|
||||||
|
console.log('✅ [ContentPanel] Article completed (100%), starting from top')
|
||||||
|
} else {
|
||||||
|
console.log('⏭️ [ContentPanel] Position too early (<5%):', Math.round(savedPosition.position * 100) + '%')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ [ContentPanel] Failed to load reading position:', error)
|
console.error('❌ [ContentPanel] Failed to load reading position:', error)
|
||||||
|
|||||||
@@ -29,11 +29,15 @@ export const useReadingPosition = ({
|
|||||||
const scheduleSave = useCallback((currentPosition: number) => {
|
const scheduleSave = useCallback((currentPosition: number) => {
|
||||||
if (!syncEnabled || !onSave) return
|
if (!syncEnabled || !onSave) return
|
||||||
|
|
||||||
// Don't save if position is too low (< 5%) or too high (> 95%)
|
// Don't save if position is too low (< 5%)
|
||||||
if (currentPosition < 0.05 || currentPosition > 0.95) return
|
if (currentPosition < 0.05) return
|
||||||
|
|
||||||
// Don't save if position hasn't changed significantly (less than 1%)
|
// Don't save if position hasn't changed significantly (less than 1%)
|
||||||
if (Math.abs(currentPosition - lastSavedPosition.current) < 0.01) return
|
// But always save if we've reached 100% (completion)
|
||||||
|
const hasSignificantChange = Math.abs(currentPosition - lastSavedPosition.current) >= 0.01
|
||||||
|
const hasReachedCompletion = currentPosition === 1 && lastSavedPosition.current < 1
|
||||||
|
|
||||||
|
if (!hasSignificantChange && !hasReachedCompletion) return
|
||||||
|
|
||||||
// Clear existing timer
|
// Clear existing timer
|
||||||
if (saveTimerRef.current) {
|
if (saveTimerRef.current) {
|
||||||
@@ -57,8 +61,8 @@ export const useReadingPosition = ({
|
|||||||
saveTimerRef.current = null
|
saveTimerRef.current = null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save if position is meaningful
|
// Save if position is meaningful (>= 5%)
|
||||||
if (position >= 0.05 && position <= 0.95) {
|
if (position >= 0.05) {
|
||||||
lastSavedPosition.current = position
|
lastSavedPosition.current = position
|
||||||
onSave(position)
|
onSave(position)
|
||||||
}
|
}
|
||||||
@@ -77,8 +81,13 @@ export const useReadingPosition = ({
|
|||||||
const documentHeight = document.documentElement.scrollHeight
|
const documentHeight = document.documentElement.scrollHeight
|
||||||
|
|
||||||
// Calculate position based on how much of the content has been scrolled through
|
// Calculate position based on how much of the content has been scrolled through
|
||||||
const scrollProgress = Math.min(scrollTop / (documentHeight - windowHeight), 1)
|
// Add a small threshold (5px) to account for rounding and make it easier to reach 100%
|
||||||
const clampedProgress = Math.max(0, Math.min(1, scrollProgress))
|
const maxScroll = documentHeight - windowHeight
|
||||||
|
const scrollProgress = maxScroll > 0 ? scrollTop / maxScroll : 0
|
||||||
|
|
||||||
|
// If we're within 5px of the bottom, consider it 100%
|
||||||
|
const isAtBottom = scrollTop + windowHeight >= documentHeight - 5
|
||||||
|
const clampedProgress = isAtBottom ? 1 : Math.max(0, Math.min(1, scrollProgress))
|
||||||
|
|
||||||
setPosition(clampedProgress)
|
setPosition(clampedProgress)
|
||||||
onPositionChange?.(clampedProgress)
|
onPositionChange?.(clampedProgress)
|
||||||
|
|||||||
Reference in New Issue
Block a user