@@ -10,6 +10,7 @@ import { useSettings } from '../../hooks/useSettings';
1010import type { DocumentList } from '../../types/documents' ;
1111import type { FileNode } from '../../types/files' ;
1212import { isTemporaryFile } from '../../utils/fileUtils' ;
13+ import { fileStorageService } from '../../services/FileStorageService' ;
1314import { ChevronDownIcon , ClearCompileIcon , PlayIcon , StopIcon , TrashIcon } from '../common/Icons' ;
1415
1516interface LaTeXCompileButtonProps {
@@ -59,6 +60,10 @@ const LaTeXCompileButton: React.FC<LaTeXCompileButtonProps> = ({
5960 const compileButtonRef = useRef < { clearAndCompile : ( ) => void } > ( ) ;
6061 const dropdownRef = useRef < HTMLDivElement > ( null ) ;
6162
63+ const effectiveAutoCompileOnSave = useSharedSettings
64+ ? doc ?. projectMetadata ?. autoCompileOnSave ?? false
65+ : false ;
66+
6267 const projectMainFile = useSharedSettings ? doc ?. projectMetadata ?. mainFile : undefined ;
6368 const projectEngine = useSharedSettings ? doc ?. projectMetadata ?. latexEngine : undefined ;
6469 const effectiveEngine = projectEngine || latexEngine ;
@@ -128,6 +133,56 @@ const LaTeXCompileButton: React.FC<LaTeXCompileButtonProps> = ({
128133 } ;
129134 } , [ ] ) ;
130135
136+ // Listen for save events and auto-compile if enabled
137+ useEffect ( ( ) => {
138+ if ( ! useSharedSettings || ! effectiveAutoCompileOnSave || ! effectiveMainFile ) return ;
139+
140+ const handleFileSaved = async ( event : Event ) => {
141+ if ( isCompiling ) return ;
142+
143+ try {
144+ const customEvent = event as CustomEvent ;
145+ const detail = customEvent . detail ;
146+
147+ if ( ! detail ) return ;
148+
149+ const candidatePath = detail . isFile
150+ ? detail . fileId
151+ ? detail . filePath ||
152+ ( await fileStorageService . getFile ( detail . fileId ) ) ?. path
153+ : undefined
154+ : linkedFileInfo ?. filePath ?? detail . filePath ;
155+
156+ if ( ! candidatePath ?. endsWith ( '.tex' ) ) return ;
157+
158+ const mainFileToCompile =
159+ detail . isFile ? effectiveMainFile : candidatePath ;
160+
161+ setTimeout ( async ( ) => {
162+ if ( onExpandLatexOutput ) {
163+ onExpandLatexOutput ( ) ;
164+ }
165+ await compileDocument ( mainFileToCompile ) ;
166+ } , 120 ) ;
167+ } catch ( error ) {
168+ console . error ( 'Error in auto-compile on save:' , error ) ;
169+ }
170+ } ;
171+
172+ document . addEventListener ( 'file-saved' , handleFileSaved ) ;
173+ return ( ) => {
174+ document . removeEventListener ( 'file-saved' , handleFileSaved ) ;
175+ } ;
176+ } , [
177+ useSharedSettings ,
178+ effectiveAutoCompileOnSave ,
179+ effectiveMainFile ,
180+ isCompiling ,
181+ compileDocument ,
182+ onExpandLatexOutput ,
183+ linkedFileInfo ,
184+ ] ) ;
185+
131186 const shouldNavigateToMain = async ( mainFilePath : string ) : Promise < boolean > => {
132187 const navigationSetting = getSetting ( 'latex-auto-navigate-to-main' ) ?. value as string ?? 'conditional' ;
133188
@@ -320,6 +375,17 @@ const LaTeXCompileButton: React.FC<LaTeXCompileButtonProps> = ({
320375 } ) ;
321376 } ;
322377
378+ const handleAutoCompileOnSaveChange = ( checked : boolean ) => {
379+ if ( ! useSharedSettings || ! changeDoc ) return ;
380+
381+ changeDoc ( ( d ) => {
382+ if ( ! d . projectMetadata ) {
383+ d . projectMetadata = { name : '' , description : '' } ;
384+ }
385+ d . projectMetadata . autoCompileOnSave = checked ;
386+ } ) ;
387+ } ;
388+
323389 const getFileName = ( path ?: string ) => {
324390 if ( ! path ) return 'No .tex file' ;
325391 return path . split ( '/' ) . pop ( ) || path ;
@@ -442,6 +508,20 @@ const LaTeXCompileButton: React.FC<LaTeXCompileButtonProps> = ({
442508 ) }
443509 </ div >
444510
511+ { useSharedSettings && (
512+ < div className = "auto-compile-controls" >
513+ < label className = "auto-compile-checkbox" >
514+ < input
515+ type = "checkbox"
516+ checked = { effectiveAutoCompileOnSave }
517+ onChange = { ( e ) => handleAutoCompileOnSaveChange ( e . target . checked ) }
518+ disabled = { isCompiling }
519+ />
520+ Auto-compile
521+ </ label >
522+ </ div >
523+ ) }
524+
445525 < div className = "cache-controls" >
446526 < div
447527 className = "cache-item clear-cache"
0 commit comments