Today the app opens straight to MAILBOX; with no accounts it shows NoAccountState
(a blank inbox with an "Add account" button) in MailboxScreen.kt. The onboarding epic
replaces that with a guided flow. This ticket builds the navigation skeleton the other
onboarding tickets plug into.
Scope
Add an onboarding route/graph and a welcome screen that invites the user to add
their email accounts (replaces the blank-inbox + "Add account" experience).
Gate the start destination: when there are no accounts, the app opens onboarding
instead of MAILBOX; when accounts exist, it opens MAILBOX as today. Observe the
account count and avoid a flash of the wrong screen on cold start (hold the splash /
render nothing until the count is known).
Own the onboarding-session state that #30 needs (e.g. a nav-graph-scoped ViewModel
or saved-state holder) so the "first account added this session" can be tracked.
Keep "Add account" reachable later from Settings and the mailbox, re-entering the same picker/setup screens (reuse, don't duplicate).
Remove/replace NoAccountState now that onboarding covers the empty case.
Acceptance criteria
Fresh install with zero accounts lands on the onboarding welcome, not a blank inbox.
Launching with >= 1 account still opens the mailbox directly, with no onboarding flash.
Completing onboarding lands on a real inbox (first-account landing handled in #30).
Part of #9.
## Context
Today the app opens straight to `MAILBOX`; with no accounts it shows `NoAccountState`
(a blank inbox with an "Add account" button) in `MailboxScreen.kt`. The onboarding epic
replaces that with a guided flow. This ticket builds the navigation skeleton the other
onboarding tickets plug into.
## Scope
- [ ] Add an onboarding route/graph and a **welcome screen** that invites the user to add
their email accounts (replaces the blank-inbox + "Add account" experience).
- [ ] Gate the start destination: when there are **no accounts**, the app opens onboarding
instead of `MAILBOX`; when accounts exist, it opens `MAILBOX` as today. Observe the
account count and avoid a flash of the wrong screen on cold start (hold the splash /
render nothing until the count is known).
- [ ] Wire the flow shape: welcome → vendor picker (#27) → setup path → "add another?"
(#30) → inbox.
- [ ] Own the onboarding-session state that #30 needs (e.g. a nav-graph-scoped ViewModel
or saved-state holder) so the "first account added this session" can be tracked.
- [ ] Keep "Add account" reachable later from Settings and the mailbox, re-entering the
**same** picker/setup screens (reuse, don't duplicate).
- [ ] Remove/replace `NoAccountState` now that onboarding covers the empty case.
## Acceptance criteria
- Fresh install with zero accounts lands on the onboarding welcome, not a blank inbox.
- Launching with >= 1 account still opens the mailbox directly, with no onboarding flash.
- Completing onboarding lands on a real inbox (first-account landing handled in #30).
## Relevant files
- `app/src/main/kotlin/org/libremail/ui/LibreMailApp.kt` (NavHost, `startDestination`)
- `app/src/main/kotlin/org/libremail/ui/navigation/Routes.kt`
- `app/src/main/kotlin/org/libremail/ui/mailbox/MailboxScreen.kt` (`NoAccountState`)
## Dependencies
Foundational — unblocks #27 and #30.
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.
Part of #9.
Context
Today the app opens straight to
MAILBOX; with no accounts it showsNoAccountState(a blank inbox with an "Add account" button) in
MailboxScreen.kt. The onboarding epicreplaces that with a guided flow. This ticket builds the navigation skeleton the other
onboarding tickets plug into.
Scope
their email accounts (replaces the blank-inbox + "Add account" experience).
instead of
MAILBOX; when accounts exist, it opensMAILBOXas today. Observe theaccount count and avoid a flash of the wrong screen on cold start (hold the splash /
render nothing until the count is known).
(#30) → inbox.
or saved-state holder) so the "first account added this session" can be tracked.
same picker/setup screens (reuse, don't duplicate).
NoAccountStatenow that onboarding covers the empty case.Acceptance criteria
Relevant files
app/src/main/kotlin/org/libremail/ui/LibreMailApp.kt(NavHost,startDestination)app/src/main/kotlin/org/libremail/ui/navigation/Routes.ktapp/src/main/kotlin/org/libremail/ui/mailbox/MailboxScreen.kt(NoAccountState)Dependencies
Foundational — unblocks #27 and #30.