Settings reorganization
This commit is contained in:
@@ -20,6 +20,7 @@ export default function CollectionReadingView({
|
||||
}: CollectionReadingViewProps) {
|
||||
const { story, collection } = data;
|
||||
const [hasScrolledToPosition, setHasScrolledToPosition] = useState(false);
|
||||
const [readingPercentage, setReadingPercentage] = useState(0);
|
||||
const contentRef = useRef<HTMLDivElement>(null);
|
||||
const saveTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
@@ -43,28 +44,38 @@ export default function CollectionReadingView({
|
||||
return Math.floor(scrollRatio * textLength);
|
||||
}, [story]);
|
||||
|
||||
// Calculate reading percentage from character position
|
||||
const calculateReadingPercentage = useCallback((currentPosition: number): number => {
|
||||
if (!story) return 0;
|
||||
|
||||
const totalLength = story.contentPlain?.length || story.contentHtml.length;
|
||||
if (totalLength === 0) return 0;
|
||||
|
||||
return Math.round((currentPosition / totalLength) * 100);
|
||||
}, [story]);
|
||||
|
||||
// Convert character position back to scroll position for auto-scroll
|
||||
const scrollToCharacterPosition = useCallback((position: number) => {
|
||||
if (!contentRef.current || !story || hasScrolledToPosition) return;
|
||||
|
||||
|
||||
const textLength = story.contentPlain?.length || story.contentHtml.length;
|
||||
if (textLength === 0 || position === 0) return;
|
||||
|
||||
|
||||
const ratio = position / textLength;
|
||||
const content = contentRef.current;
|
||||
const contentTop = content.offsetTop;
|
||||
const contentHeight = content.scrollHeight;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
|
||||
// Calculate target scroll position
|
||||
const targetScroll = contentTop + (ratio * contentHeight) - (windowHeight * 0.3);
|
||||
|
||||
|
||||
// Smooth scroll to position
|
||||
window.scrollTo({
|
||||
top: Math.max(0, targetScroll),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
|
||||
|
||||
setHasScrolledToPosition(true);
|
||||
}, [story, hasScrolledToPosition]);
|
||||
|
||||
@@ -102,23 +113,28 @@ export default function CollectionReadingView({
|
||||
console.log('Collection view - initializing reading position tracking, saved position:', story.readingPosition);
|
||||
if (story.readingPosition && story.readingPosition > 0) {
|
||||
console.log('Collection view - auto-scrolling to saved position:', story.readingPosition);
|
||||
const initialPercentage = calculateReadingPercentage(story.readingPosition);
|
||||
setReadingPercentage(initialPercentage);
|
||||
scrollToCharacterPosition(story.readingPosition);
|
||||
} else {
|
||||
console.log('Collection view - no saved position, starting fresh tracking');
|
||||
setReadingPercentage(0);
|
||||
setHasScrolledToPosition(true);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}
|
||||
}, [story, scrollToCharacterPosition, hasScrolledToPosition]);
|
||||
}, [story, scrollToCharacterPosition, calculateReadingPercentage, hasScrolledToPosition]);
|
||||
|
||||
// Track reading progress and save position
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
if (hasScrolledToPosition) {
|
||||
const characterPosition = getCharacterPositionFromScroll();
|
||||
console.log('Collection view - scroll detected, character position:', characterPosition);
|
||||
const percentage = calculateReadingPercentage(characterPosition);
|
||||
console.log('Collection view - scroll detected, character position:', characterPosition, 'percentage:', percentage);
|
||||
setReadingPercentage(percentage);
|
||||
debouncedSavePosition(characterPosition);
|
||||
} else {
|
||||
console.log('Collection view - scroll detected but not ready for tracking yet');
|
||||
@@ -132,7 +148,7 @@ export default function CollectionReadingView({
|
||||
clearTimeout(saveTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, [hasScrolledToPosition, getCharacterPositionFromScroll, debouncedSavePosition]);
|
||||
}, [hasScrolledToPosition, getCharacterPositionFromScroll, calculateReadingPercentage, debouncedSavePosition]);
|
||||
|
||||
const handlePrevious = () => {
|
||||
if (collection.previousStoryId) {
|
||||
@@ -190,6 +206,11 @@ export default function CollectionReadingView({
|
||||
|
||||
{/* Progress Bar */}
|
||||
<div className="flex items-center gap-4">
|
||||
{/* Reading percentage indicator */}
|
||||
<div className="text-sm text-blue-700 dark:text-blue-300 font-mono bg-blue-100 dark:bg-blue-900 px-2 py-1 rounded">
|
||||
{readingPercentage}%
|
||||
</div>
|
||||
|
||||
<div className="w-32 bg-blue-200 dark:bg-blue-800 rounded-full h-2">
|
||||
<div
|
||||
className="bg-blue-600 dark:bg-blue-400 h-2 rounded-full transition-all duration-300"
|
||||
|
||||
Reference in New Issue
Block a user