Add AuthStatus.offline and distinguish NetworkException from HTTP 401 in AuthNotifier.verify()
Persist has_ever_logged_in flag; splash lands returning users on the briefing (not login) when the server is unreachable
New OfflineBanner widget with retry button, mounted in _Shell for both narrow and wide layouts
Router redirect updated to treat offline + ever-logged-in as allowed navigation
Why
Previously, if the backend was unreachable at launch, the splash screen routed to the login screen. The server URL stayed in SharedPreferences but visually appeared lost — frustrating for any user who isn't the service operator.
Tier 2 followup
Real offline mode (local store, per-provider last-good caching, edit reconciliation) is tracked as Fable task #147 and is explicitly out of scope for this PR.
Test plan
Launch app with backend reachable, logged-in cookies → briefing opens (no banner)
## Summary
- Add `AuthStatus.offline` and distinguish `NetworkException` from HTTP 401 in `AuthNotifier.verify()`
- Persist `has_ever_logged_in` flag; splash lands returning users on the briefing (not login) when the server is unreachable
- New `OfflineBanner` widget with retry button, mounted in `_Shell` for both narrow and wide layouts
- Router redirect updated to treat `offline + ever-logged-in` as allowed navigation
## Why
Previously, if the backend was unreachable at launch, the splash screen routed to the login screen. The server URL stayed in SharedPreferences but visually appeared lost — frustrating for any user who isn't the service operator.
## Tier 2 followup
Real offline mode (local store, per-provider last-good caching, edit reconciliation) is tracked as Fable task #147 and is explicitly out of scope for this PR.
## Test plan
- [ ] Launch app with backend reachable, logged-in cookies → briefing opens (no banner)
- [ ] Kill backend, relaunch app → briefing opens with offline banner, Retry button responds
- [ ] Fresh install with backend unreachable → login screen (no banner, `has_ever_logged_in = false`)
- [ ] Backend returns 401 on verify → login screen (not offline banner)
This repo is archived. You cannot comment on pull requests.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
AuthStatus.offlineand distinguishNetworkExceptionfrom HTTP 401 inAuthNotifier.verify()has_ever_logged_inflag; splash lands returning users on the briefing (not login) when the server is unreachableOfflineBannerwidget with retry button, mounted in_Shellfor both narrow and wide layoutsoffline + ever-logged-inas allowed navigationWhy
Previously, if the backend was unreachable at launch, the splash screen routed to the login screen. The server URL stayed in SharedPreferences but visually appeared lost — frustrating for any user who isn't the service operator.
Tier 2 followup
Real offline mode (local store, per-provider last-good caching, edit reconciliation) is tracked as Fable task #147 and is explicitly out of scope for this PR.
Test plan
has_ever_logged_in = false)