Commit Graph
120 Commits
Author SHA1 Message Date
Linus Rath 35be105a73 fix: size small text in rem so it follows the browser and app text size 2026-10-29 19:38:45 +01:00
Linus Rath f43eb9f41a fix: give chip remove buttons, tree expanders, task circles and month events a 24px target 2026-10-29 19:38:45 +01:00
Linus Rath 9f6c7b99c9 fix: raise text contrast to 4.5:1 in every built-in theme, light and dark 2026-10-29 19:38:45 +01:00
Linus Rath 1111dd6709 fix: show the focus outline on menu items, grid cells and other roving-focus controls 2026-10-29 19:38:44 +01:00
Linus Rath cf4d02b49b feat: draw calendar, tag and folder colours in a colour-blind-safe palette when that setting is on 2026-10-29 17:53:51 +01:00
Linus Rath f23784a488 feat: open submenus, previews and the rail peek only on click when hover opening is off 2026-10-29 17:53:37 +01:00
Linus Rath 7c282f1f40 fix: say which folder is open and how many are unread in the folder lists 2026-10-29 17:53:36 +01:00
Linus Rath dcc504fcfa feat: add landmarks, an h1 per app, skip links and F6 between panes 2026-10-29 17:53:35 +01:00
Linus Rath 368acca121 fix: stop app shortcuts from acting behind open dialogs and menus 2026-10-29 17:53:33 +01:00
Linus Rath 96797597c5 Merge branch 'main' into feat/org-features 2026-10-28 15:14:34 +01:00
Linus Rath 9eaf7ca754 fix: show the full folder name as a tooltip when the sidebar cuts it 2026-10-28 10:59:44 +01:00
Linus Rath 62169427b9 fix: tint the sidebar's folder icons from theme tokens instead of fixed hues 2026-10-28 10:58:02 +01:00
Linus Rath 26d9fadc50 feat: count shared tags per group and open their tag view in that group only 2026-10-28 08:58:23 +01:00
Linus Rath ed9fa2de45 feat: offer Undo after a move to another account and in lists that mix accounts, moving the messages back into their folders 2026-10-28 08:06:45 +01:00
Linus Rath 528450db61 fix: name the edit button of a shared tag after the tag, not the list 2026-10-28 07:10:42 +01:00
Linus Rath 92815cc0ab fix: keep opening a message as cheap as before: mount Mail's new dialogs, the selection bar and the folder options button only when they show 2026-10-28 06:48:00 +01:00
Linus Rath b049b6f470 feat: share tag names and colours in group mailboxes #1310 2026-10-28 06:43:46 +01:00
Linus Rath b65b7b07d6 fix: give Mail's small controls on the phone a 44px touch target and a name: folder chevrons, search clear, recipient and attachment remove 2026-10-28 06:26:30 +01:00
Linus Rath d17277fab2 fix: point Mail's arrows, indents and panels the right way in right-to-left languages, and keep English subjects and sizes readable there 2026-10-28 05:16:29 +01:00
Linus Rath 43dd87b301 Merge branch 'main' into ux/mail 2026-10-28 05:16:28 +01:00
Linus Rath 91446a807c fix: make the mail list easier by keyboard: a skip link, named row checkboxes, hover actions on focus, no hidden or nested buttons 2026-10-28 05:16:08 +01:00
Linus Rath a62317ba63 fix: translate the shell's resize, close, folder count and update labels, and announce a waiting update on the admin entry 2026-10-28 04:06:12 +01:00
Linus Rath 1386b12908 fix: open Out of Office from the vacation banner instead of the last settings page 2026-10-28 03:43:51 +01:00
Linus Rath 2c808b0990 fix: open a folder's actions on the phone with a long-press or its options button 2026-10-28 03:25:49 +01:00
Linus Rath 6c5aead20b feat: undo a delete to Trash, archive, move, spam report or remove from folder from its toast 2026-10-28 03:11:43 +01:00
Linus Rath cf2c27157d Merge branch 'main' into feat/stalwart-1.0
# Conflicts:
#	components/contacts/contacts-app.tsx
#	components/email/__tests__/composer-discard.test.tsx
#	components/email/calendar-invitation-banner.tsx
#	components/email/email-composer.tsx
#	components/mail/mail-app.tsx
#	components/pro/pro-compose-tab-body.tsx
#	components/pro/pro-email-tab-body.tsx
#	components/ui/__tests__/avatar.test.tsx
#	components/ui/avatar.tsx
#	hooks/use-mailbox-drop.ts
#	lib/__tests__/calendar-alerts.test.ts
#	lib/__tests__/jmap-calendar-tasks.test.ts
#	lib/__tests__/jmap-send-threading.test.ts
#	lib/demo/demo-client.ts
#	lib/demo/fixtures/calendars.ts
#	lib/jmap/client-interface.ts
#	lib/jmap/client.ts
#	lib/web-push.ts
#	stores/__tests__/contact-store.test.ts
#	stores/__tests__/email-store-thread-key.test.ts
#	stores/calendar-store.ts
#	stores/contact-store.ts
#	stores/email-store.ts
2026-10-26 10:14:12 +01:00
Jacob ZeitzandClaude Opus 5.5 96526c1b41 feat: admin policy gate to list the Tags above the shared mailboxes
A new feature gate, tagsAboveSharedEnabled (default off, so the sidebar
keeps its order), lists the Tags section above the shared mailboxes
instead of below them. With many shared mailboxes expanded, the tags
otherwise end up out of sight. In Mountain View the tags then follow the
Labels list directly, also when More is open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:54:23 +02:00
Linus Rath 401d49471e feat: let settings links name a section and add a jump row to each page 2026-10-19 18:14:01 +02:00
Linus Rath 4c0017d0c1 feat: rework the demo around one persona with two accounts and a shared mailbox
The demo user becomes Nora Lindqvist, engineering lead at Meridian Labs,
in the week of a product launch. The fixtures tell one story across mail,
contacts, calendar, tasks and files, and exercise the features the
screenshots and the public demo should show:

- a second, mail-only login (her personal domain) and the shared Support
  mailbox delegated to the work account, so the account switcher, the
  shared section and the merged inbox have real content
- raw headers the way Stalwart writes them: the sender check fails on
  the phishing mail, newsletters carry a one-click unsubscribe, one mail
  asks for a read receipt, and spam scores show in the details
- an iMIP invitation with a served .ics, an event waiting for the answer
  on the calendar, and RSVP patches applied in the demo client
- @mentions as mailto links in a received mail, a verification code
  twelve minutes old, nested folders, named tags on the mail, contact
  groups, a scheduled message and tasks switched on
- every attachment and file backed by real bytes under public/demo,
  generated by `scripts/demo-assets/generate.mjs`; contact photos are
  bundled portraits instead of requests to randomuser.me
- folder counts computed from the mail instead of hand-kept numbers

Demo login seeds the tags, templates and merged-inbox settings once per
device and switches the cross-account gate on for the session; "Reset"
restores them. `bulwark-demo-simulate=off` in localStorage stops the
simulated incoming mail for screenshot runs.
2026-10-18 19:48:11 +02:00
Linus Rath edf675b2f4 feat: list your own folders in a separate section of the sidebar #1205 2026-10-17 19:18:22 +02:00
Linus Rath 1c3cc35a7c feat: set the counter per folder, e.g. keep the Drafts count with totals off #982 2026-10-17 19:18:16 +02:00
Linus Rath 41a0716c50 Merge branch 'main' into feat/stalwart-1.0 2026-10-16 01:41:48 +02:00
Linus Rath dd2104cdda feat: mute notifications for single folders or whole accounts #1169 2026-10-15 21:50:08 +02:00
Linus Rath 84a53e9ea3 perf: stop re-rendering the folder sidebar when a message opens 2026-10-15 02:20:56 +02:00
Linus Rath b59e3520f8 perf: stop re-rendering the message rows and mail view on unrelated store changes 2026-10-15 00:00:28 +02:00
Linus Rath 93c40024d9 fix: show user folders named like system folders with the plain folder icon #1235 2026-10-14 22:57:57 +02:00
Linus Rath 37846bec44 feat: let plugins add collapsible sections to the mail sidebar 2026-10-14 04:45:24 +02:00
Linus Rath 3788446271 feat: let users hide shared mail accounts from the sidebar #1228 2026-10-13 15:55:54 +02:00
Linus Rath c633185cda Merge branch 'main' into feat/stalwart-1.0
# Conflicts:
#	CONTRIBUTING.md
#	LICENSE
#	README.md
#	app/api/calendar-agenda/route.ts
#	app/api/wopi/files/[fileId]/contents/route.ts
#	app/api/wopi/launch/route.ts
#	components/calendar/calendar-app.tsx
#	components/calendar/calendar-day-view.tsx
#	components/calendar/calendar-month-view.tsx
#	components/calendar/calendar-week-view.tsx
#	components/calendar/event-modal.tsx
#	components/contacts/contact-detail.tsx
#	components/email/email-composer.tsx
#	components/email/email-list.tsx
#	components/files/file-browser.tsx
#	components/files/files-app.tsx
#	components/files/folder-tree-sidebar.tsx
#	components/filters/filter-rule-modal.tsx
#	components/mail/mail-app.tsx
#	hooks/use-mailbox-drop.ts
#	integration/run-tests.sh
#	lib/__tests__/calendar-agenda-route.test.ts
#	lib/__tests__/jmap-draft-lifecycle.test.ts
#	lib/__tests__/web-push.test.ts
#	lib/account-state-manager.ts
#	lib/jmap/client-interface.ts
#	lib/jmap/client.ts
#	lib/jmap/types.ts
#	lib/message-list-order.ts
#	lib/sieve/generator.ts
#	lib/sieve/parser.ts
#	lib/telemetry/payload.ts
#	lib/thread-utils.ts
#	lib/unified-mailbox.ts
#	lib/web-push.ts
#	lib/wopi/token.ts
#	locales/ar/common.json
#	locales/ca/common.json
#	locales/cs/common.json
#	locales/da/common.json
#	locales/de/common.json
#	locales/en/common.json
#	locales/es/common.json
#	locales/fa/common.json
#	locales/fr/common.json
#	locales/he/common.json
#	locales/hu/common.json
#	locales/it/common.json
#	locales/ja/common.json
#	locales/ko/common.json
#	locales/lv/common.json
#	locales/mn/common.json
#	locales/nb/common.json
#	locales/nl/common.json
#	locales/pl/common.json
#	locales/pt/common.json
#	locales/ro/common.json
#	locales/ru/common.json
#	locales/sk/common.json
#	locales/tr/common.json
#	locales/uk/common.json
#	locales/zh-TW/common.json
#	locales/zh/common.json
#	scripts/lite/lib.mjs
#	stores/__tests__/calendar-store-synthetic-ids.test.ts
#	stores/__tests__/email-store-shared-folder-keywords.test.ts
#	stores/__tests__/email-store-unified-actions.test.ts
#	stores/__tests__/file-store.test.ts
#	stores/email-store.ts
#	stores/file-store.ts
#	stores/message-list-tabs-store.ts
2026-10-12 08:35:08 +02:00
Linus Rath cf558e7e9f feat: lay out Mountain View's navigation like Gmail's, with a Labels section 2026-10-12 00:46:48 +02:00
Linus Rath ae151cec25 feat: set Mountain View's content on a rounded card over a tinted canvas 2026-10-12 00:37:59 +02:00
lucamzanon 26ae483577 fix(mountain-view): let the collapsed rail fill its 72px column
With the navigation collapsed, Mountain View gives the sidebar a 72px
column, but the sidebar inside kept the default layout's 48px width. The
round compose button was cut in half, the selected folder's highlight
ran off the edge, and an empty strip showed before the message list.
2026-10-11 13:30:11 +02:00
lucamzanon 7c35ed360f fix(mountain-view): labels, selection and controls that did not match
- The refresh button was labelled "Loading" and the overflow menu
  "Mark folder as read"; they now say Refresh and More actions.
- The Starred row stayed highlighted while a tag was open, and its icon
  ignored the colourful-icons setting.
- Reply, Reply all and Forward use the standard small button size.
- With a single login the account popover offers one Sign out pill
  instead of a pill-less footer row.
- The compose backdrop matches the other dialogs.
- Layout settings hide the mail layout and toolbar label options, which
  do nothing under Mountain View; their values still apply to the
  default layout.
2026-10-09 08:27:01 +02:00
lucamzanon d632956231 feat: add Mountain View, an optional alternative layout
Add an "Interface layout" setting at the top of Settings > Layout with two
options, Default and Mountain View. Default is the existing layout and stays
the default, so nothing changes unless a user opts in.

Mountain View rearranges the chrome while keeping the theme's colours, icons
and type:

- desktop: a top bar with a wide search field (filters drop from the field),
  an apps grid and the account avatar instead of the left app rail; flat
  navigation with Starred under Inbox and the rest behind "More"; a Compose
  pill; one list toolbar with select-all, refresh, overflow menu, a 1-N of
  total range and the batch actions; rows led by a checkbox and a star; an
  icon-only message toolbar with Reply / Reply all / Forward under the
  message; compose in a docked window; an account popover with per-account
  unread counts; j/k cursor, x to select and g-sequences
- phone: rounded search header, compact rows with the star on the preview
  line, and Reply / Reply all / Forward at the end of a message instead of
  the bottom action bar

It is one setting (`interfaceLayout`), written to a data attribute on <html>
that keys a block of CSS tokens in globals.css, plus a few components gated
on the flag. The mail layout in force is derived (effectiveMailLayout), so
the user's saved mail layout is never rewritten. The setting is listed in
the admin policy tab, and the new strings are translated in all locales.

Includes unit tests and a Playwright smoke test against a running instance
(scripts/mountain-view-smoke/).
2026-10-05 10:36:20 +02:00
Linus Rath e5755c821a fix: give the unified loading count a screen-reader label that is read #1140
An aria-label on a plain span is not reliably read out, so the count
now comes with a visually hidden label and the digits themselves are
hidden from screen readers. Also reuses the sidebar's existing accounts
selector instead of subscribing to the same list twice.
2026-10-01 11:00:20 +02:00
lucamzanon 717f18fc46 feat(unified): say how many accounts the unified mailbox holds while logins reconnect
After a load the logins other than the one on screen reconnect in the
background, and until they are all back the unified counts cover only
some of them. With many logins that lasts seconds, and a partial total
looks exactly like the whole one.

While that restore runs, the "All accounts" header shows how many logins
are already in the scope, e.g. "4/10", with a translated label for screen
readers. It goes away when the scope is complete or the restore is over -
a login that failed to reconnect does not keep it up.

`restoringAccounts` in the auth store marks the background restore; the
count itself is a pure function with its own tests.
2026-10-01 04:38:04 +02:00
Linus Rath 0e0d99e7c3 fix: send unified-view archive, move and spam to each message's account
In the unified views, a tag view and an "All folders" search a
selection can span logins and accounts, and message, account and folder
ids repeat across both: Stalwart numbers the accounts and the system
folders of every install alike.

- Archive sent the whole selection through one login into the Archive of
  the selected folder's account, which is a virtual folder there, so the
  own one: messages of a group account or of another login were archived
  by their ids in the own account, where the same ids can name unrelated
  messages, or failed after the own ones had moved. The list dropped
  every selected row either way. Each login and account now archives
  into its own Archive.
- "Move to" and dragging messages applied one folder id to every
  account, so another account's messages landed in whatever folder has
  that id there, and failed moves were dropped from the list anyway.
  Only messages in the folder's own login and account change folders in
  place now; the others take the cross-account move (Email/copy within
  one login, download and import across logins), a single message moved
  with "Move to" or dragged as well.
- A drop goes to the login whose sidebar list shows the folder. It went
  to the first login whose own account id matched the folder's, which
  with two servers that both number the user `e` could be the other one.
- "Spam" did nothing while the app said the messages were marked, and
  "Not spam" failed, because the selected folder is a virtual one there.
  Both now write each message in its own account and move it to that
  account's Junk or Inbox. The spam shortcut in "All Junk" means "Not
  spam", as the toolbar does.
- What could not be archived, moved or marked stays listed and selected,
  and the error says why.
2026-09-26 02:23:28 +02:00
Linus Rath 3823d2da17 fix: sign in and show addresses on internationalized domains #1100 2026-09-24 21:15:22 +02:00
Linus Rath d7548a4bab refactor: migrate icon set from Lucide to Tabler Icons 2026-09-19 13:32:41 +02:00
Linus Rath f3f0127c9d fix: only show the unified mailbox section when it can be populated #843 2026-09-07 22:34:47 +02:00