Skip to content

v2026.3.1

Choose a tag to compare

@github-actions github-actions released this 27 Jul 17:48
· 205 commits to main since this release

Highlights

  • Views can now match on multiple sender and recipient addresses, and support regular expressions for text, from, to and subject.
  • Settings are reorganized into clearer groups with a search box that finds individual settings, not just categories.
  • New offline indicator in the status bar. When there is no connection, sync and the raw-source viewer say "No internet connection" instead of confusing credential or host errors.
  • Unified Inbox and the built-in view names (Inbox, Flagged, Drafts, Sent, and more) are now fully localized.
  • Optional fullscreen empty-state background image for the reading pane, off by default.
  • New "This email" action to load remote content for a single message, remembered across syncs.
  • Polish language support.

Changes

feat: add Polish (pl) locale - @TRC-Loop in #153

Closes #140.

Adds a Polish (pl) locale.

Changes

  • New frontend/src/lib/locales/pl.ts translating every key from en.ts. Key set is at exact parity with en.ts (verified by diff); placeholder tokens ({count}, {who}, {when}, {version}, {n}, {field}, {folder}, {size}, {mailbox}, {author}, {detail}) are preserved verbatim, and technical terms (IMAP, SMTP, OAuth, Gravatar, BIMI, PGP, SPF/DKIM/DMARC, MCP, TLS/SSL/STARTTLS, Markdown, HTML, Vim, proxy) are left untranslated.
  • Registered pl in the i18n loader/selector (Locale type, locales array, localeNames -> "Polski", dynamic import map), so it is selectable in Settings.
  • Extended the Go-side locale tables so Polish users also get native strings: built-in locales set (bind_locales.go), new-mail notifications (notify.go), and the native menu bar (menu_i18n.go).
  • No em-dashes in any string.

Verification

  • pl.ts key set diffs clean against en.ts.
  • go build, go test (internal/desktop), svelte-check and pnpm build all pass.

Note: this is a complete first-pass translation; a native-speaker review pass is welcome as a follow-up.

feat: fullscreen empty-state background toggle - @TRC-Loop in #152

Closes #148.

Adds an option to show the empty-state image as a full-screen background of the reading pane, instead of the small centered mark.

Changes

  • New emptyStateFullscreen boolean preference, off by default.
  • When on (and an empty-state image is set), the reading pane renders that image as a full-bleed cover background when no message is open. Otherwise the existing small, faded, centered mark is unchanged.
  • Toggle added in Settings next to the empty-state image picker; it is disabled until an image is chosen.
  • Wired through backend setting (empty_state_fullscreen), UIPrefsDTO, prefs store + setter, api key, types, and generated bindings.
  • i18n keys added to all five locales (en/de/fr/es/nl).

Verification

  • go build, svelte-check, and pnpm build all clean.
feat: group and rebalance settings categories with per-setting search - @TRC-Loop in #151

Closes #130.

The settings panel had ~20 flat categories with a badly overloaded Appearance section and several near-empty ones. This groups and rebalances them and adds real per-setting search. Every existing setting is preserved, only relocated.

Categories: 24 → 16, grouped under 6 headings

  • Appearance now holds theming only: theme/schedule, accent, density, corners, interface scale, reduce motion, empty-state image.
  • Menu bar (new): the whole macOS menu-bar cluster pulled out of Appearance.
  • Reading & display = Display + Panes + all three font pickers (body/UI/mono moved out of Appearance).
  • Message list = List + Sidebar + Avatars.
  • Composing & sending = Composing + Sending.
  • Privacy & network = Privacy + Network.
  • Accounts = Mailboxes + Contacts.
  • Backup & integrations = External + Import/Export.
  • Sync & power = Power + Offline/download.
  • Unchanged: Themes, Language, Signatures, Notifications, Gestures, Shortcuts, About.

Nav groups: Appearance / Mail / Privacy / Accounts / Advanced / About. Merged sub-groups get a labeled divider so nothing reads as a jumble.

Per-setting search

Typing filters the nav and shows a flat results list of individual settings by their own label (e.g. proxy, gravatar, vim, undo send, swipe, backup), each tagged with the category it lives in; clicking jumps straight there.

Spacing and space

  • Hints now hug the control they describe with a clear gap below, so they read as part of that setting instead of floating between two.
  • Content column widened 560 to 720px.

i18n / verification

  • New keys (groups, per-category keywords, new category labels, Menu bar) added to all five locales (en/de/fr/es/nl), files at parity.
  • Every category key maps 1:1 to a render block; no setting removed.
  • svelte-check clean, pnpm build clean.
feat: multi-address chips and regex matching in views - @TRC-Loop in #150

Closes #149.

Saved views can now filter with multiple sender/recipient addresses and match content with regular expressions.

Changes

  • Multi-address chips for From / To. The single-line from and to inputs are now chip inputs: type an address, press Enter/comma/semicolon (or blur) to add it, remove with backspace or the x. A message matches the field when it matches any chip (OR within the field); fields still AND with each other.
  • Regex toggle. A per-view "Use regular expressions" option treats the text/from/to/subject criteria as regular expressions instead of plain substrings. Invalid patterns are rejected on save; a view whose regex fails to compile at run time matches nothing rather than breaking the sidebar.

Implementation

  • Plain single-address views keep the existing full-text index path (unchanged behavior/perf). Regex or multi-address views take a scan-and-filter path: read the newest messages in scope (capped by maxViewScan), then match in Go. Matches stay capped at maxViewMatches.
  • Storage: new use_regex column (migration 0012); query_from/query_to now hold a newline-separated address list. Existing single-address views load as one-item lists, so nothing breaks on upgrade.
  • Plain matching is case-insensitive substring; regex is matched as written (use (?i) for case-insensitive).
  • i18n keys added to all five locales. Generated Wails bindings updated for the new DTO shape.

Tests

  • internal/desktop/bind_views_test.go: multi-address OR, case-insensitive plain match, regex alternation, invalid-regex rejection, and field ANDing.
  • Full go test ./internal/..., svelte-check, and pnpm build pass.
feat: persistent per-message remote content allow - @TRC-Loop in #154

Closes #136.

Adds a persistent per-message remote-content allow, so a newsletter or receipt you reopen often can render remote images every time without trusting the whole sender or domain.

Approach

Chose option 1 from the issue: a fourth banner action, This email, alongside "Load once" / "This sender" / "This domain". It is non-modal and does not change what "Load once" does (which stays ephemeral).

Changes

  • Backend AllowRemoteForMessage(messageID) records the message in a new remote_allow_messages setting. It is keyed by the RFC Message-ID header (lowercased/trimmed) so the allow survives re-sync, expunge and a changed local row id; when a message has no Message-ID it falls back to local:<row id>.
  • GetMessage now renders remote content when the message is individually allowed: remoteAutoAllow(from) || remoteMessageAllowed(m). The existing global / sender / domain paths are untouched, so privacy defaults (blocked by default) are unchanged and this stays an explicit per-message opt-in.
  • Frontend: new banner button wired to allowRemoteForMessage; on click it persists and renders remote content immediately. New i18n keys added to all five locales (en/de/fr/es/nl). No em-dashes.
  • Generated Wails bindings + api wrapper updated for the new method.

Tests / verification

  • internal/desktop/bind_images_test.go: Message-ID keying and local fallback.
  • go build, go test (internal/desktop), svelte-check and pnpm build all pass.

Full Changelog: v2026.3...v2026.3.1