- t(key, vars) interpolates {placeholders}; numeric count picks a CLDR plural variant
- createTranslator(locale) shares the translator with server code
- registry entries accept dir: "rtl"; layout and provider set <html dir>
- DialogContent translates its close label itself (closeLabel stays an override)
- memoize the language context value, merge double map in dashboard-nav
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Stub the DOM-only email HTML module in the recipient-display test bundle,
since css-tree/parse5 do not bundle for node. Add contain:paint to the
reader host so fixed/absolute email CSS cannot cover the app UI.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- IMAP import: walk a folder newest-first in batches of up to 100 via an
`offset` / `nextOffset` pair, so folders with more than 100 messages can be
imported completely. The import page loops until every folder is done and
shows progress. The per-request limit stays at 100 (default 100).
- IMAP import: recognise iCloud `Sent Messages` and `Deleted Messages`.
- Agent model list: use `redirect: "manual"` instead of `"error"` so
providers that redirect do not fail the request with a generic error.
- Domains: require typing the hostname before removing a domain, since
removal deletes the domain's mailboxes and all their messages.
- Add tests for the batch selection helper.
Adds a "Delete forever" action and an "Empty Trash"/"Empty Spam" button so
mail can be removed for good from the web UI (closes#68, part 1).
- Bulk action "delete" only destroys messages already in Trash or Spam
- POST /api/messages/empty empties a mailbox's Trash or Spam in batches
- Message view: the delete button becomes "Delete forever" in Trash/Spam
- Every removal deletes R2 objects and writes an email.delete audit entry
The domain rule dialog submits its whole form state, so "Deliver to
mailbox" and "Reject / block" rules arrive with forwardTo: "". The
schema only allowed an email or null, so those requests failed with a
400 that the dialog shows as "Request failed". This blocked creating
the "*" catch-all, editing such rules, and toggling them on or off.
Treat a blank forwardTo as null. Forward rules still require a valid
address through the existing superRefine check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Inbound To no longer says "me". To, Cc, and Bcc show the mailbox
address. A switch on the signed-in user, under Settings → Inbox,
shows Name <user@domain.tld> when the header includes a display name.