@@ -42,7 +42,6 @@ import {
4242 readFileAsText ,
4343} from "../utils/fs-util" ;
4444import { useDownloadActions } from "./download-hooks" ;
45- import { usePromiseRef } from "./use-promise-ref" ;
4645
4746class CodeEditorError extends Error { }
4847
@@ -136,11 +135,17 @@ export const ProjectProvider = ({
136135 const checkIfProjectNeedsFlush = useStore ( ( s ) => s . checkIfProjectNeedsFlush ) ;
137136 const getCurrentProject = useStore ( ( s ) => s . getCurrentProject ) ;
138137 const setPostImportDialogState = useStore ( ( s ) => s . setPostImportDialogState ) ;
138+ const { editorReadyPromise, editorContentLoadedPromise } = useStore (
139+ ( s ) => s . editorPromises
140+ ) ;
141+ const startUpTimestamp = useStore ( ( s ) => s . editorStartUpTimestamp ) ;
142+ const langChangeFlushedToEditor = useStore (
143+ ( s ) => s . langChangeFlushedToEditor
144+ ) ;
145+ const checkIfLangChanged = useStore ( ( s ) => s . checkIfLangChanged ) ;
139146 const navigate = useNavigate ( ) ;
140147
141148 const project = useStore ( ( s ) => s . project ) ;
142- const editorReadyPromiseRef = usePromiseRef < void > ( ) ;
143- const editorContentLoadedPromiseRef = usePromiseRef < void > ( ) ;
144149 const initialProjects = useCallback ( ( ) => {
145150 logging . log (
146151 `[MakeCode] Initialising with header ID: ${ project . header ?. id } `
@@ -150,30 +155,29 @@ export const ProjectProvider = ({
150155 } , [ logging , project ] ) ;
151156
152157 const startUpTimeout = 90000 ;
153- const startUpTimestamp = useRef < number > ( Date . now ( ) ) ;
154158
155159 const onWorkspaceLoaded = useCallback ( async ( ) => {
156160 logging . log ( "[MakeCode] Workspace loaded" ) ;
157- await editorContentLoadedPromiseRef . current . promise ;
161+ await editorContentLoadedPromise . promise ;
158162 // Get latest start up state and only mark editor ready if editor has not timed out.
159163 getEditorStartUp ( ) !== "timed out" && editorReady ( ) ;
160- editorReadyPromiseRef . current . resolve ( ) ;
164+ editorReadyPromise . resolve ( ) ;
161165 } , [
162- editorContentLoadedPromiseRef ,
166+ editorContentLoadedPromise ,
163167 editorReady ,
164- editorReadyPromiseRef ,
168+ editorReadyPromise ,
165169 getEditorStartUp ,
166170 logging ,
167171 ] ) ;
168172
169173 const onEditorContentLoaded = useCallback ( ( ) => {
170174 logging . log ( "[MakeCode] Editor content loaded" ) ;
171- editorContentLoadedPromiseRef . current . resolve ( ) ;
172- } , [ editorContentLoadedPromiseRef , logging ] ) ;
175+ editorContentLoadedPromise . resolve ( ) ;
176+ } , [ editorContentLoadedPromise , logging ] ) ;
173177
174178 const checkIfEditorStartUpTimedOut = useCallback (
175179 async ( promise : Promise < void > | undefined ) => {
176- const elapsedTimeSinceStartup = Date . now ( ) - startUpTimestamp . current ;
180+ const elapsedTimeSinceStartup = Date . now ( ) - startUpTimestamp ;
177181 const remainingTimeout = startUpTimeout - elapsedTimeSinceStartup ;
178182 if (
179183 // Editor has already timed out.
@@ -195,31 +199,39 @@ export const ProjectProvider = ({
195199 : [ ] ) ,
196200 ] ) ;
197201 } ,
198- [ editorStartUp ]
202+ [ editorStartUp , startUpTimestamp ]
199203 ) ;
200204
201205 const doAfterEditorUpdatePromise = useRef < Promise < void > > ( ) ;
202206 const doAfterEditorUpdate = useCallback (
203207 async ( action : ( ) => Promise < void > ) => {
204- if ( ! doAfterEditorUpdatePromise . current && checkIfProjectNeedsFlush ( ) ) {
208+ if (
209+ ! doAfterEditorUpdatePromise . current &&
210+ ( checkIfProjectNeedsFlush ( ) || checkIfLangChanged ( ) )
211+ ) {
205212 doAfterEditorUpdatePromise . current = ( async ( ) => {
206213 // driverRef.current is not defined on first render.
207214 // Only an issue when navigating to code page directly.
208215 if ( ! driverRef . current ) {
209216 throw new CodeEditorError ( "MakeCode iframe ref is undefined" ) ;
210- } else {
217+ } else if ( checkIfProjectNeedsFlush ( ) ) {
211218 logging . log ( "[MakeCode] Importing project" ) ;
212- await editorReadyPromiseRef . current . promise ;
219+ await editorReadyPromise . promise ;
213220 const project = getCurrentProject ( ) ;
214221 expectChangedHeader ( ) ;
215222 try {
216223 await driverRef . current . importProject ( { project } ) ;
217224 logging . log ( "[MakeCode] Project import succeeded" ) ;
218225 projectFlushedToEditor ( ) ;
226+ langChangeFlushedToEditor ( ) ;
219227 } catch ( e ) {
220228 logging . log ( "[MakeCode] Project import failed" ) ;
221229 throw e ;
222230 }
231+ } else {
232+ logging . log ( "[MakeCode] Waiting for editor after language change" ) ;
233+ await editorReadyPromise . promise ;
234+ langChangeFlushedToEditor ( ) ;
223235 }
224236 } ) ( ) ;
225237 }
@@ -243,12 +255,14 @@ export const ProjectProvider = ({
243255 } ,
244256 [
245257 checkIfProjectNeedsFlush ,
258+ checkIfLangChanged ,
246259 driverRef ,
247260 logging ,
248- editorReadyPromiseRef ,
261+ editorReadyPromise . promise ,
249262 getCurrentProject ,
250263 expectChangedHeader ,
251264 projectFlushedToEditor ,
265+ langChangeFlushedToEditor ,
252266 checkIfEditorStartUpTimedOut ,
253267 editorTimedOut ,
254268 ]
@@ -311,7 +325,7 @@ export const ProjectProvider = ({
311325 // Check if is a MakeCode hex, otherwise show error dialog.
312326 if ( hex . includes ( makeCodeMagicMark ) ) {
313327 const hasTimedOut = await checkIfEditorStartUpTimedOut (
314- editorReadyPromiseRef . current . promise
328+ editorReadyPromise . promise
315329 ) ;
316330 if ( hasTimedOut ) {
317331 openEditorTimedOutDialog ( ) ;
@@ -332,7 +346,7 @@ export const ProjectProvider = ({
332346 [
333347 checkIfEditorStartUpTimedOut ,
334348 driverRef ,
335- editorReadyPromiseRef ,
349+ editorReadyPromise ,
336350 loadDataset ,
337351 logging ,
338352 navigate ,
@@ -412,9 +426,14 @@ export const ProjectProvider = ({
412426 const editorChange = useStore ( ( s ) => s . editorChange ) ;
413427 const onWorkspaceSave = useCallback (
414428 ( event : EditorWorkspaceSaveRequest ) => {
415- editorChange ( event . project ) ;
429+ if ( ! checkIfLangChanged ( ) ) {
430+ // We don't want to handle these events until MakeCode has been
431+ // reinitialised after a language change.
432+ // We should reinitialise with the latest project.
433+ editorChange ( event . project ) ;
434+ }
416435 } ,
417- [ editorChange ]
436+ [ checkIfLangChanged , editorChange ]
418437 ) ;
419438
420439 const onBack = useCallback ( ( ) => {
0 commit comments