feat: restore open tabs and active tab across sessions#224
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closing the app with tabs open and reopening it now lands the user back on the same tabs in the same order, with the previously active tab focused. Closing with no tabs open is unchanged. A user whose clips were deleted/renamed between sessions gets a clean empty editor with no error dialog.
Design
SessionStateandTabRefrecords persist(folderPath, name)per open tab plus the active tab.(folderPath, name)mirrorsClipData's identity — the same pair the repository uses on disk.SessionStateServicereads and writes a single JSON file at%LocalAppData%/SharpFM/session.json. It mirrorsPluginConfigService's shape (default-path / injectable-path ctors, NullLogger-friendly).MainWindowViewModel.CaptureSessionState()snapshots the current tab strip.RestoreSessionState(state)resolves eachTabRefagainstFileMakerClipsand opens it viaOpenAsPermanent; the saved active tab is set if it resolves.App.axaml.cscallsLoad+RestoreSessionStateright after the VM constructor has finished loading the repository.MainWindow.ClosingcallsSave(vm.CaptureSessionState()).Failure handling
SessionState.Empty.Empty.{}):System.Text.Jsonproduces aSessionStatewithnullOpenTabs;Loadcoerces to[]so the restore path can iterate safely.OpenAsPermanent).Known v1 limits (intentional, called out for review)
Tests
SessionStateServiceTests(7): empty-load, round-trip, null-active, directory creation, malformed-JSON tolerance, partial-JSON coercion, IO-failure swallowed.SessionRestoreTests(8): empty capture, ordered capture w/ active, restore resolves, restored tabs are not preview, skips missing, all-missing leaves empty, missing-active leaves last-opened, full capture→restore round-trip across two VM instances.Manual smoke test plan
session.jsonto{}and reopen — clean empty editor.session.jsonto invalid JSON and reopen — clean empty editor.