Commit Graph
310 Commits
Author SHA1 Message Date
JMR-devandClaude Opus 4.8 bae25b20f3 feat(onboarding): require GPL-3.0 license agreement as the first screen
Inserts a new LicenseScreen ahead of OnboardingWelcomeScreen as the
onboarding graph's start destination: the user must scroll the full
GPL-3.0 text and tap Agree before reaching anything else, or Decline
to exit the app outright. Acceptance is persisted
(SettingsRepository.licenseAccepted) so a user who agrees but exits
before adding an account isn't asked again, and the
NotificationPermissionEffect() request (#151) stays scoped to
OnboardingWelcomeScreen so it never fires on the license screen.

Closes #172

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 22:56:34 -05:00
Jason Ross 4872d24981 Merge pull request #190 from JMR-dev/feat-156-154-aol-provider
feat(accountsetup): add AOL provider with app-password help and IMAP/SMTP presets
2026-07-02 21:37:38 -05:00
Jason Ross af22467817 Merge main into feat-156-154-aol-provider 2026-07-02 21:26:33 -05:00
Jason Ross 04b856e10c Merge pull request #189 from JMR-dev/feat-74-75-compose-color-highlight
feat(compose): add font color and text highlight to the formatting toolbar
2026-07-02 21:26:02 -05:00
Jason Ross fd80bded67 Merge main into feat-156-154-aol-provider 2026-07-02 21:15:15 -05:00
Jason Ross 2ce2cb39d2 Merge main into feat-74-75-compose-color-highlight 2026-07-02 21:15:14 -05:00
Jason Ross 5826317182 Merge pull request #191 from JMR-dev/test-53-sync-concurrency
test(sync): interleaving tests for the ungated sync↔backfill and sync↔prune pairs
2026-07-02 21:14:46 -05:00
Jason Ross 4f588b8fd1 Merge main into feat-74-75-compose-color-highlight 2026-07-02 21:03:12 -05:00
Jason Ross 4dd2c20053 Merge main into feat-156-154-aol-provider 2026-07-02 21:03:11 -05:00
Jason Ross cf274781bd Merge main into test-53-sync-concurrency 2026-07-02 21:03:10 -05:00
Jason Ross 33c826b7ec Merge pull request #188 from JMR-dev/perf-186-message-open
perf(reader): render message body once, move openMessage IO off-main, drop wasted work
2026-07-02 21:02:42 -05:00
JMR-devandClaude Opus 4.8 b4a450a8b8 test(sync): interleaving tests for the ungated sync↔backfill and sync↔prune pairs
MailMaintenanceGate serializes only the backfill↔prune pair. The other two
pairs — sync↔backfill and sync↔prune — are deliberately ungated (foreground
sync uses its own syncMutex to stay UI-responsive) and rely on a disjoint-by-UID
argument for safety, with no test covering it (issue #53).

Add MailSyncConcurrencyTest: a real MailSyncer and a real MailBackfiller/
MailPruner wired to one shared in-memory message store, with CompletableDeferred
gates (mirroring MailMaintenanceGateTest) that park one actor mid-critical-
section while the other's whole critical section runs. Each interleaving is
driven to the boundary (window edge / count floor) where an overlap would
surface as a lost, duplicated, or wrongly-deleted row:

- sync's windowed reconcile runs while a backfill is parked mid-paging just
  below the window (tightest edge: lowestSyncedUid == minWindowUid);
- a backfill's below-window page lands after a concurrent full sync of the
  window (stale-boundary ordering);
- a count-retention prune runs while a foreground sync is parked in its fetch;
- a full foreground sync runs while a prune is parked inside its critical
  section, before it touches the message table.

All four pass: the disjointness invariant holds unlocked. No production code
changed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 21:00:23 -05:00
JMR-devandClaude Opus 4.8 ef43dc9a79 feat(accountsetup): add AOL provider with app-password help and IMAP/SMTP presets
Adds MailProvider.AOL as a guided app-password provider (after iCloud, before
Other), closing the coupled pair of #156 (app-password help content) and #154
(IMAP/SMTP presets):

- appPasswordHelpUrl points at AOL's "Create and manage 3rd-party app
  passwords" article. No twoFactorHelpUrl: verified against both AOL's
  app-password article and its separate two-step-verification article that
  neither treats 2FA as a prerequisite for generating an app password (AOL
  mirrors Yahoo here, not Gmail/iCloud).
- IMAP imap.aol.com:993 (SSL/TLS); SMTP smtp.aol.com:465 (SSL/TLS) — AOL's
  official docs and the Thunderbird ISPDB autoconfig only document implicit
  TLS on 465 for submission, with no STARTTLS/587 alternative, so this
  follows Yahoo's rationale rather than Gmail/iCloud's STARTTLS preset.

AppPasswordSetupScreen's two exhaustive `when` blocks (providerIntro,
twoFactorHelpLabel) gain an AOL branch; AccountPickerScreen already lists
providers generically via MailProvider.entries. Test coverage mirrors the
Yahoo/iCloud assertions: presets, help URLs, no twoFactorHelpUrl, fromKey,
forImapHost, and brandFor resolving a manually-configured imap.aol.com
account to the AOL brand.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:59:17 -05:00
JMR-devandClaude Opus 4.8 5120d65793 feat(compose): add font color and text highlight to the formatting toolbar
Wire the previously-unused ColorSwatchRow into the compose FormattingToolbar
with two new controls: a font-color button applying RichStyle.FontColor and a
highlight button applying RichStyle.Highlight over the selection. Each opens a
ColorPickerDialog built on the shared ColorSwatchRow (~8 font colors; yellow /
green / cyan / pink highlighter markers), with a "no color"/"none" entry that
clears the style outright via a new clearStyle op. Buttons reflect the current
selection's color and carry accessible onClickLabels; swatches carry their own
contentDescriptions.

Closes #74
Closes #75

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:52:09 -05:00
Jason Ross 92c97a386b Merge main into perf-186-message-open 2026-07-02 20:43:31 -05:00
Jason Ross 62c9279700 Merge pull request #185 from JMR-dev/feat-155-yahoo-app-password
feat(accountsetup): add Yahoo app-password/2FA help in onboarding
2026-07-02 20:43:02 -05:00
JMR-devandClaude Opus 4.8 aafb4f8f6a perf(reader): render message body once, move openMessage IO off-main, drop wasted work
Follow-up to #148: opening an already-cached message was still slow. Three fixes
on the cached-open critical path (issue #186).

Fix 1 - WebView renders once. The reader resolved cid: inline images AFTER the
first render, so the AndroidView update key (which included inlineImages.keys)
changed and reloaded the whole document a second time for any inline-image email.
ReaderViewModel now resolves inline images and folds them into the SAME state
update as the body, and HtmlBody drops inline images from the reload key, so the
WebView loads exactly once and a late inline-image change never reloads. The
WebView is also destroyed onRelease so it (and its Context) is not leaked.
Pool/pre-warm is left as a TODO (leak-prone; single-render is the dominant win).

Fix 2 - openMessage does no wasted work for a cached, already-read message. Added
a body-less MessageRouting projection (mirrors MessageSummary, no migration);
the routing/flag callers (openMessage's first read, downloadAttachment, setStarred,
deleteMessage, expunge, moveByRole/moveToFolder, buildReplyDraft, prefetchMessage)
route on it, and getById (SELECT *) is reserved for the single read that returns
the body. imapParamsFor (Keystore decrypt + DataStore read) is resolved lazily,
only in the fetch / SEEN-push branches; the cached+read path also skips the
account lookup. De-duped the inlineImages attachment N+1 via a shared
ensureAttachmentFile helper that takes the already-resolved account/folder.

Fix 3 - repository IO off the main thread. openMessage, inlineImages,
downloadedAttachmentParts, and downloadAttachment now run in
withContext(Dispatchers.IO), so their DB/file/crypto work no longer runs on the
Main.immediate viewModelScope during the open animation.

Reader behavior (content, read/SEEN semantics) is unchanged; does not touch the
async SEEN network push handled separately by #170.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:33:07 -05:00
Jason Ross 046c21cdaa Merge main into feat-155-yahoo-app-password 2026-07-02 20:32:49 -05:00
Jason Ross 5ee1cbeecf Merge pull request #184 from JMR-dev/feat-71-strikethrough
feat(compose): add strikethrough to the formatting toolbar
2026-07-02 20:32:20 -05:00
Jason Ross ec88548f25 Merge main into feat-71-strikethrough 2026-07-02 20:21:11 -05:00
Jason Ross 1d63d6c7e1 Merge pull request #170 from JMR-dev/fix-148-async-seen-flag
fix(reader): propagate SEEN flag off the message-open critical path
2026-07-02 20:20:36 -05:00
Jason Ross ecbc052389 Merge main into fix-148-async-seen-flag 2026-07-02 20:08:15 -05:00
Jason Ross 455948774d Merge main into feat-155-yahoo-app-password 2026-07-02 20:08:14 -05:00
Jason Ross 0d0bb0d8fe Merge main into feat-71-strikethrough 2026-07-02 20:08:13 -05:00
Jason Ross 421f113349 Merge pull request #178 from JMR-dev/feat-162-advanced-settings-hierarchy
feat(settings): reorder the Advanced settings section
2026-07-02 20:07:42 -05:00
Jason Ross 31771e3a4e Merge main into feat-71-strikethrough 2026-07-02 19:56:24 -05:00
Jason Ross 49e22d1873 Merge main into feat-155-yahoo-app-password 2026-07-02 19:56:22 -05:00
Jason Ross 228ea83288 Merge main into feat-162-advanced-settings-hierarchy 2026-07-02 19:56:22 -05:00
Jason Ross 0ef26da933 Merge pull request #173 from JMR-dev/feat-150-battery-deeplink
feat(onboarding): deep-link battery step nearer the per-app background-activity screen (best-effort)
2026-07-02 19:55:54 -05:00
Jason Ross d3f0ca46dd Merge main into feat-155-yahoo-app-password 2026-07-02 19:44:32 -05:00
Jason Ross 73f69c5326 Merge main into feat-150-battery-deeplink 2026-07-02 19:44:32 -05:00
Jason Ross aff7133bbb Merge main into feat-162-advanced-settings-hierarchy 2026-07-02 19:44:31 -05:00
Jason Ross 47b7efade7 Merge main into fix-148-async-seen-flag 2026-07-02 19:44:29 -05:00
Jason Ross 6a3b3d5a92 Merge main into feat-71-strikethrough 2026-07-02 19:44:29 -05:00
Jason Ross e22e6c14dd Merge pull request #175 from JMR-dev/feat-163-default-account
feat(settings): let the user set a default mail account
2026-07-02 19:44:01 -05:00
Jason Ross bd1f09fc06 Merge main into feat-71-strikethrough 2026-07-02 19:33:18 -05:00
Jason Ross 565a4ebfa8 Merge main into fix-148-async-seen-flag 2026-07-02 19:33:17 -05:00
Jason Ross d6100462a7 Merge main into feat-163-default-account 2026-07-02 19:33:16 -05:00
Jason Ross 56a6776f67 Merge main into feat-162-advanced-settings-hierarchy 2026-07-02 19:33:15 -05:00
Jason Ross 96fb91ce8c Merge main into feat-150-battery-deeplink 2026-07-02 19:33:13 -05:00
Jason Ross 7b2bef32fc Merge main into feat-155-yahoo-app-password 2026-07-02 19:33:12 -05:00
Jason Ross 7d92aa6feb Merge pull request #181 from JMR-dev/fix-157-notification-open-message
fix(notifications): reliably open the tapped message from a new-mail notification
2026-07-02 19:32:42 -05:00
JMR-devandClaude Opus 4.8 6ff988aaec feat(accountsetup): add Yahoo app-password/2FA help in onboarding
Yahoo's guided app-password setup pointed appPasswordHelpUrl at the
generic account-security sign-in page, which assumes the user already
knows to hunt for "Create app password" once there. Point it instead at
Yahoo's own step-by-step "Generate and manage 3rd-party app passwords"
article, mirroring what #153 did for iCloud.

Yahoo does NOT gate app-password creation behind two-step verification
(verified against Yahoo's live help docs, which never list it as a
prerequisite), so — unlike Gmail and iCloud — it keeps twoFactorHelpUrl
null and shows no 2FA button. AppPasswordSetupScreen already renders the
help buttons generically from these provider fields, so no screen change
is needed; the existing PR #152 ordering (2FA link before the
app-password link) is preserved for the providers that have both.

Add a MailProviderTest assertion pinning Yahoo's new app-password URL
(mirroring the iCloud test) and extend the onboarding
yahooSetup_hasNoTwoFactorHelpLink coverage note for #155.

Closes #155

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 19:25:24 -05:00
Jason Ross 52d99d2bf9 Merge main into feat-150-battery-deeplink 2026-07-02 19:21:15 -05:00
Jason Ross 41d06c5c77 Merge main into fix-157-notification-open-message 2026-07-02 19:21:13 -05:00
Jason Ross 5eebe2e2b1 Merge main into feat-162-advanced-settings-hierarchy 2026-07-02 19:21:12 -05:00
Jason Ross d4412ce5f3 Merge main into feat-163-default-account 2026-07-02 19:21:11 -05:00
Jason Ross e2ab1b8953 Merge main into fix-148-async-seen-flag 2026-07-02 19:21:10 -05:00
Jason Ross 64918731eb Merge main into feat-71-strikethrough 2026-07-02 19:21:09 -05:00
Jason Ross 66534d6a0e Merge pull request #183 from JMR-dev/feat-159-report-required-email
feat(reporting): require a reply-to email and a 200-char minimum on problem reports
2026-07-02 19:20:14 -05:00