Autosave before closing applab
A teacher reported that they experienced data loss in Applab several times as they navigated between levels. Turns out we have autosave set up every 30 seconds (and triggered by other actions, like clicking the run button), but no autosave when navigating away from the page.
We have logic in place in Javalab that saves a project before leaving the page -- this PR refactors that logic into project.js and makes use of in Applab.
Javalab sets a project's edited/not state to be changed on each change in its editor (Codemirror), but we have no such logic set up for Applab. In this PR, I add a change handler to Applab's editor (Droplet) such that the project's edited/not state is changed each time an update happens in the editor. It's worth noting that this change doesn't trigger a write to S3 with every key stroke or anything -- it just sets the state within project.js of hasProjectChanged to true, which then is used to decide when to write to S3 (either via our every 30 second autosave, or when navigating away from the page).
Links
- Jira (with Zendesk ticket): LABS-256
Testing story
Tested manually in an Applab level (/s/csp3-2023/lessons/5/levels/3) that before this change, I could navigate away and lose progress. With his change, we present the user with the browser default "changes may not be saved if you navigate away" dialog. You can then cancel, close again, and changes are saved. Also tested no behavior change in a Javalab allthethings level.
Follow-up work
Not sure if there's any reason we wouldn't want this for all labs? It's a little tricky because I think we have to plug into each editor (Blockly, Codemirror, Droplet, etc), but I think that is mostly handled by StudioApp's addChangeHandler?
Nice! Could other labs also simply add
project.registerSaveOnUnload();to get this behavior?
That, and making sure the editor has a change handler set up that marks a project as changed every time an edit is made (I think this would work the same way in Google Blockly labs as here, like studioApp().addChangeHandler(project.projectChanged);)
It looks like the studioApp().setupChangeHandlers thing I used is set up to handle Blockly and Droplet, so it might require additional work if we wanted to support another editor (weblab)?
@fisher-alice @sanchitmalhotra126 had to move some stuff around here for testing purposes (and add a couple new tests) since y'all last looked, lmk what you think! Sorry to have not had this sorted out the first time around.