feat: pre-fetch email bodies for offline access #400

Merged
guettlibot merged 1 commits from refs/pull/400/head into main 2026-06-04 04:15:04 +00:00
guettlibot commented 2026-06-04 01:29:41 +00:00 (Migrated from codeberg.org)

Closes #373

Summary

  • Schema v38: two new columns on user_preferencesprefetch_mode (default wifiOnly) and body_cache_limit_mb (default 100 MB).
  • BodyCacheService: queries for emails that have no cached body, fetches them newest-first in batches of 20, and evicts the oldest cached bodies when the configured size limit is exceeded.
  • Separate WorkManager task (si_bg_prefetch): runs hourly with NetworkType.unmetered (Wi-Fi) or NetworkType.connected (any) depending on the user's choice. The task is cancelled when prefetch is disabled.
  • App startup: reads the stored preference from the DB and re-registers the WorkManager task with the correct constraint.
  • Preferences screen: radio group for prefetch mode (Wi-Fi only / Any network / Disabled) and a dropdown for cache size limit (50 / 100 / 200 / 500 MB).

What is NOT downloaded

Binary attachments are never fetched — getEmailBody() stores only textBody and htmlBody. The cache size limit + per-run batch cap (20 emails) keep storage bounded even on large mailboxes.

Test plan

  • task analyze — no issues
  • task test — all 492 tests pass (incl. updated migration_test.dart for v38)
Closes #373 ## Summary - **Schema v38**: two new columns on `user_preferences` — `prefetch_mode` (default `wifiOnly`) and `body_cache_limit_mb` (default 100 MB). - **`BodyCacheService`**: queries for emails that have no cached body, fetches them newest-first in batches of 20, and evicts the oldest cached bodies when the configured size limit is exceeded. - **Separate WorkManager task** (`si_bg_prefetch`): runs hourly with `NetworkType.unmetered` (Wi-Fi) or `NetworkType.connected` (any) depending on the user's choice. The task is cancelled when prefetch is disabled. - **App startup**: reads the stored preference from the DB and re-registers the WorkManager task with the correct constraint. - **Preferences screen**: radio group for prefetch mode (Wi-Fi only / Any network / Disabled) and a dropdown for cache size limit (50 / 100 / 200 / 500 MB). ## What is NOT downloaded Binary attachments are never fetched — `getEmailBody()` stores only `textBody` and `htmlBody`. The cache size limit + per-run batch cap (20 emails) keep storage bounded even on large mailboxes. ## Test plan - [x] `task analyze` — no issues - [x] `task test` — all 492 tests pass (incl. updated migration_test.dart for v38)
Sign in to join this conversation.