Files
Oğuz YılmazandClaude Opus 5.5 54ec8c6584 feat: let operators keep the message subject out of the tab title
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>
2026-10-07 08:26:51 +03:00

37 lines
1.5 KiB
TypeScript

// Browser-tab titles read "<context> - <account> - <app>", the order Gmail and
// Outlook Web use. Browsers cut a long title from the end, so the part that
// changes (folder, unread count, subject) goes first and the app name last.
// The account sits in between, so two mailboxes open side by side stay apart
// in the tab strip and in session restore. Empty parts are left out. (#1159)
export function formatTabTitle(
context: string | null | undefined,
account: string | null | undefined,
appName: string,
): string {
return [context, account, appName].filter(Boolean).join(' - ');
}
/** What the mail view is showing, already localized. */
export interface MailTitleView {
/** Composer label while the composer is open ("New message", "Reply", ...). */
composer?: string | null;
/** Subject of the open message. */
subject?: string | null;
/** Selected mailbox, with its unread count when there is one. */
mailbox?: string | null;
}
/**
* The context part of the mail view's tab title: composer, then message, then
* mailbox. The subject does not stay in the tab strip - browsers keep it in
* history and in the session-restore list, and screen shares show it - so an
* operator can keep it out (`tabTitleSubjectEnabled`). The mailbox line is
* shown instead, so the tab still says where you are. (#1159)
*/
export function mailTitleContext(
view: MailTitleView,
{ showSubject = true }: { showSubject?: boolean } = {},
): string | null {
return view.composer || (showSubject ? view.subject : null) || view.mailbox || null;
}