M3.9: a browser session restored with unsaved changes stays modified
The web app reopens the last visit's project and, when it had unsaved changes, marked it modified with `bump()`. Since M3.9 the modified mark follows the saved snapshot, and a bump on the very project just opened counts as "back at the saved state", so restored changes looked saved (no `*`, no unsaved-changes prompt). `Session::mark_unsaved` forgets the saved snapshot instead: the project stays modified until saved, whatever is undone. Regression test included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b21e04b301
commit
a12d4ae1fa
|
|
@ -167,7 +167,7 @@ pub fn restore(s: &mut Session) -> bool {
|
||||||
}
|
}
|
||||||
if meta.dirty {
|
if meta.dirty {
|
||||||
// Unsaved changes stay unsaved.
|
// Unsaved changes stay unsaved.
|
||||||
s.bump();
|
s.mark_unsaved();
|
||||||
}
|
}
|
||||||
SNAP.with(|c| c.set((s.revision, 0.0)));
|
SNAP.with(|c| c.set((s.revision, 0.0)));
|
||||||
log::info!("restored the last session ({})", meta.path.as_deref().unwrap_or("untitled"));
|
log::info!("restored the last session ({})", meta.path.as_deref().unwrap_or("untitled"));
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,13 @@ impl Session {
|
||||||
self.saved_revision = self.revision;
|
self.saved_revision = self.revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The project has changes its file doesn't (a session restored with unsaved changes): it
|
||||||
|
/// stays modified until it is saved, whatever is undone.
|
||||||
|
pub fn mark_unsaved(&mut self) {
|
||||||
|
self.saved_project = Arc::new(Project::default());
|
||||||
|
self.bump();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn active_comp(&self) -> Option<&Comp> {
|
pub fn active_comp(&self) -> Option<&Comp> {
|
||||||
self.project.comp(self.state.active_comp?)
|
self.project.comp(self.state.active_comp?)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -175,3 +175,18 @@ fn modified_mark_follows_undo_and_no_op_edits_record_nothing() {
|
||||||
assert!(!s.is_dirty(), "rolled back");
|
assert!(!s.is_dirty(), "rolled back");
|
||||||
let _ = std::fs::remove_file(path);
|
let _ = std::fs::remove_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn a_session_restored_with_unsaved_changes_stays_modified() {
|
||||||
|
let mut s = Session::default();
|
||||||
|
s.execute("comp.new", json!({"name": "H", "width": 64, "height": 64, "duration": 2})).unwrap();
|
||||||
|
let p = (*s.project).clone();
|
||||||
|
// The web app reopens the last visit's project, which had unsaved changes.
|
||||||
|
s.replace_project(p, None);
|
||||||
|
assert!(!s.is_dirty());
|
||||||
|
s.mark_unsaved();
|
||||||
|
assert!(s.is_dirty());
|
||||||
|
solid(&mut s, "A");
|
||||||
|
s.execute("edit.undo", json!({})).unwrap();
|
||||||
|
assert!(s.is_dirty(), "undo doesn't reach a saved state");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue