Real-time folder-first sync with footer progress bar
Details
Add FoldersSynced event to EmailSyncManager that fires after folder
list is persisted but before message sync begins. This enables the
sidebar to populate immediately with folder structure while messages
sync in the background.
Introduce SyncStatusMessage property on EmailSyncManager that tracks
human-readable sync phase text (Connecting, Syncing folders, Syncing
messages with counts). Add corresponding SyncStatusText and
IsSyncDeterminate properties to EmailViewModel for UI binding.
Move sync progress indicator from above the message list to the
lower-right footer. The footer now shows an indeterminate progress
bar during folder sync phase, switching to a determinate bar with
message count during message sync. When not syncing, the footer
falls back to showing the existing StatusMessage text.
Update OnMessageBatchSynced in EmailPlugin to capture sync state
snapshots (count, total, status) on the background thread before
posting to UI thread, eliminating cross-thread read races.
Wire OnFoldersSyncedAsync in EmailViewModel.MessageActions to reload
folders for the active account when FoldersSynced fires, giving
immediate sidebar feedback after account creation.
Version bump to 1.14.0.
Fix sync order and add offline email body cache (v1.13.0)
Details
Sync order: Changed FetchHeadersBatchedAsync from fire-and-forget
IProgress<T> callback to sequentially awaited Func<T, Task>. Batches
now persist in guaranteed newest-first order. Messages within each
batch and in the incremental sync path are sorted by date descending.
The MessageBatchSynced event now includes EmailAccount and EmailFolder
context for downstream consumers.
Offline body cache: Added EmailBodyCacheService backed by local
filesystem storage under WorkspaceDataPath/email-cache/. Bodies are
device-local and never synced between devices — each device downloads
its own copy directly from the IMAP server. A background Channel-based
download queue processes newly synced message batches (newest first).
The ViewModel checks the local cache before falling back to IMAP for
on-demand body fetches, and caches the result for future offline
access. Cache is cleaned up on account removal.
IMAP connection reuse across sync cycle (v1.12.0)
Details
Add ConnectForSessionAsync to ImapSyncService returning a persistent
ImapClient. Add overloads for SyncFoldersAsync, FetchNewHeadersAsync,
and FetchHeadersBatchedAsync accepting an existing ImapClient. Update
EmailSyncManager.SyncSingleAccountAsync to open one connection at the
start and reuse it across folder sync and message fetch. Reduces
connections from 15+ (one per folder) to 1 per sync cycle. Existing
standalone methods preserved for on-demand operations.
HTML message renderer with sender trust gate (v1.11.0)
Details
Add HtmlSanitizer using HtmlAgilityPack: parses email HTML into safe
RenderBlock records (paragraphs, headings, links, lists, blockquotes,
preformatted text). Strips scripts, styles, iframes, objects, event
handlers, and external images. HtmlMessageRenderer TemplatedControl
renders sanitized HTML as composed Avalonia controls when sender is
trusted, plain text otherwise. Links open in system browser. Trust
banner in ReadingPaneView offers "Trust sender", "Trust domain", and
"Open in Browser" (writes HTML to temp file). Added HtmlAgilityPack
package dependency.
Add sender trust whitelist for HTML content gating (v1.10.0)
Details
Introduce SenderTrustList model (address + domain sets) persisted via
IPluginSettings. SenderTrustService provides IsTrusted, TrustAddress,
TrustDomain, and RevokeTrust operations. ViewModel exposes IsSenderTrusted
computed property updated on message selection, plus TrustSenderCommand
and TrustDomainCommand. Wired into plugin lifecycle. Prepares for HTML
renderer trust gate in next commit.
Get notified about new releases