11'use client' ;
22
3- import { Fragment , useState , useRef } from 'react' ;
3+ import { Fragment , useState , useRef , useCallback , useEffect } from 'react' ;
44import { Dialog , DialogPanel , Transition , TransitionChild , Listbox , ListboxButton , ListboxOptions , ListboxOption , Button } from '@headlessui/react' ;
55import { useConfig , ViewType } from '@/contexts/ConfigContext' ;
66import { ChevronUpDownIcon , CheckIcon } from '@/components/icons/Icons' ;
@@ -21,13 +21,33 @@ const viewTypes = [
2121] ;
2222
2323export function DocumentSettings ( { isOpen, setIsOpen, epub } : DocViewSettingsProps ) {
24- const { viewType, skipBlank, epubTheme, updateConfigKey } = useConfig ( ) ;
24+ const { viewType, skipBlank, epubTheme, textExtractionMargin , updateConfigKey } = useConfig ( ) ;
2525 const { createFullAudioBook } = useEPUB ( ) ;
2626 const [ progress , setProgress ] = useState ( 0 ) ;
2727 const [ isGenerating , setIsGenerating ] = useState ( false ) ;
28+ const [ localMargin , setLocalMargin ] = useState ( textExtractionMargin ) ;
2829 const abortControllerRef = useRef < AbortController | null > ( null ) ;
2930 const selectedView = viewTypes . find ( v => v . id === viewType ) || viewTypes [ 0 ] ;
3031
32+ //console.log(localMargin, textExtractionMargin);
33+
34+ // Sync local margin with global state
35+ useEffect ( ( ) => {
36+ setLocalMargin ( textExtractionMargin ) ;
37+ } , [ textExtractionMargin ] ) ;
38+
39+ // Handler for slider change (updates local state only)
40+ const handleMarginChange = useCallback ( ( event : React . ChangeEvent < HTMLInputElement > ) => {
41+ setLocalMargin ( Number ( event . target . value ) ) ;
42+ } , [ ] ) ;
43+
44+ // Handler for slider release
45+ const handleMarginChangeComplete = useCallback ( ( ) => {
46+ if ( localMargin !== textExtractionMargin ) {
47+ updateConfigKey ( 'textExtractionMargin' , localMargin ) ;
48+ }
49+ } , [ localMargin , textExtractionMargin , updateConfigKey ] ) ;
50+
3151 const handleStartGeneration = async ( ) => {
3252 setIsGenerating ( true ) ;
3353 setProgress ( 0 ) ;
@@ -132,13 +152,38 @@ export function DocumentSettings({ isOpen, setIsOpen, epub }: DocViewSettingsPro
132152 </ div >
133153 ) }
134154 </ div > }
135- { ! epub && < div className = "space-y-2" >
136- < label className = "block text-sm font-medium text-foreground" > Mode</ label >
155+ { ! epub && < div className = "space-y-6" >
156+ < div className = "mt-4 space-y-2" >
157+ < label className = "block text-sm font-medium text-foreground" >
158+ Text Extraction Margin
159+ </ label >
160+ < div className = "flex justify-between" >
161+ < span className = "text-xs" > 0%</ span >
162+ < span className = "text-xs font-bold" > { Math . round ( localMargin * 100 ) } %</ span >
163+ < span className = "text-xs" > 20%</ span >
164+ </ div >
165+ < input
166+ type = "range"
167+ min = "0"
168+ max = "0.2"
169+ step = "0.01"
170+ value = { localMargin }
171+ onChange = { handleMarginChange }
172+ onMouseUp = { handleMarginChangeComplete }
173+ onKeyUp = { handleMarginChangeComplete }
174+ onTouchEnd = { handleMarginChangeComplete }
175+ className = "w-full bg-offbase rounded-lg appearance-none cursor-pointer accent-accent [&::-webkit-slider-runnable-track]:bg-offbase [&::-webkit-slider-runnable-track]:rounded-lg [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-accent [&::-moz-range-track]:bg-offbase [&::-moz-range-track]:rounded-lg [&::-moz-range-thumb]:appearance-none [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-accent"
176+ />
177+ < p className = "text-xs text-muted" >
178+ { "Don't" } include content from outer rim of the page during text extraction (experimental)
179+ </ p >
180+ </ div >
137181 < Listbox
138182 value = { selectedView }
139183 onChange = { ( newView ) => updateConfigKey ( 'viewType' , newView . id as ViewType ) }
140184 >
141- < div className = "relative z-10" >
185+ < div className = "relative z-10 space-y-2" >
186+ < label className = "block text-sm font-medium text-foreground" > Mode</ label >
142187 < ListboxButton className = "relative w-full cursor-pointer rounded-lg bg-background py-2 pl-3 pr-10 text-left text-foreground shadow-sm focus:outline-none focus:ring-2 focus:ring-accent transform transition-transform duration-200 ease-in-out hover:scale-[1.01] hover:text-accent" >
143188 < span className = "block truncate" > { selectedView . name } </ span >
144189 < span className = "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2" >
@@ -177,14 +222,16 @@ export function DocumentSettings({ isOpen, setIsOpen, epub }: DocViewSettingsPro
177222 ) ) }
178223 </ ListboxOptions >
179224 </ Transition >
225+ { selectedView . id === 'scroll' && (
226+ < p className = "text-sm text-warning pt-2" >
227+ Note: Continuous scroll may perform poorly for larger documents.
228+ </ p >
229+ ) }
180230 </ div >
181231 </ Listbox >
182- { selectedView . id === 'scroll' && (
183- < p className = "text-sm text-warning pt-2" >
184- Note: Continuous scroll may perform poorly for larger documents.
185- </ p >
186- ) }
232+
187233 </ div > }
234+
188235 < div className = "space-y-2" >
189236 < label className = "flex items-center space-x-2" >
190237 < input
0 commit comments