feat(onboarding): first-run flow, vendor picker, and app-password setup

Implements the onboarding epic (#26–#31) as a single feature:

- #26 First-run nav scaffold: gate the start destination on the account
  count (no accounts -> onboarding, else mailbox) via AppViewModel, holding
  render until the count is known so there is no cold-start flash. Onboarding
  is a nested nav graph with a graph-scoped OnboardingViewModel tracking the
  first account added this session. Removes NoAccountState in favour of a
  shared welcome/empty state.
- #28 Provider registry: MailProvider presets for Gmail/Yahoo/iCloud
  (IMAP+SMTP host/port/security, help URL) mirroring Account.outlook, biased
  to STARTTLS where documented; host/port/security unit-tested.
- #27 Vendor picker: AccountPickerScreen replaces the two-button setup screen
  as the single entry point (onboarding + Settings/mailbox "Add account"),
  routing Outlook -> OAuth, Gmail/Yahoo/iCloud -> app-password, Other -> manual.
- #29 App-password guided screen: one reusable screen per provider key with
  explanation + security warning + help link; verifies/persists via
  addImapAccount. ViewModel unit tests cover valid/invalid/failure paths.
- #30 "Add another?" prompt + first-account landing: after each onboarding
  add, offer Yes (back to picker) / No (open the first account's inbox,
  per-account filtered via a MAILBOX account nav arg). Only inside onboarding.
- #31 Instrumented onboarding E2E (welcome -> picker -> app-password add ->
  add-another -> first inbox); managed-device list and CI matrix already in
  lockstep. All new files carry the SPDX header.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 00:13:32 -05:00
co-authored by Claude Opus 4.8
parent 64fb82ebd9
commit e2e2c36d1d
23 changed files with 1450 additions and 96 deletions
+29 -5
View File
@@ -30,8 +30,6 @@
<string name="search_hint">Search mail</string>
<string name="search_no_results">No results</string>
<string name="mailbox_pull_to_refresh">Pull down to refresh</string>
<string name="mailbox_welcome_title">Welcome to LibreMail</string>
<string name="mailbox_welcome_subtitle">Add an account to start reading your mail.</string>
<!-- Mailbox multi-select contextual action bar -->
<string name="cab_selected_count">%1$d selected</string>
@@ -102,10 +100,36 @@
<string name="attachment_download_failed">Couldn\'t download %1$s</string>
<string name="attachment_no_app">No app can open this file</string>
<!-- Account setup -->
<string name="account_setup_outlook">Sign in with Microsoft</string>
<!-- Onboarding -->
<string name="onboarding_welcome_title">Welcome to LibreMail</string>
<string name="onboarding_welcome_subtitle">A private, open-source home for all your email. Add your first account to get started.</string>
<string name="onboarding_add_account">Add an email account</string>
<string name="onboarding_account_added_title">Account added</string>
<string name="onboarding_add_another_prompt">Would you like to add another email account?</string>
<string name="onboarding_add_another_yes">Add another account</string>
<string name="onboarding_add_another_no">No, take me to my inbox</string>
<!-- Account setup (vendor picker) -->
<string name="account_setup_outlook">Outlook or Hotmail</string>
<string name="account_setup_other">Other (IMAP/SMTP)</string>
<string name="account_setup_subtitle">Choose how you want to connect your mailbox.</string>
<string name="account_setup_subtitle">Choose your email provider to get started.</string>
<!-- App-password guided setup (Gmail/Yahoo/iCloud) -->
<string name="app_password_title">Connect %1$s</string>
<string name="app_password_unknown_provider">Unknown email provider.</string>
<string name="app_password_intro_gmail">To connect Gmail, create an app password in your Google Account. Gmail requires 2-Step Verification to be turned on before you can create one.</string>
<string name="app_password_intro_yahoo">To connect Yahoo Mail, generate an app password from your Yahoo Account security settings.</string>
<string name="app_password_intro_icloud">To connect iCloud Mail, create an app-specific password from your Apple ID account page.</string>
<string name="app_password_what_is">An app password is a one-off password that lets an app sign in to your account without your main password or a two-factor code.</string>
<string name="app_password_warning">Store this app password carefully — it grants full access to your email. LibreMail keeps it only on this device.</string>
<string name="app_password_open_page">Create an app password for %1$s</string>
<string name="app_password_open_failed">Couldn\'t open your browser</string>
<string name="app_password_email">Email address</string>
<string name="app_password_field">App password</string>
<string name="app_password_show_servers">Server settings</string>
<string name="app_password_server_imap">Incoming (IMAP): %1$s:%2$d (%3$s)</string>
<string name="app_password_server_smtp">Outgoing (SMTP): %1$s:%2$d (%3$s)</string>
<string name="app_password_test_and_add">Test &amp; add account</string>
<!-- Manual IMAP/SMTP setup -->
<string name="manual_setup_title">IMAP / SMTP</string>