Thomas GüttlerandClaude Sonnet 4.6 72e2b599bf Fix API mismatches, add Linux desktop entry point, reply prefill
API fixes (against vendored enough_mail 2.1.7):
- listMailboxes() returns List<Mailbox> directly — remove .mailboxes
- Use statusMailbox() for unread/total counts per mailbox
- fetchMessages(MessageSequence.fromAll(), ...) replaces nonexistent
  fetchAllMessages(); fetchMessage() takes isUidSequence flag
- FetchImapResult.messages are already MimeMessages — no need to
  re-parse rawData; use msg.decodeTextPlainPart() / decodeTextHtmlPart()
- msg.hasAttachments() (method) not msg.body?.hasAttachments (field)
- SmtpClient clientDomain = sender domain, not display name; quit()
  instead of nonexistent disconnect(); STARTTLS wrapped in try/catch
- ContentInfo.size is nullable; use a.fileName / a.size getters

Other fixes:
- main.dart: move sync start to initState, not build()
- account_list_screen: remove dead/invalid Riverpod select() code
- account_sync_manager: subscribe to account changes; cancel sub on
  dispose; use Future.any([newMsg, 25-min timeout]) for IDLE
- email_repository: add getEmail(id) to interface + impl
- email_detail_screen: load header + body together via Future.wait;
  reply prefills To/Cc/Subject correctly
- compose_screen + router: thread prefillCc through

Add Linux desktop entry point:
- linux/CMakeLists.txt, main.cc, my_application.h/.cc (GTK3 runner)

Add flake.lock (generated by nix flake update).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 07:51:52 +02:00

SharedInbox License: MIT

IMAP/SMTP email client written in Flutter.

Targets Android, iOS, and Desktop (Linux, macOS, Windows).
Supports multiple accounts — each synced independently via IMAP IDLE.

Design philosophy: offline-first

IMAP/SMTP server
       ↓
  AccountSyncManager  ←→  Drift (SQLite, local DB)
                                   ↓
                             UI (reads only from DB)

The UI never touches the network. The sync engine runs in the background and writes to a local Drift database. Screens observe reactive streams from that DB.

Key packages

Package Role
enough_mail (vendored in packages/) IMAP / SMTP / MIME
drift Local SQLite ORM
flutter_riverpod State management / DI
go_router Navigation

Building

# Install dependencies and run code generation
dart pub get
dart run build_runner build --delete-conflicting-outputs

# Run on desktop
flutter run -d linux   # or macos / windows

# Run on Android / iOS
flutter run

Vendored enough_mail

packages/enough_mail/ is a local copy of enough_mail so it can be modified if needed. It is referenced via a path: dependency in pubspec.yaml.

S
Description
SharedInbox: a Mail User Agent supporting IMAP and JMAP
https://sharedinbox.de/
Readme
8.9 MiB
Languages
Dart 77.1%
HTML 13.4%
Go 2.7%
Shell 2.3%
Python 2.1%
Other 2.3%