Replying to a reply produced "Re: Re: foo" (and German used the English
"Re:"/"Fwd:" instead of "AW:"/"WG:"). Four code paths built reply/forward
subjects and only one deduplicated - and only for the English prefix, so
cross-locale threads accumulated chains.
New lib/subject-prefix.ts strips any leading run of reply/forward markers
across ~35 tokens from all supported languages (plus Outlook Re[2]: and
Eudora Re*2: counters), then prepends the locale-appropriate prefix. All four
call sites (composer getInitialSubject, the two page.tsx sites, and the three
pro-tab handlers) now use buildReplySubject/buildForwardSubject. German prefix
corrected to AW:/WG:.
The reply/forward quote header was always emitted in English ("On {date},
{from} wrote:", "---------- Forwarded message ----------", From/Date/Subject)
regardless of UI language, in both the main path (lib/quote-header.ts) and the
composer's inline fallback. quote-header.ts now takes an optional localized
QuoteHeaderLabels set (English defaults preserved for back-compat); page.tsx
builds it from a new quote_header message namespace, and the composer fallback
uses the same keys. Added the quote_header namespace to all 17 locales.
Also folds in the forward-sender-address fix: the forward "From:" line now
shows the full "Name <email>" like every mail client (the reply line keeps the
bare name, which reads naturally in "On … wrote:").
The global rule
td, th { word-break: break-word; }
was breaking HTML-email tables one glyph per row whenever a column was
narrow, especially for Hebrew/Arabic/CJK headers and long English
strings. The non-standard `word-break: break-word` keyword behaves
like `break-all` in some engines, splitting words at arbitrary
character boundaries even when the word would fit if the column auto-
expanded.
`overflow-wrap: break-word` is already set on body/table, so the rule
only needs to add min-content relaxation for cells. `overflow-wrap:
anywhere` does exactly that without re-introducing break-all
behaviour.
Repro: any transactional Hebrew/RTL order-summary email — each header
(`מוצר`, `כמות`, `מחיר`) collapses to one glyph per row. After the fix
they render on a single line.
Closes#341.
Adds the universal "send with the platform modifier" shortcut every
mainstream mail client (Gmail, Outlook, Apple Mail, Proton, Tutanota,
Fastmail, Thunderbird) supports. Closes#343.
Behaviour:
* Window-level keydown listener registered while the composer is
mounted. Fires when focus is anywhere inside the composer — chip
inputs, subject, body textarea, or the rich-text contentEditable.
* Plain Enter is untouched; only Enter + Ctrl (Win/Linux) or Cmd
(macOS) triggers send. Shift/Alt modifiers are ignored so existing
autocomplete-confirm / chip-commit Enters are not hijacked.
* Routes through a ref so handleSend's per-render rebind doesn't
re-register the listener every render.
* All existing send-time validation, attachment-warning, draft-save
and undo-send flows still apply — the shortcut just calls the
same handleSend() as the toolbar button.
* Listed in the Keyboard Shortcuts dialog under the existing
Composer section.
Tested:
* Compose -> type body -> Ctrl+Enter -> Outbox.
* Cc/Bcc autocomplete suggestion + Enter still selects (alt-free
Enter without Ctrl, so the new listener bails).
* Subject input -> Ctrl+Enter -> sends.
* Body Enter without modifier -> newline.
Parallelize ICS parse with raw blob fetch, render the banner as soon
as parsing returns instead of awaiting the existing-event lookup, and
filter that lookup by UID server-side instead of fetching every event
on the calendar.
Adds an Override toggle in the composer's From row. When enabled, name
and address become free-text inputs. Mail is still submitted through the
selected identity, but the outgoing message's From: header — and the
SMTP envelope MAIL FROM when different — is set from the override.
The existing "Auto-select Reply Address" setting is extended: if the
incoming message was addressed to an alias on a domain that matches one
of your identities but isn't itself an identity (classic domain catch-
all), it now auto-enables Override and pre-fills the alias. Quick reply
honors the same resolution. The setting is relabeled to reflect the
broader behavior.
JMAP: client.sendEmail gains an optional envelopeMailFrom; when set, the
EmailSubmission includes an explicit envelope with that mailFrom and the
to/cc/bcc as rcptTo so header-From and envelope can diverge (JMAP §7.3).
S/MIME: override is incompatible with sign/encrypt and is refused with a
clear error — signing a different visible From from the identity's
certificate Subject would produce messages clients reject.
Tests: resolveReplyFrom covers exact match, sub-address stripping,
catch-all detection, identity preference, and foreign-domain null.