You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The common project save flow works well today, but hcoona#17 describes several edge cases where different parts of the app appear to interpret "saved" slightly differently.
The goal of this proposal is not to redesign the project file format or introduce a large new persistence system. The goal is smaller: make the save-state decisions explicit, shared, and tested so that the window title, Save/Ctrl+S, close/switch confirmation, autosave, and actual file persistence all agree.
Observed problem
Today, the project's undo version and last saved version work as a reasonable dirty-state proxy for the normal path:
Open an existing project.
Edit it.
Save it back to the same file.
The edge cases are different. A project can have no new undo edits but still not be safely represented by the main project file. For example:
the project has no file name yet;
the attached project file was deleted or is missing;
the current contents came from a newer autosave and have not been written back to the main file;
autosave paths can accidentally become part of later save/autosave decisions.
Those cases are not all the same UX problem. "Can the user save?", "Should the title show a dirty marker?", and "Should closing warn the user?" are related, but they should not necessarily be the same boolean.
Proposed direction
I suggest centralizing the save-state logic into a small set of derived decisions on Project, or into a small value object if that is cleaner. The exact shape is less important than making the decisions explicit and tested.
A lightweight model could track:
whether the project has a main save target;
whether the current content differs from the last explicit save;
whether the main save target is known to be missing;
whether the project was restored from a newer autosave;
whether an untitled project is still the initial blank project or has user edits.
From that, the UI can derive separate decisions:
Decision
Suggested meaning
CanSave
Save/Ctrl+S should do something useful: Save As for untitled projects, write dirty content, recreate a missing file when possible, or write recovered autosave content back to the main file.
ShowsDirtyMarker
The current content is not safely represented by the main project file.
ShouldWarnBeforeDiscard
Continuing could lose meaningful project content or recovered autosave data.
ShouldAutosave
Autosave may protect dirty content, but autosave alone should not count as an explicit save to the main project file.
Proposed user-visible behavior
Scenario
Proposed behavior
Untitled blank project
Save may open Save As, but the title does not need a dirty marker and closing does not need a warning.
Untitled project with user edits
Save opens Save As, the title shows dirty state, and close/switch prompts before discarding.
Existing clean project
Save can be disabled, no dirty marker, no close/switch prompt.
Existing dirty project
Save is enabled, the title shows dirty state, and close/switch prompts.
Attached file is missing
Save should try to write back to the original path when possible. If that fails, the app should keep the unsaved state and fall back to Save As or an error path.
Newer autosave was restored
The project should remain in a "needs explicit save" state until the recovered content is saved to the main file or saved elsewhere.
Save As is canceled
The project state should remain unchanged; dirty/recovered/missing-file state should not be cleared.
Important details
A few details seem important for correctness:
Autosave should not clear the explicit-save state. It protects the user from data loss, but it should not make the main project file count as saved.
Restoring from *-autosave-N.yafc should keep the main project file as the save target, rather than turning the autosave file into the project's normal path.
Saving should not short-circuit only because the undo version matches. If the target file is missing, Save still needs to write the file.
Existing behavior such as flushing pending undo/edit batches before persistence should be preserved.
File-system checks should be treated carefully. Whether a target can be written is ultimately known at save time, so failed saves should leave the project in a state where the user can retry or use Save As.
Owner decisions
I think the main product decisions for the project owners are:
Should a brand-new untitled blank project have Save enabled, or should Save only become enabled after edits?
Should the title * mean "content has user edits" or the broader "main project file does not safely represent the current content"?
When an attached file is missing, should Ctrl+S first try to recreate the original path, immediately prompt Save As, or show an error first?
After autosave recovery, should Save overwrite the main file directly, or should the UI make the recovery state more explicit before overwriting?
What counts as a meaningful edit for an untitled project: only user-created project changes, or also automatic/default project initialization?
My preference is:
untitled blank projects should be saveable but not dirty;
untitled edited projects should behave like normal unsaved work;
recovered autosave content should require an explicit save;
missing attached files should not be treated as clean.
Goal
The common project save flow works well today, but hcoona#17 describes several edge cases where different parts of the app appear to interpret "saved" slightly differently.
The goal of this proposal is not to redesign the project file format or introduce a large new persistence system. The goal is smaller: make the save-state decisions explicit, shared, and tested so that the window title, Save/Ctrl+S, close/switch confirmation, autosave, and actual file persistence all agree.
Observed problem
Today, the project's undo version and last saved version work as a reasonable dirty-state proxy for the normal path:
The edge cases are different. A project can have no new undo edits but still not be safely represented by the main project file. For example:
Those cases are not all the same UX problem. "Can the user save?", "Should the title show a dirty marker?", and "Should closing warn the user?" are related, but they should not necessarily be the same boolean.
Proposed direction
I suggest centralizing the save-state logic into a small set of derived decisions on
Project, or into a small value object if that is cleaner. The exact shape is less important than making the decisions explicit and tested.A lightweight model could track:
From that, the UI can derive separate decisions:
CanSaveShowsDirtyMarkerShouldWarnBeforeDiscardShouldAutosaveProposed user-visible behavior
Important details
A few details seem important for correctness:
*-autosave-N.yafcshould keep the main project file as the save target, rather than turning the autosave file into the project's normal path.Owner decisions
I think the main product decisions for the project owners are:
*mean "content has user edits" or the broader "main project file does not safely represent the current content"?My preference is:
Practical implementation path
This can be kept incremental:
MainScreento use those derived decisions for Save/Ctrl+S, the title marker, close/switch confirmation, and autosave.This could be one PR if the change stays small, or split into a model/test PR followed by UI wiring if that is easier to review.