diff --git a/src/components/EPUBViewer.tsx b/src/components/EPUBViewer.tsx index d70a22b..d3f96d5 100644 --- a/src/components/EPUBViewer.tsx +++ b/src/components/EPUBViewer.tsx @@ -27,9 +27,10 @@ export function EPUBViewer({ className = '' }: EPUBViewerProps) { const rendition = useRef(undefined); const toc = useRef([]); const locationRef = useRef(currDocPage); + const handleLocationChanged = useCallback((location: string | number, initial = false) => { - // Handle special 'next' and 'prev' cases + // Handle special 'next' and 'prev' cases, which if (location === 'next' && rendition.current) { rendition.current.next(); return; diff --git a/src/contexts/EPUBContext.tsx b/src/contexts/EPUBContext.tsx index 7119765..15fb6b7 100644 --- a/src/contexts/EPUBContext.tsx +++ b/src/contexts/EPUBContext.tsx @@ -84,9 +84,7 @@ export function EPUBProvider({ children }: { children: ReactNode }) { * Extracts text content from the current EPUB page/location */ const extractPageText = useCallback(async (book: Book, rendition: Rendition): Promise => { - try { - console.log('Extracting EPUB text from current location'); - + try { const { start, end } = rendition.location; if (!start?.cfi || !end?.cfi) return ''; diff --git a/src/contexts/TTSContext.tsx b/src/contexts/TTSContext.tsx index c69d1a4..d4969bf 100644 --- a/src/contexts/TTSContext.tsx +++ b/src/contexts/TTSContext.tsx @@ -102,7 +102,7 @@ export function TTSProvider({ children }: { children: React.ReactNode }) { // Use custom hooks const audioContext = useAudioContext(); - const audioCache = useAudioCache(50); + const audioCache = useAudioCache(25); const { availableVoices, fetchVoices } = useVoiceManagement(openApiKey, openApiBaseUrl); // Add ref for location change handler @@ -120,22 +120,21 @@ export function TTSProvider({ children }: { children: React.ReactNode }) { * State Management */ const [isPlaying, setIsPlaying] = useState(false); + const [isEPUB, setIsEPUB] = useState(false); + const [isProcessing, setIsProcessing] = useState(false); + + const [currDocPage, setCurrDocPage] = useState(1); + const currDocPageNumber = (!isEPUB ? parseInt(currDocPage.toString()) : 1); // PDF uses numbers only + const [currDocPages, setCurrDocPages] = useState(); + const [sentences, setSentences] = useState([]); const [currentIndex, setCurrentIndex] = useState(0); const [activeHowl, setActiveHowl] = useState(null); - const [isProcessing, setIsProcessing] = useState(false); const [speed, setSpeed] = useState(voiceSpeed); const [voice, setVoice] = useState(configVoice); - const [currDocPage, setCurrDocPage] = useState(1); - const [currDocPages, setCurrDocPages] = useState(); const [nextPageLoading, setNextPageLoading] = useState(false); - // Add this state to track if we're in EPUB mode - const [isEPUB, setIsEPUB] = useState(false); - - const currDocPageNumber = (!isEPUB ? parseInt(currDocPage.toString()) : 1); - - console.log('page:', currDocPage, 'pages:', currDocPages); + //console.log('page:', currDocPage, 'pages:', currDocPages); /** * Changes the current page by a specified amount diff --git a/src/utils/nlp.ts b/src/utils/nlp.ts index cdd9f08..a0aa8ae 100644 --- a/src/utils/nlp.ts +++ b/src/utils/nlp.ts @@ -15,35 +15,42 @@ export const preprocessSentenceForAudio = (text: string): string => { .trim(); }; -const MAX_BLOCK_LENGTH = 250; // Maximum characters per block +const MAX_BLOCK_LENGTH = 300; // Maximum characters per block export const splitIntoSentences = (text: string): string[] => { - // Preprocess the text before splitting into sentences - const cleanedText = preprocessSentenceForAudio(text); - const doc = nlp(cleanedText); - const rawSentences = doc.sentences().out('array') as string[]; - + // Split text into paragraphs first + const paragraphs = text.split(/\n+/); const blocks: string[] = []; - let currentBlock = ''; - for (const sentence of rawSentences) { - const trimmedSentence = sentence.trim(); + for (const paragraph of paragraphs) { + if (!paragraph.trim()) continue; + + // Preprocess each paragraph + const cleanedText = preprocessSentenceForAudio(paragraph); + const doc = nlp(cleanedText); + const rawSentences = doc.sentences().out('array') as string[]; - // If adding this sentence would exceed the limit, start a new block - if (currentBlock && (currentBlock.length + trimmedSentence.length + 1) > MAX_BLOCK_LENGTH) { - blocks.push(currentBlock.trim()); - currentBlock = trimmedSentence; - } else { - // Add to current block with a space if not empty - currentBlock = currentBlock - ? `${currentBlock} ${trimmedSentence}` - : trimmedSentence; - } - } + let currentBlock = ''; - // Add the last block if not empty - if (currentBlock) { - blocks.push(currentBlock.trim()); + for (const sentence of rawSentences) { + const trimmedSentence = sentence.trim(); + + // If adding this sentence would exceed the limit, start a new block + if (currentBlock && (currentBlock.length + trimmedSentence.length + 1) > MAX_BLOCK_LENGTH) { + blocks.push(currentBlock.trim()); + currentBlock = trimmedSentence; + } else { + // Add to current block with a space if not empty + currentBlock = currentBlock + ? `${currentBlock} ${trimmedSentence}` + : trimmedSentence; + } + } + + // Add the last block if not empty + if (currentBlock) { + blocks.push(currentBlock.trim()); + } } return blocks; diff --git a/src/utils/pdf.ts b/src/utils/pdf.ts index 00cc7ab..461e610 100644 --- a/src/utils/pdf.ts +++ b/src/utils/pdf.ts @@ -116,10 +116,12 @@ export function findBestTextMatch( lengthDiff: Infinity, }; + const SPAN_SEARCH_LIMIT = 10; + for (let i = 0; i < elements.length; i++) { let combinedText = ''; const currentElements = []; - for (let j = i; j < Math.min(i + 10, elements.length); j++) { + for (let j = i; j < Math.min(i + SPAN_SEARCH_LIMIT, elements.length); j++) { const node = elements[j]; const newText = combinedText ? `${combinedText} ${node.text}` : node.text; if (newText.length > maxCombinedLength) break;