From 92220de5eaf63513ed7c55e270bf368b7c779ae2 Mon Sep 17 00:00:00 2001 From: Richard Roberson Date: Tue, 25 Feb 2025 15:53:45 -0700 Subject: [PATCH] Refactor PDF text extraction to support configurable margins for header, footer, left, and right --- src/components/DocumentSettings.tsx | 156 +++++++++++++++++++++------- src/contexts/ConfigContext.tsx | 40 +++++++ src/contexts/EPUBContext.tsx | 4 +- src/contexts/PDFContext.tsx | 24 ++++- src/utils/pdf.ts | 33 +++--- 5 files changed, 200 insertions(+), 57 deletions(-) diff --git a/src/components/DocumentSettings.tsx b/src/components/DocumentSettings.tsx index eed03c2..fde1a63 100644 --- a/src/components/DocumentSettings.tsx +++ b/src/components/DocumentSettings.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Fragment, useState, useRef, useCallback, useEffect } from 'react'; +import { Fragment, useState, useRef, useEffect } from 'react'; import { Dialog, DialogPanel, Transition, TransitionChild, Listbox, ListboxButton, ListboxOptions, ListboxOption, Button } from '@headlessui/react'; import { useConfig, ViewType } from '@/contexts/ConfigContext'; import { ChevronUpDownIcon, CheckIcon } from '@/components/icons/Icons'; @@ -21,32 +21,54 @@ const viewTypes = [ ]; export function DocumentSettings({ isOpen, setIsOpen, epub }: DocViewSettingsProps) { - const { viewType, skipBlank, epubTheme, textExtractionMargin, updateConfigKey } = useConfig(); + const { + viewType, + skipBlank, + epubTheme, + headerMargin, + footerMargin, + leftMargin, + rightMargin, + updateConfigKey + } = useConfig(); const { createFullAudioBook } = useEPUB(); const [progress, setProgress] = useState(0); const [isGenerating, setIsGenerating] = useState(false); - const [localMargin, setLocalMargin] = useState(textExtractionMargin); + const [localMargins, setLocalMargins] = useState({ + header: headerMargin, + footer: footerMargin, + left: leftMargin, + right: rightMargin + }); const abortControllerRef = useRef(null); const selectedView = viewTypes.find(v => v.id === viewType) || viewTypes[0]; - //console.log(localMargin, textExtractionMargin); - - // Sync local margin with global state + // Sync local margins with global state useEffect(() => { - setLocalMargin(textExtractionMargin); - }, [textExtractionMargin]); + setLocalMargins({ + header: headerMargin, + footer: footerMargin, + left: leftMargin, + right: rightMargin + }); + }, [headerMargin, footerMargin, leftMargin, rightMargin]); // Handler for slider change (updates local state only) - const handleMarginChange = useCallback((event: React.ChangeEvent) => { - setLocalMargin(Number(event.target.value)); - }, []); + const handleMarginChange = (margin: keyof typeof localMargins) => (event: React.ChangeEvent) => { + setLocalMargins(prev => ({ + ...prev, + [margin]: Number(event.target.value) + })); + }; // Handler for slider release - const handleMarginChangeComplete = useCallback(() => { - if (localMargin !== textExtractionMargin) { - updateConfigKey('textExtractionMargin', localMargin); + const handleMarginChangeComplete = (margin: keyof typeof localMargins) => () => { + const value = localMargins[margin]; + const configKey = `${margin}Margin`; + if (value !== (useConfig)[configKey as keyof typeof useConfig]) { + updateConfigKey(configKey as 'headerMargin' | 'footerMargin' | 'leftMargin' | 'rightMargin', value); } - }, [localMargin, textExtractionMargin, updateConfigKey]); + }; const handleStartGeneration = async () => { setIsGenerating(true); @@ -154,28 +176,92 @@ export function DocumentSettings({ isOpen, setIsOpen, epub }: DocViewSettingsPro } {!epub &&
-