@@ -161,6 +161,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
161161 const [ messageApi , contextHolder ] = Antd . message . useMessage ( ) ;
162162 const [ generatedCode , setGeneratedCode ] = React . useState < string > ( '' ) ;
163163 const [ toolboxSettingsModalIsOpen , setToolboxSettingsModalIsOpen ] = React . useState ( false ) ;
164+ const [ modulePathToContentText , setModulePathToContentText ] = React . useState < { [ modulePath : string ] : string } > ( { } ) ;
164165 const [ tabItems , setTabItems ] = React . useState < Tabs . TabItem [ ] > ( [ ] ) ;
165166 const [ activeTab , setActiveTab ] = React . useState ( '' ) ;
166167 const [ shownPythonToolboxCategories , setShownPythonToolboxCategories ] = React . useState < Set < string > > ( new Set ( ) ) ;
@@ -208,7 +209,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
208209 // Save current blocks before language change
209210 if ( currentModule && areBlocksModified ( ) ) {
210211 try {
211- await saveBlocks ( ) ;
212+ await saveModule ( ) ;
212213 } catch ( e ) {
213214 console . error ( 'Failed to save blocks before language change:' , e ) ;
214215 }
@@ -303,15 +304,17 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
303304 } ;
304305
305306 /** Saves blocks to storage with success/error messaging. */
306- const saveBlocks = async ( ) : Promise < boolean > => {
307+ const saveModule = async ( ) : Promise < boolean > => {
307308 return new Promise ( async ( resolve , reject ) => {
308- if ( ! blocksEditor . current ) {
309+ if ( ! currentModule ||
310+ ! blocksEditor . current ) {
309311 reject ( new Error ( 'Blocks editor not initialized' ) ) ;
310312 return ;
311313 }
312314
313315 try {
314- await blocksEditor . current . saveBlocks ( ) ;
316+ const moduleContentText = await blocksEditor . current . saveModule ( ) ;
317+ modulePathToContentText [ currentModule . modulePath ] = moduleContentText ;
315318 messageApi . open ( {
316319 type : 'success' ,
317320 content : SAVE_SUCCESS_MESSAGE ,
@@ -346,7 +349,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
346349 /** Changes current module with automatic saving if modified. */
347350 const changeModule = async ( module : storageModule . Module | null ) : Promise < void > => {
348351 if ( currentModule && areBlocksModified ( ) ) {
349- await saveBlocks ( ) ;
352+ await saveModule ( ) ;
350353 }
351354 setCurrentModule ( module ) ;
352355 } ;
@@ -424,8 +427,8 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
424427 if ( generatorContext . current ) {
425428 generatorContext . current . setModule ( currentModule ) ;
426429 }
427- if ( blocksEditor . current ) {
428- blocksEditor . current . loadModuleBlocks ( currentModule , project ) ;
430+ if ( blocksEditor . current && currentModule ) {
431+ blocksEditor . current . loadModuleBlocks ( currentModule , project , modulePathToContentText ) ;
429432 }
430433 } , [ currentModule ] ) ;
431434
@@ -434,7 +437,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
434437 } ;
435438
436439 const setupWorkspace = ( newWorkspace : Blockly . WorkspaceSvg ) => {
437- if ( ! blocklyComponent . current || ! storage ) {
440+ if ( ! blocklyComponent . current || ! storage || ! generatorContext . current ) {
438441 return ;
439442 }
440443 // Recreate workspace when Blockly component is ready
@@ -456,7 +459,7 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
456459
457460 // Set the current module in the editor after creating it
458461 if ( currentModule ) {
459- blocksEditor . current . loadModuleBlocks ( currentModule , project ) ;
462+ blocksEditor . current . loadModuleBlocks ( currentModule , project , modulePathToContentText ) ;
460463 }
461464
462465 blocksEditor . current . updateToolbox ( shownPythonToolboxCategories ) ;
@@ -494,14 +497,38 @@ const AppContent: React.FC<AppContentProps> = ({ project, setProject }): React.J
494497 }
495498 } , [ currentModule , shownPythonToolboxCategories ] ) ;
496499
497- // Update tab items when project changes
500+ // Fetch modules when project changes.
501+ React . useEffect ( ( ) => {
502+ if ( project && storage ) {
503+ const fetchModules = async ( ) => {
504+ const promises : { [ modulePath : string ] : Promise < string > } = { } ; // value is promise of module content.
505+ promises [ project . robot . modulePath ] = storage . fetchFileContentText ( project . robot . modulePath ) ;
506+ project . mechanisms . forEach ( mechanism => {
507+ promises [ mechanism . modulePath ] = storage . fetchFileContentText ( mechanism . modulePath ) ;
508+ } ) ;
509+ project . opModes . forEach ( opmode => {
510+ promises [ opmode . modulePath ] = storage . fetchFileContentText ( opmode . modulePath ) ;
511+ } ) ;
512+ const modulePathToContentText : { [ modulePath : string ] : string } = { } ; // value is module content text
513+ await Promise . all (
514+ Object . entries ( promises ) . map ( async ( [ modulePath , promise ] ) => {
515+ modulePathToContentText [ modulePath ] = await promise ;
516+ } )
517+ ) ;
518+ setModulePathToContentText ( modulePathToContentText ) ;
519+ } ;
520+ fetchModules ( ) ;
521+ }
522+ } , [ project ] ) ;
523+
524+ // Update tab items when fetching modules is done.
498525 React . useEffect ( ( ) => {
499526 if ( project ) {
500527 const tabs = createTabItemsFromProject ( project ) ;
501528 setTabItems ( tabs ) ;
502529 setActiveTab ( project . robot . modulePath ) ;
503530 }
504- } , [ project ] ) ;
531+ } , [ modulePathToContentText ] ) ;
505532
506533 const { Sider, Content } = Antd . Layout ;
507534
0 commit comments