Fix horizontal PDF scale

This commit is contained in:
Richard Roberson 2025-01-26 14:38:16 -07:00
parent a1136be580
commit 816690360e
2 changed files with 21 additions and 21 deletions

View file

@ -1,10 +1,9 @@
'use client'; 'use client';
import { RefObject, useCallback } from 'react'; import { RefObject, useCallback, useState, useEffect, useRef } from 'react';
import { Document, Page } from 'react-pdf'; import { Document, Page } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css'; import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css'; import 'react-pdf/dist/Page/TextLayer.css';
import { useState, useEffect, useRef } from 'react';
import { PDFSkeleton } from './PDFSkeleton'; import { PDFSkeleton } from './PDFSkeleton';
import { useTTS } from '@/contexts/TTSContext'; import { useTTS } from '@/contexts/TTSContext';
import { usePDF } from '@/contexts/PDFContext'; import { usePDF } from '@/contexts/PDFContext';
@ -109,13 +108,25 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
}; };
}, [currDocText, currentSentence, highlightPattern, clearHighlights]); }, [currDocText, currentSentence, highlightPattern, clearHighlights]);
// Add scale calculation function // Add page dimensions state
const calculateScale = useCallback((pageWidth = 595): number => { const [pageWidth, setPageWidth] = useState<number>(595); // default A4 width
const [pageHeight, setPageHeight] = useState<number>(842); // default A4 height
// Modify scale calculation function to handle orientation
const calculateScale = useCallback((width = pageWidth, height = pageHeight): number => {
const margin = 24; // 24px padding on each side const margin = 24; // 24px padding on each side
const containerHeight = window.innerHeight - 100; // approximate visible height
const targetWidth = containerWidth - margin; const targetWidth = containerWidth - margin;
const baseScale = targetWidth / pageWidth; const targetHeight = containerHeight - margin;
// Calculate scales based on both dimensions
const scaleByWidth = targetWidth / width;
const scaleByHeight = targetHeight / height;
// Use the smaller scale to ensure the page fits both dimensions
const baseScale = Math.min(scaleByWidth, scaleByHeight);
return baseScale * (zoomLevel / 100); return baseScale * (zoomLevel / 100);
}, [containerWidth, zoomLevel]); }, [containerWidth, zoomLevel, pageWidth, pageHeight]);
// Add resize observer effect // Add resize observer effect
useEffect(() => { useEffect(() => {
@ -152,6 +163,10 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
renderTextLayer={true} renderTextLayer={true}
className="shadow-lg" className="shadow-lg"
scale={calculateScale()} scale={calculateScale()}
onLoadSuccess={(page) => {
setPageWidth(page.originalWidth);
setPageHeight(page.originalHeight);
}}
/> />
</div> </div>
</div> </div>

View file

@ -39,7 +39,6 @@ interface PDFContextType {
getDocument: (id: string) => Promise<PDFDocument | undefined>; getDocument: (id: string) => Promise<PDFDocument | undefined>;
removeDocument: (id: string) => Promise<void>; removeDocument: (id: string) => Promise<void>;
isLoading: boolean; isLoading: boolean;
error: string | null;
extractTextFromPDF: (pdfURL: string, currDocPage: number) => Promise<string>; extractTextFromPDF: (pdfURL: string, currDocPage: number) => Promise<string>;
highlightPattern: (text: string, pattern: string, containerRef: React.RefObject<HTMLDivElement>) => void; highlightPattern: (text: string, pattern: string, containerRef: React.RefObject<HTMLDivElement>) => void;
clearHighlights: () => void; clearHighlights: () => void;
@ -65,7 +64,6 @@ const PDFContext = createContext<PDFContextType | undefined>(undefined);
export function PDFProvider({ children }: { children: ReactNode }) { export function PDFProvider({ children }: { children: ReactNode }) {
const [documents, setDocuments] = useState<PDFDocument[]>([]); const [documents, setDocuments] = useState<PDFDocument[]>([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const { isDBReady } = useConfig(); const { isDBReady } = useConfig();
const { const {
@ -86,12 +84,10 @@ export function PDFProvider({ children }: { children: ReactNode }) {
if (!isDBReady) return; if (!isDBReady) return;
try { try {
setError(null);
const docs = await indexedDBService.getAllDocuments(); const docs = await indexedDBService.getAllDocuments();
setDocuments(docs); setDocuments(docs);
} catch (error) { } catch (error) {
console.error('Failed to load documents:', error); console.error('Failed to load documents:', error);
setError('Failed to load documents. Please try again.');
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
@ -102,7 +98,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
// Add a new document to IndexedDB // Add a new document to IndexedDB
const addDocument = useCallback(async (file: File): Promise<string> => { const addDocument = useCallback(async (file: File): Promise<string> => {
setError(null);
const id = uuidv4(); const id = uuidv4();
const newDoc: PDFDocument = { const newDoc: PDFDocument = {
id, id,
@ -118,32 +113,27 @@ export function PDFProvider({ children }: { children: ReactNode }) {
return id; return id;
} catch (error) { } catch (error) {
console.error('Failed to add document:', error); console.error('Failed to add document:', error);
setError('Failed to save the document. Please try again.');
throw error; throw error;
} }
}, []); }, []);
// Get a document by ID from IndexedDB // Get a document by ID from IndexedDB
const getDocument = useCallback(async (id: string): Promise<PDFDocument | undefined> => { const getDocument = useCallback(async (id: string): Promise<PDFDocument | undefined> => {
setError(null);
try { try {
return await indexedDBService.getDocument(id); return await indexedDBService.getDocument(id);
} catch (error) { } catch (error) {
console.error('Failed to get document:', error); console.error('Failed to get document:', error);
setError('Failed to retrieve the document. Please try again.');
return undefined; return undefined;
} }
}, []); }, []);
// Remove a document by ID from IndexedDB // Remove a document by ID from IndexedDB
const removeDocument = useCallback(async (id: string): Promise<void> => { const removeDocument = useCallback(async (id: string): Promise<void> => {
setError(null);
try { try {
await indexedDBService.removeDocument(id); await indexedDBService.removeDocument(id);
setDocuments((prev) => prev.filter((doc) => doc.id !== id)); setDocuments((prev) => prev.filter((doc) => doc.id !== id));
} catch (error) { } catch (error) {
console.error('Failed to remove document:', error); console.error('Failed to remove document:', error);
setError('Failed to remove the document. Please try again.');
throw error; throw error;
} }
}, []); }, []);
@ -241,7 +231,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
setTTSText(text); setTTSText(text);
} catch (error) { } catch (error) {
console.error('Error loading PDF text:', error); console.error('Error loading PDF text:', error);
setError('Failed to extract PDF text');
} }
}, [currDocURL, currDocPage, extractTextFromPDF, setTTSText]); }, [currDocURL, currDocPage, extractTextFromPDF, setTTSText]);
@ -254,7 +243,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
// Set curr document // Set curr document
const setCurrentDocument = useCallback(async (id: string): Promise<void> => { const setCurrentDocument = useCallback(async (id: string): Promise<void> => {
setError(null);
try { try {
const doc = await getDocument(id); const doc = await getDocument(id);
if (doc) { if (doc) {
@ -265,7 +253,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
} }
} catch (error) { } catch (error) {
console.error('Failed to get document URL:', error); console.error('Failed to get document URL:', error);
setError('Failed to retrieve the document. Please try again.');
} }
}, [getDocument]); }, [getDocument]);
@ -463,7 +450,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
getDocument, getDocument,
removeDocument, removeDocument,
isLoading, isLoading,
error,
extractTextFromPDF, extractTextFromPDF,
highlightPattern, highlightPattern,
clearHighlights, clearHighlights,
@ -483,7 +469,6 @@ export function PDFProvider({ children }: { children: ReactNode }) {
getDocument, getDocument,
removeDocument, removeDocument,
isLoading, isLoading,
error,
extractTextFromPDF, extractTextFromPDF,
highlightPattern, highlightPattern,
clearHighlights, clearHighlights,