The week and day headers now show a small weekday above a large date,
with today's date in a filled circle and its weekday in the primary
colour. Clicking a date in the week header opens that day in the day
view. The all-day row moved below the dates, where it lines up with
the columns it belongs to.
The current time line is thicker with a larger dot at the start of
today's column, and events shorter than 45 minutes show their start
time next to the title instead of hiding it.
The calendar list in the sidebar now works like Google Calendar's:
- "My calendars" and a new "Other calendars" section (shared
calendars, still grouped by owner) fold away, and stay folded
- each calendar has a checkbox filled in its colour with a check mark
- hovering a calendar shows an options button that opens the same
menu as a right-click
In the mini month, today is the filled circle and the selected day is
tinted, so the two no longer look alike.
The previous commit copied Google Calendar's look along with its
layout. The bar and the sidebar now use the webmail's regular buttons,
sizes and title style again; only the arrangement stays: menu button,
Today and arrows with the title, the view menu on the right and the
create button at the top of the sidebar.
The bar now spans the sidebar and the grid. It starts with a menu
button that hides or shows the sidebar (remembered across visits),
then a pill Today button, the arrows and a large period title. On
the right a view menu lists Day, Week, Month and Agenda (and Tasks)
with their shortcut keys, and import and subscribe moved into a
"more actions" menu instead of a button of their own.
The Create button moved to the top of the sidebar. While the sidebar
is hidden or an overlay, a compact create button sits in the bar.
Opening a message puts its subject in the browser-tab title. The title does
not stay in the tab strip: browsers keep it in history and in the
session-restore list, and screen shares show it. For mailboxes that hold
other people's correspondence that is a leak nobody audits.
A new feature gate, tabTitleSubjectEnabled ("Subject in Tab Title" under
Admin -> Policy), is on by default, so nothing changes for existing
installs. With it off, the title names the folder instead, so the tab still
says where you are. It is an admin gate rather than a user setting: whose
mail the boxes hold is a deployment decision.
The gate counts as off until the policy has loaded, so a subject never
slips into history while the setting is still unknown.
Refs #1159
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the mail shell updated document.title, so every other surface sat at the
static value the root layout renders: the tab could not tell you where you
were, and on a multi-account setup it could not tell you whose mailbox you
were in either.
Each surface now sets "<screen> - <account> - <app>" through the shared
useDocumentTitle hook. Labels reuse the sidebar navigation translations, so
the tab and the rail never disagree about what a screen is called - no new
translation keys.
Refs #1159
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The tab title was "<context> - <app>", so two mailboxes open side by side
read the same in the tab strip and in the browser's session-restore list.
It is now "<context> - <account> - <app>", the order Gmail and Outlook Web
use: browsers cut a long title from the end, so the part that changes comes
first and the app name last. There is no setting for it; the account is what
tells the tabs apart.
The formatting, and the mail view's choice of context (composer, then
message, then mailbox), live in lib/tab-title.ts with tests. The mail view
sets its title through useDocumentTitle(), which other surfaces can use too.
Next renders the root layout's metadata <title> again on every client-side
navigation, after the surface has mounted; the hook puts its title back when
that happens. Only the surface that set the title last does so, so two
titles never fight.
Refs #1159
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tailwind v4's preflight no longer gives buttons a pointer cursor, so most
buttons, menu items, tabs, switches and selects showed the arrow. A base-layer
rule in globals.css gives them the pointer again and gives disabled ones
not-allowed. Cursor utilities on components still take precedence.
On a branded deployment (APP_NAME, APP_LOGO_*) three places after sign-in
still showed Bulwark or Stalwart (#1160):
- the TOTP issuer was 'Stalwart', so the authenticator app listed the
mail server instead of the service; it is now the configured app name,
- the About card used the Bulwark wordmark and title; with APP_NAME set
it shows the configured name and logo (light/dark as configured), and
keeps the Bulwark mark otherwise,
- the Files settings preview thumbnail used the bundled logo; it now uses
the configured one when there is one.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stalwart's default folder set has no archive-role mailbox, so on a fresh
account Archive did nothing but raise the not-found toast (#578). Both
archive paths now go through ensureArchiveMailbox(), which creates
"Archive" with the archive role in the account the action targets (own,
the selected shared folder's owner, or the pinned account in unified
view), reloads the mailbox list and continues with the store's own
object. createMailbox() takes an optional role for this. A refused
creation or a folder that does not come back still surfaces as an error.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The agenda sidecar queried only the session's primary calendar account,
so events in a shared or group account (a family or team calendar) never
reached the Calendar Agenda plugin, although the calendar app shows them.
Read every account the calendar app reads: the primary account plus
accounts that advertise the calendar capability or are not personal,
mirroring the client's getCalendarCapableAccountIds(). Event and
calendar ids repeat across accounts, so the DTO id is scoped as
<accountId>:<id> and carries accountId; calendar colours are looked up
per account. A shared account whose calendars cannot be read is skipped
instead of failing the whole agenda; a failure of the primary account is
still reported.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Forty strings in locales/cs/common.json were still identical to English:
removing an account, tinting list rows, the date-format region and time
zone settings, inbox-only notifications, cache refresh, file sharing,
contact groups, and a few folder roles and labels. Placeholders are
unchanged and the file keeps its CRLF line endings.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- hu: {elválasztó} → {delimiter} (3 strings)
- mn: {from}/{to} → {before}/{after}; account email/server/last-sync values
held the label text instead of {email}/{server}/{time}; user+tag → user{delimiter}tag (2)
- he: user+tag → user{delimiter}tag, with the missing spaces around the address
- fa, sk: descriptions were cut short and lost {delimiter}, {appName},
{filename} and {ext}; completed them