Interface refresh, smarter composer, and templates that remember recipients #59

Merged
jcoffey-dev merged 5 commits from feature/interface-refresh into main 2026-10-20 20:51:58 +00:00
5 Commits
Author SHA1 Message Date
jcoffey-dev 0190262bba Templates remember who they're for
ci / node (pull_request) Skipped
ci / version (pull_request) Skipped
ci / docker-build (pull_request) Skipped
ci / publish (pull_request) Skipped
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 2m56s
A template saved a subject and a body, so a message sent to the same
people every time (an invoice, a weekly report) had to be addressed by
hand each time.

A template can now hold To, Cc and Bcc as well:

- Settings > Templates has the three fields, with the composer's own
  suggestions, and each template's card lists who it adds;
- inserting it adds them to the message beside anyone already there; an
  address already on the message, in any field, isn't added twice, and
  the Cc and Bcc rows open when the template uses them;
- {{recipientName}} and the other placeholders see the template's own
  recipients, so "Dear {{recipientFirstName}}" names the person it's for;
- "Save as template" in the composer keeps the message's recipients.

Templates saved before this have none and insert exactly as they did.

New strings: 5 ("To (optional)", "Cc (optional)", "Bcc (optional)",
"Adds: {recipients}" and the field hint), in all ten catalogs. Turkish
also gains the two strings for the language model's opinion.

Fixes #58
2026-10-20 13:32:31 -07:00
jcoffey-dev d2b3fda9a4 Show the language model's opinion on a message
When Stalwart's AI spam classification is on, the spam filter records the
model's answer in an X-Spam-LLM header: the category it chose and, in
parentheses, its explanation. The full message now asks for it, and where
it's there:

- the message details show "Language model's opinion" beside the spam
  filter's own working, with the category and explanation (and a
  confidence, where the header carries one in the LLM_<category>_<level>
  form);
- a message in Junk carries a banner saying the same.

Both say it's one of several signals the spam filter weighed, never the
reason on its own. The explanation is model output and is only ever
rendered as text. Nothing shows without the header, so a server without
the feature, or with it off, looks as before.

New strings: 2 ("Language model's opinion", "One of several signals the
spam filter weighed"), in nine catalogs; Turkish follows with the rest of
this update's strings.
2026-10-20 13:32:31 -07:00
jcoffey-dev 2002120902 App rail, pill counts, tinted folder icons and raised controls
On a wide screen the switcher moves from the foot of the folder pane to a
rail down the left edge: Mail (with the inbox's unread badge), Calendar,
Contacts and Files, then Settings and the folder-list toggle at the
bottom. The top bar loses the menu button and the Settings gear there,
both now on the rail. Phones are unchanged: no rail, the tab bar, the
menu button for the drawer and the gear.

- Folder counts are pills: filled with the accent when there is unread
  mail, neutral for totals (Drafts, Scheduled).
- Role folders get their own icon tint (Inbox, Drafts, Sent, Archive,
  Junk, Trash, Scheduled); a color the reader picked still wins.
- Buttons, Compose and the current selection have a top-lit, raised look
  with a pressed state; Compose and the selected rail item are filled
  with the accent.
- Collapsing the sidebar keeps Mail's icon strip; Calendar, Contacts,
  Files, Settings and Admin have no icon-only form, so their sidebar
  hides instead of being crushed.
- The collapsed sidebar no longer draws a cut-off "FOLDERS": the rule
  hiding section headings lost to a later one of the same weight (this
  is on main today too).

Contrast: the accent behind small text is darkened in light themes and
lightened a touch in dark ones. Measured in a browser across all 12
palettes x 6 accents x both modes: text on pills, the rail badge and
Compose at least 4.83:1, tinted icons at least 3.14:1 on the sidebar.

New strings: 2 ("Show folder list", "Hide folder list"), in all ten
catalogs.
2026-10-20 13:32:31 -07:00
jcoffey-dev 6e78d748d9 Save the people you write to as contacts
The addresses written to were remembered only in the browser that sent
the message, as a list of recent recipients, so a new device or a cleared
browser suggested nobody. After each confirmed send, the recipients who
are not contacts yet are now saved on the server, in an address book of
their own called Collected, so they are suggested everywhere.

- Only addresses on no card in any address book, own or shared, are
  added, de-duplicated, and never the sender's own identities.
- The book is created on first use and remembered by id in the synced
  settings, so its name can be anything; a deleted one is replaced.
- Names are split as the contact editor does ("Smith, Jane").
- Settings > Calendar & contacts > Contacts has a switch, on by default,
  as mail clients do; the book can be emptied or deleted like any other.

New strings: 3, in all ten catalogs.
2026-10-20 13:32:31 -07:00
jcoffey-dev 4e2de305d3 Composer: smarter suggestions, links over selections, big images attached
Recipient suggestions:
- the words typed match in any order, each one the start of a word in the
  name, a nickname, the organization or the address: "jane smi" finds
  "Smith, Jane", and "globex" finds the people at Globex;
- someone written to lately ranks a little above an equal match;
- an address already in To, Cc or Bcc is no longer offered in the other
  two fields.

Pasting:
- a single web or mailto address pasted over selected words makes those
  words the link, instead of replacing them with the address;
- a pasted or dropped image over 10 MB goes in as an attachment rather
  than inline, where it would swell every reply.

No new strings.
2026-10-20 13:32:31 -07:00