mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-09 06:06:19 +02:00
implement BrandApi and it's titleRenderer
This commit is contained in:
parent
e53a148da2
commit
883fb622e6
@ -248,6 +248,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
// What to focus on next component update, if anything
|
||||
private focusNext: FocusNextType;
|
||||
private subTitleStatus: string;
|
||||
private notificationCount = 0;
|
||||
private hasActivity = false;
|
||||
private errorDidOccur = false;
|
||||
private prevWindowWidth: number;
|
||||
|
||||
private readonly loggedInView = createRef<LoggedInViewType>();
|
||||
@ -2081,17 +2084,36 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
}
|
||||
|
||||
private setPageSubtitle(subtitle = ""): void {
|
||||
if (this.state.currentRoomId) {
|
||||
const client = MatrixClientPeg.get();
|
||||
const room = client?.getRoom(this.state.currentRoomId);
|
||||
if (room) {
|
||||
subtitle = `${this.subTitleStatus} | ${room.name} ${subtitle}`;
|
||||
const brand = SdkConfig.get().brand;
|
||||
const room = this.state.currentRoomId
|
||||
? MatrixClientPeg.get()?.getRoom(this.state.currentRoomId)
|
||||
: undefined;
|
||||
|
||||
const customTitle = ModuleApi.instance.brand.renderTitle({
|
||||
brand,
|
||||
notificationCount: this.notificationCount || undefined,
|
||||
hasActivity: this.hasActivity || undefined,
|
||||
statusText: this.errorDidOccur ? _t("common|offline") : undefined,
|
||||
roomId: this.state.currentRoomId ?? undefined,
|
||||
roomName: room?.name,
|
||||
});
|
||||
|
||||
if (customTitle !== undefined) {
|
||||
if (document.title !== customTitle) {
|
||||
document.title = customTitle;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const elementSuffix = brand !== "Element" ? " | Element" : "";
|
||||
|
||||
if (room) {
|
||||
subtitle = `${this.subTitleStatus} | ${room.name} ${subtitle}`;
|
||||
} else {
|
||||
subtitle = `${this.subTitleStatus} ${subtitle}`;
|
||||
}
|
||||
|
||||
const title = `${SdkConfig.get().brand} ${subtitle}`;
|
||||
const title = `${brand}${elementSuffix} ${subtitle}`;
|
||||
|
||||
if (document.title !== title) {
|
||||
document.title = title;
|
||||
@ -2107,12 +2129,15 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
}
|
||||
|
||||
this.subTitleStatus = "";
|
||||
if (state === SyncState.Error) {
|
||||
this.errorDidOccur = state === SyncState.Error;
|
||||
if (this.errorDidOccur) {
|
||||
this.subTitleStatus += `[${_t("common|offline")}] `;
|
||||
}
|
||||
this.notificationCount = numUnreadRooms;
|
||||
this.hasActivity = notificationState.level >= NotificationLevel.Activity;
|
||||
if (numUnreadRooms > 0) {
|
||||
this.subTitleStatus += `[${numUnreadRooms}]`;
|
||||
} else if (notificationState.level >= NotificationLevel.Activity) {
|
||||
} else if (this.hasActivity) {
|
||||
this.subTitleStatus += `*`;
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ import { StoresApi } from "./StoresApi.ts";
|
||||
import { WidgetLifecycleApi } from "./WidgetLifecycleApi.ts";
|
||||
import { WidgetApi } from "./WidgetApi.ts";
|
||||
import { CustomisationsApi } from "./customisationsApi.ts";
|
||||
import { ElementWebBrandApi } from "./BrandApi.ts";
|
||||
|
||||
const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) => {
|
||||
let used = false;
|
||||
@ -87,6 +88,7 @@ export class ModuleApi implements Api {
|
||||
public readonly i18n = new I18nApi();
|
||||
public readonly customComponents = new CustomComponentsApi();
|
||||
public readonly customisations = new CustomisationsApi();
|
||||
public readonly brand = new ElementWebBrandApi();
|
||||
public readonly extras = new ElementWebExtrasApi();
|
||||
public readonly builtins = new ElementWebBuiltinsApi();
|
||||
public readonly widgetLifecycle = new WidgetLifecycleApi();
|
||||
|
||||
27
apps/web/src/modules/BrandApi.ts
Normal file
27
apps/web/src/modules/BrandApi.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2026 Element Creations Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type BrandApi, type TitleRenderFunction, type TitleRenderOptions } from "@element-hq/element-web-module-api";
|
||||
|
||||
export class ElementWebBrandApi implements BrandApi {
|
||||
private titleRenderer: TitleRenderFunction | undefined;
|
||||
|
||||
public registerTitleRenderer(renderFunction: TitleRenderFunction): void {
|
||||
if (this.titleRenderer) {
|
||||
throw new Error("A title renderer has already been registered by another module");
|
||||
}
|
||||
this.titleRenderer = renderFunction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the window title using the registered renderer, or return undefined
|
||||
* to fall back to the default title logic.
|
||||
*/
|
||||
public renderTitle(opts: TitleRenderOptions): string | undefined {
|
||||
return this.titleRenderer?.(opts);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user