Implement page forward and back

This commit is contained in:
Richard Roberson 2025-01-25 22:57:29 -07:00
parent b6880b9910
commit de1ad2c4da
4 changed files with 28 additions and 14 deletions

View file

@ -159,7 +159,6 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
<TTSPlayer <TTSPlayer
currentPage={currDocPage} currentPage={currDocPage}
numPages={currDocPages} numPages={currDocPages}
onPageChange={() => {}}
/> />
</div> </div>
); );

View file

@ -1,15 +1,15 @@
import { Button } from '@headlessui/react'; import { Button } from '@headlessui/react';
export const Navigator = ({ currentPage, numPages, onPageChange }: { export const Navigator = ({ currentPage, numPages, skipToPage }: {
currentPage: number; currentPage: number;
numPages: number | undefined; numPages: number | undefined;
onPageChange: (page: number) => void; skipToPage: (page: number) => void;
}) => { }) => {
return ( return (
<div className="flex items-center space-x-1"> <div className="flex items-center space-x-1">
{/* Page back */} {/* Page back */}
<Button <Button
onClick={() => onPageChange(currentPage - 1)} onClick={() => skipToPage(currentPage - 1)}
disabled={currentPage <= 1} disabled={currentPage <= 1}
className="relative p-2 rounded-full text-foreground hover:bg-offbase data-[hover]:bg-offbase data-[active]:bg-offbase/80 transition-colors duration-200 focus:outline-none disabled:opacity-50" className="relative p-2 rounded-full text-foreground hover:bg-offbase data-[hover]:bg-offbase data-[active]:bg-offbase/80 transition-colors duration-200 focus:outline-none disabled:opacity-50"
aria-label="Previous page" aria-label="Previous page"
@ -21,14 +21,14 @@ export const Navigator = ({ currentPage, numPages, onPageChange }: {
{/* Page number */} {/* Page number */}
<div className="bg-offbase px-2 py-0.5 rounded-full"> <div className="bg-offbase px-2 py-0.5 rounded-full">
<p className="text-xs"> <p className="text-xs whitespace-nowrap">
{currentPage} / {numPages || 1} {currentPage} / {numPages || 1}
</p> </p>
</div> </div>
{/* Page forward */} {/* Page forward */}
<Button <Button
onClick={() => onPageChange(currentPage + 1)} onClick={() => skipToPage(currentPage + 1)}
disabled={currentPage >= (numPages || 1)} disabled={currentPage >= (numPages || 1)}
className="relative p-2 rounded-full text-foreground hover:bg-offbase data-[hover]:bg-offbase data-[active]:bg-offbase/80 transition-colors duration-200 focus:outline-none disabled:opacity-50" className="relative p-2 rounded-full text-foreground hover:bg-offbase data-[hover]:bg-offbase data-[active]:bg-offbase/80 transition-colors duration-200 focus:outline-none disabled:opacity-50"
aria-label="Next page" aria-label="Next page"

View file

@ -13,10 +13,9 @@ import { VoicesControl } from '@/components/player/VoicesControl';
import { SpeedControl } from '@/components/player/SpeedControl'; import { SpeedControl } from '@/components/player/SpeedControl';
import { Navigator } from '@/components/player/Navigator'; import { Navigator } from '@/components/player/Navigator';
export default function TTSPlayer({ currentPage, numPages, onPageChange }: { export default function TTSPlayer({ currentPage, numPages }: {
currentPage: number; currentPage: number;
numPages: number | undefined; numPages: number | undefined;
onPageChange: (page: number) => void;
}) { }) {
const { const {
isPlaying, isPlaying,
@ -29,6 +28,7 @@ export default function TTSPlayer({ currentPage, numPages, onPageChange }: {
voice, voice,
setVoiceAndRestart, setVoiceAndRestart,
availableVoices, availableVoices,
skipToPage,
} = useTTS(); } = useTTS();
return ( return (
@ -38,7 +38,7 @@ export default function TTSPlayer({ currentPage, numPages, onPageChange }: {
<SpeedControl speed={speed} setSpeedAndRestart={setSpeedAndRestart} /> <SpeedControl speed={speed} setSpeedAndRestart={setSpeedAndRestart} />
{/* Page Navigation */} {/* Page Navigation */}
<Navigator currentPage={currentPage} numPages={numPages} onPageChange={onPageChange} /> <Navigator currentPage={currentPage} numPages={numPages} skipToPage={skipToPage} />
{/* Playback Controls */} {/* Playback Controls */}
<Button <Button

View file

@ -53,7 +53,9 @@ interface TTSContextType {
setCurrentIndex: (index: number) => void; setCurrentIndex: (index: number) => void;
currDocPage: number; currDocPage: number;
currDocPages: number | undefined; currDocPages: number | undefined;
setCurrDocPages: (pages: number) => void; setCurrDocPages: (num: number) => void;
incrementPage: (num?: number) => void;
skipToPage: (page: number) => void;
} }
const TTSContext = createContext<TTSContextType | undefined>(undefined); const TTSContext = createContext<TTSContextType | undefined>(undefined);
@ -114,6 +116,19 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
}); });
}, [abortAudio]); }, [abortAudio]);
const skipToPage = useCallback((page: number) => {
abortAudio();
setIsPlaying(false);
setNextPageLoading(true);
setCurrentIndex(0);
setCurrDocPage(page);
}, [abortAudio]);
const incrementPage = useCallback((num = 1) => {
setNextPageLoading(true);
setCurrDocPage((prev) => prev + num);
}, []);
const advance = useCallback(async (backwards = false) => { const advance = useCallback(async (backwards = false) => {
setCurrentIndex((prev) => { setCurrentIndex((prev) => {
const nextIndex = prev + (backwards ? -1 : 1); const nextIndex = prev + (backwards ? -1 : 1);
@ -123,15 +138,13 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
} else if (nextIndex >= sentences.length && currDocPage < currDocPages!) { } else if (nextIndex >= sentences.length && currDocPage < currDocPages!) {
console.log('Advancing to next page:', currDocPage + 1); console.log('Advancing to next page:', currDocPage + 1);
setNextPageLoading(true); incrementPage();
setCurrDocPage(currDocPage + 1);
return 0; return 0;
} else if (nextIndex < 0 && currDocPage > 1) { } else if (nextIndex < 0 && currDocPage > 1) {
console.log('Advancing to previous page:', currDocPage - 1); console.log('Advancing to previous page:', currDocPage - 1);
setNextPageLoading(true); incrementPage(-1);
setCurrDocPage(currDocPage - 1);
return 0; return 0;
} else if (nextIndex >= sentences.length && currDocPage >= currDocPages!) { } else if (nextIndex >= sentences.length && currDocPage >= currDocPages!) {
@ -475,6 +488,8 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
currDocPage, currDocPage,
currDocPages, currDocPages,
setCurrDocPages, setCurrDocPages,
incrementPage,
skipToPage,
}; };
if (configIsLoading) { if (configIsLoading) {