Debounce PDF scale and extraction
This commit is contained in:
parent
ebff52d4e6
commit
36fdbc276d
2 changed files with 36 additions and 7 deletions
|
|
@ -9,6 +9,7 @@ import { useTTS } from '@/contexts/TTSContext';
|
||||||
import { usePDF } from '@/contexts/PDFContext';
|
import { usePDF } from '@/contexts/PDFContext';
|
||||||
import TTSPlayer from '@/components/player/TTSPlayer';
|
import TTSPlayer from '@/components/player/TTSPlayer';
|
||||||
import { useConfig } from '@/contexts/ConfigContext';
|
import { useConfig } from '@/contexts/ConfigContext';
|
||||||
|
import { debounce } from '@/utils/pdf';
|
||||||
|
|
||||||
interface PDFViewerProps {
|
interface PDFViewerProps {
|
||||||
zoomLevel: number;
|
zoomLevel: number;
|
||||||
|
|
@ -17,6 +18,7 @@ interface PDFViewerProps {
|
||||||
export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
const [containerWidth, setContainerWidth] = useState<number>(0);
|
const [containerWidth, setContainerWidth] = useState<number>(0);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const scaleRef = useRef<number>(1);
|
||||||
|
|
||||||
// Config context
|
// Config context
|
||||||
const { viewType } = useConfig();
|
const { viewType } = useConfig();
|
||||||
|
|
@ -124,7 +126,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
? (currDocPage % 2 === 0 ? currDocPage : currDocPage + 1)
|
? (currDocPage % 2 === 0 ? currDocPage : currDocPage + 1)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// Modify scale calculation to account for view type
|
// Modify scale calculation to be more efficient
|
||||||
const calculateScale = useCallback((width = pageWidth, height = pageHeight): number => {
|
const calculateScale = useCallback((width = pageWidth, height = pageHeight): number => {
|
||||||
const margin = viewType === 'dual' ? 48 : 24; // adjust margin based on view type
|
const margin = viewType === 'dual' ? 48 : 24; // adjust margin based on view type
|
||||||
const containerHeight = window.innerHeight - 100;
|
const containerHeight = window.innerHeight - 100;
|
||||||
|
|
@ -147,19 +149,34 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
return baseScale * (zoomLevel / 100);
|
return baseScale * (zoomLevel / 100);
|
||||||
}, [containerWidth, zoomLevel, pageWidth, pageHeight, viewType]);
|
}, [containerWidth, zoomLevel, pageWidth, pageHeight, viewType]);
|
||||||
|
|
||||||
// Add resize observer effect
|
// Add memoized scale to prevent unnecessary recalculations
|
||||||
|
const currentScale = useCallback(() => {
|
||||||
|
const newScale = calculateScale();
|
||||||
|
if (Math.abs(newScale - scaleRef.current) > 0.01) {
|
||||||
|
scaleRef.current = newScale;
|
||||||
|
}
|
||||||
|
return scaleRef.current;
|
||||||
|
}, [calculateScale]);
|
||||||
|
|
||||||
|
// Modify resize observer effect to use debouncing
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!containerRef.current) return;
|
if (!containerRef.current) return;
|
||||||
|
|
||||||
|
const debouncedResize = debounce((width: unknown) => {
|
||||||
|
setContainerWidth(Number(width));
|
||||||
|
}, 150); // 150ms debounce
|
||||||
|
|
||||||
const observer = new ResizeObserver(entries => {
|
const observer = new ResizeObserver(entries => {
|
||||||
const width = entries[0]?.contentRect.width;
|
const width = entries[0]?.contentRect.width;
|
||||||
if (width) {
|
if (width) {
|
||||||
setContainerWidth(width);
|
debouncedResize(width);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
observer.observe(containerRef.current);
|
observer.observe(containerRef.current);
|
||||||
return () => observer.disconnect();
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -184,7 +201,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
renderAnnotationLayer={true}
|
renderAnnotationLayer={true}
|
||||||
renderTextLayer={i + 1 === currDocPage}
|
renderTextLayer={i + 1 === currDocPage}
|
||||||
className="shadow-lg"
|
className="shadow-lg"
|
||||||
scale={calculateScale()}
|
scale={currentScale()}
|
||||||
onLoadSuccess={(page) => {
|
onLoadSuccess={(page) => {
|
||||||
setPageWidth(page.originalWidth);
|
setPageWidth(page.originalWidth);
|
||||||
setPageHeight(page.originalHeight);
|
setPageHeight(page.originalHeight);
|
||||||
|
|
@ -202,7 +219,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
renderAnnotationLayer={true}
|
renderAnnotationLayer={true}
|
||||||
renderTextLayer={leftPage === currDocPage}
|
renderTextLayer={leftPage === currDocPage}
|
||||||
className="shadow-lg"
|
className="shadow-lg"
|
||||||
scale={calculateScale()}
|
scale={currentScale()}
|
||||||
onLoadSuccess={(page) => {
|
onLoadSuccess={(page) => {
|
||||||
setPageWidth(page.originalWidth);
|
setPageWidth(page.originalWidth);
|
||||||
setPageHeight(page.originalHeight);
|
setPageHeight(page.originalHeight);
|
||||||
|
|
@ -216,7 +233,7 @@ export function PDFViewer({ zoomLevel }: PDFViewerProps) {
|
||||||
renderAnnotationLayer={true}
|
renderAnnotationLayer={true}
|
||||||
renderTextLayer={rightPage === currDocPage}
|
renderTextLayer={rightPage === currDocPage}
|
||||||
className="shadow-lg"
|
className="shadow-lg"
|
||||||
scale={calculateScale()}
|
scale={currentScale()}
|
||||||
onLoadSuccess={(page) => {
|
onLoadSuccess={(page) => {
|
||||||
setPageWidth(page.originalWidth);
|
setPageWidth(page.originalWidth);
|
||||||
setPageHeight(page.originalHeight);
|
setPageHeight(page.originalHeight);
|
||||||
|
|
|
||||||
|
|
@ -259,3 +259,15 @@ export function handleTextClick(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add debounce utility at the top of the file
|
||||||
|
export function debounce<T extends (...args: unknown[]) => unknown>(
|
||||||
|
func: T,
|
||||||
|
wait: number
|
||||||
|
): (...args: Parameters<T>) => void {
|
||||||
|
let timeout: NodeJS.Timeout;
|
||||||
|
return (...args: Parameters<T>) => {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => func(...args), wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue