Replace the fixed 50-message-per-folder header cap with a background, resumable full-history backfill, and add a user-configurable device-only retention limit that prunes local mail beyond it without ever deleting from the server. - ImapClient.fetchOlderThan pages a folder backwards in bounded batches, locating the boundary by binary search over message numbers (O(log n) tiny UID fetches, memory bounded to one batch). - MailBackfiller + BackfillWorker page each synced folder newest→oldest, persisting a per-folder boundary in a new backfill_progress table so a run interrupted by process death / network loss resumes exactly where it stopped. Runs off the sync mutex, so foreground sync / pull-to-refresh stay responsive. - MailSyncer now reconciles server deletions only within the recent UID window (deleteSyncedInWindowNotIn) instead of wiping everything outside the recent 50, so backfilled history survives each foreground sync. A materialized messages.uid column powers the windowed reconcile and backfill boundary. - Body/attachment prefetch still honours FetchPolicy (headers first). - Per-account count/age overrides (nullable) with a global default; 0 = keep everything (the default, matching #12). - MailPruner + PruneWorker delete local rows beyond the limit (cascading attachment rows + on-disk cache), never issuing a server delete. Deletes are chunked under SQLite's 999-parameter limit. - Precedence with backfill: backfill pauses (does not complete) at the retention floor and both jobs share a maintenance mutex, so they never contend; foreground fetch is also capped by the count so it can't re-download what pruning just trimmed. - Settings UI for the global default and per-account override, with copy making clear it is device-only, not the server. Room schema v9→v10 (migration + exported schema + MigrationTestHelper test). GreenMail tests prove the backfill caches >50 and resumes after interruption; pruning tests cover count/age limits and never touch the server. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -196,6 +196,22 @@
|
||||
<string name="settings_backup_include">Include settings in Android Backup</string>
|
||||
<string name="settings_backup_include_summary">Let Android back up your LibreMail preferences (Google Auto Backup) so they restore when you set up a new device. Your mail, accounts, passwords, and encryption keys are never backed up — only app settings. Off by default; uses Google infrastructure.</string>
|
||||
|
||||
<!-- Storage / retention (device-only; issue #13) -->
|
||||
<string name="settings_retention">Storage on this device</string>
|
||||
<string name="settings_retention_summary">These limits apply to this device only. Mail beyond them is removed from local storage but never deleted from the server, so it can always be downloaded again. By default LibreMail keeps everything.</string>
|
||||
<string name="settings_retention_default">Default for all accounts</string>
|
||||
<string name="retention_count_title">Keep by message count</string>
|
||||
<string name="retention_age_title">Keep by age</string>
|
||||
<string name="retention_use_default">Use the global default</string>
|
||||
<string name="retention_keep_all">Keep everything</string>
|
||||
<string name="retention_count_500">Newest 500 per folder</string>
|
||||
<string name="retention_count_1000">Newest 1,000 per folder</string>
|
||||
<string name="retention_count_5000">Newest 5,000 per folder</string>
|
||||
<string name="retention_age_3m">Last 3 months</string>
|
||||
<string name="retention_age_6m">Last 6 months</string>
|
||||
<string name="retention_age_1y">Last year</string>
|
||||
<string name="retention_age_2y">Last 2 years</string>
|
||||
|
||||
<!-- Per-account settings -->
|
||||
<string name="settings_account_title">Account</string>
|
||||
<string name="settings_signature">Signature</string>
|
||||
|
||||
Reference in New Issue
Block a user