Architecture (Advanced)

Multi-module structure

MonoMail is divided into 13 modules:

:app                        # Main application shell (DI, NavGraph, ActionQueueManager)
:core:model                 # Pure domain models
:core:designsystem          # Theme, typography, shared UI components
:core:database              # Room database, entities, DAOs, migrations
:core:network               # Retrofit APIs, Gmail/Outlook/IMAP providers
:core:data                  # Repository, auth, settings, workers
:core:pgp                   # PGP encryption engine
:feature:auth               # Sign-in screens and ViewModels
:feature:inbox              # Inbox, dock bar, email list
:feature:detail             # Email thread detail screen
:feature:compose            # Email compose screen
:feature:settings           # Settings hub and 11 sub-screens
:feature:attachment         # In-app attachment viewer

Data flow

UI (Compose) -> ViewModel -> EmailRepository -> Room DB (local cache)
                                           -> EmailProvider (Gmail/Outlook/IMAP API)

Writes: UI -> ViewModel -> EmailRepository
  -> update Room DB immediately (optimistic)
  -> insert PendingActionEntity
  -> ActionQueueManager processes pending actions against provider API

Offline-first

The app prioritises the local database:

  1. Reads — always from Room DB via reactive Flow queries. The UI never blocks.
  2. Writes — optimistic: update local DB first, then sync to server via pending actions.
  3. SyncEmailRepository.refreshInbox() fetches from provider and upserts into Room.
  4. Pending actions — if a write fails (network issue), it retries up to 5 times before marking as FAILED.

Security

LayerMechanism
Local databaseSQLCipher encryption (256-bit key, stored in EncryptedSharedPreferences)
Account credentialsAES-GCM via Android KeyStore
IMAP passwordsAES-GCM encrypted strings
PGP private keysArmored file encrypted via SecurityUtil
PGP passphrasesEncrypted blobs on disk
DataStoreEncryptedSharedPreferences (AES256_GCM value encryption, AES256_SIV key encryption)
NetworkRetrofit with Bearer token auth, 401 detection for re-auth

Micro-interactions and animations

MonoMail uses spring physics throughout for tactile feedback. No easing curves — everything bounces naturally.

ElementAnimationSpec
Settings card pressScale to 0.97Spring.DampingRatioMediumBouncy restore
Theme selector tapSelected segment bounces to 1.04xSpring.DampingRatioMediumBouncy + colour tween (250ms)
Dock tab switchAnimated background, icon tint, label widthupdateTransition
Sent overlaySpring scale-in + fade-indampingRatio 0.5, stiffness 300
Loading shimmerSweeping linear gradientInfinite tween(1000ms)
Conversations expand/collapseContent size animationSpring
← Settings Troubleshooting →