diff --git a/docs/config.md b/docs/config.md index 65e8291bb6..cd4eddcaef 100644 --- a/docs/config.md +++ b/docs/config.md @@ -211,16 +211,20 @@ Starting with `branding`, the following subproperties are available: 2. `auth_header_logo_url`: A URL to the logo used on the login, registration, etc pages. 3. `auth_footer_links`: A list of links to add to the footer during login, registration, etc. Each entry must have a `text` and `url` property. -4. `title_template`: A template string that can be used to configure the title of the application. -5. `title_template_in_room`: A template string that can be used to configure the title of the application. This applies while - the client is viewing a Matrix room. +4. `title_template`: A template string that can be used to configure the title of the application when not viewing a room. +5. `title_template_in_room`: A template string that can be used to configure the title of the application when viewing a room + #### `title_template` vars -- `subtitle` -- `room_name` -- `brand` +- `brand` The name of the web app, as configured by the `brand` config value. +- `room_name` The friendly name of a room. Only applicable to `title_template_in_room`. +- `status` The client's status, repesented as. + - The notification count, when at least one room is unread. + - "*" when no rooms are unread, but notifications are not muted. + - "Offline", when the client is offline. + - "", when the client isn't logged in or notifications are muted. `embedded_pages` can be configured as such: diff --git a/src/IConfigOptions.ts b/src/IConfigOptions.ts index bbb377e07b..bbed4c9722 100644 --- a/src/IConfigOptions.ts +++ b/src/IConfigOptions.ts @@ -50,6 +50,8 @@ export interface IConfigOptions { welcome_background_url?: string | string[]; // chosen at random if array auth_header_logo_url?: string; auth_footer_links?: { text: string; url: string }[]; + title_template?: string; + title_template_in_room?: string; }; force_verification?: boolean; // if true, users must verify new logins diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 9d3114c67c..ea65224454 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -226,6 +226,9 @@ export default class MatrixChat extends React.PureComponent { private subTitleStatus: string; private prevWindowWidth: number; + private readonly titleTemplate: string; + private readonly titleTemplateInRoom: string; + private readonly loggedInView = createRef(); private dispatcherRef?: string; private themeWatcher?: ThemeWatcher; @@ -279,6 +282,9 @@ export default class MatrixChat extends React.PureComponent { // object field used for tracking the status info appended to the title tag. // we don't do it as react state as i'm scared about triggering needless react refreshes. this.subTitleStatus = ""; + + this.titleTemplate = props.config.branding?.title_template ?? '$brand $status'; + this.titleTemplateInRoom = props.config.branding?.title_template_in_room ?? '$brand $status | $room_name'; } /** @@ -1941,21 +1947,32 @@ export default class MatrixChat extends React.PureComponent { }); } - private setPageSubtitle(subtitle = ""): void { + private setPageSubtitle(): void { + const params: { + $brand: string, + $status: string, + $room_name: string|undefined, + } = { + $brand: SdkConfig.get().brand, + $status: this.subTitleStatus, + $room_name: undefined, + }; + if (this.state.currentRoomId) { const client = MatrixClientPeg.get(); const room = client?.getRoom(this.state.currentRoomId); if (room) { - subtitle = `${this.subTitleStatus} | ${room.name} ${subtitle}`; + params.$room_name = room.name; } - } else { - subtitle = `${this.subTitleStatus} ${subtitle}`; } + + const titleTemplate = params.$room_name ? this.titleTemplateInRoom : this.titleTemplate; - const title = `${SdkConfig.get().brand} ${subtitle}`; + const title = Object.entries(params).reduce( + (title: string, [key, value]) => title.replaceAll(key, (value ?? '').replaceAll('$', '$_DLR$')), titleTemplate); if (document.title !== title) { - document.title = title; + document.title = title.replaceAll('$_DLR$', '$'); } }