Fix mobile session stability: persist connection state across API failures#50
Merged
Merged
Conversation
The router previously bounced any user without local data straight to ConnectScreen on every transient API failure, because the only condition checked was `!isBackendAvailable && !hasLocalData`. A fresh-install mobile user who had just connected to a remote backend (no local notes yet) was thrown back to the connect flow on the first network blip, forcing them to retype their server URL after every action. Track a persisted `hasEverConnected` flag set on the first successful ping. Route to ConnectScreen only when the user has neither ever connected nor has local data. Add `_markBackendAvailable()` so a successful API call after a transient failure auto-clears the offline banner without requiring a manual reconnect. Pre-fill ConnectScreen's URL field with the saved URL so a user who lands there from Settings does not retype. The saved server URL was never cleared by `_handleBackendFailure`, but the routing made it irrelevant — the user got bounced anyway. The combined change keeps the URL persisted, the user on HomeScreen, and the offline banner visible until the next successful call. Tests cover: HomeScreen retention after runtime API failure, URL preservation in SharedPreferences after backend failure, local-only actions never flipping the connection flags, automatic recovery when the backend returns, and cold-start restoration of `hasEverConnected` from prefs.
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
This PR fixes a critical mobile UX issue where transient API failures would bounce users back to the ConnectScreen, forcing them to retype their server URL. The fix introduces persistent connection state tracking so that once a user has successfully connected to a backend, temporary network blips no longer disrupt their session.
Key Changes
Added
hasEverConnectedflag: A new persistent boolean that tracks whether the app has ever successfully reached a backend. This flag is saved to SharedPreferences and restored on cold start, allowing the router to keep users on HomeScreen even when the backend is temporarily unavailable.Auto-recovery from transient failures: Introduced
_markBackendAvailable()method that clears the offline banner as soon as any API call succeeds, allowing the app to auto-recover from transient failures without requiring manual reconnection.Persistent URL handling: Refactored SharedPreferences key usage into named constants (
kPrefsApiUrl,kPrefsHasEverConnected) and ensured the saved server URL persists across failures and cold starts.Updated routing logic: Modified
main.dartto usehasEverConnectedas the primary signal for showing ConnectScreen. Users now only see ConnectScreen on first launch when they have no local data and have never connected—not on every transient failure.ConnectScreen URL pre-fill: Updated ConnectScreen to pre-populate the text field with the previously-entered URL from AppState, reducing friction when users need to retry after a typo or reconnect from Settings.
Comprehensive regression tests: Added a new "mobile session stability" test group with five tests covering:
Implementation Details
_markEverConnected()is called after successful connection and sync operations, with graceful handling of SharedPreferences write failures_markBackendAvailable()is called after every successful API operation to clear the offline statecreateNoteCallsto support testing the connection state transitionshttps://claude.ai/code/session_01PjwxE4tnZuv7aWve2RXGf9