mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-05 12:16:53 +02:00
Rewrite favicon code to support modules.
This commit is contained in:
parent
bb0f2d65ab
commit
3ffcaba20b
@ -494,15 +494,10 @@ export default abstract class BasePlatform {
|
||||
}
|
||||
|
||||
private updateFavicon(): void {
|
||||
let bgColor = "#d00";
|
||||
let notif: string | number = this.notificationCount;
|
||||
|
||||
if (this.errorDidOccur) {
|
||||
notif = notif || "×";
|
||||
bgColor = "#f00";
|
||||
}
|
||||
|
||||
this.favicon.badge(notif, { bgColor });
|
||||
this.favicon.badge({
|
||||
notificationCount: this.notificationCount,
|
||||
errorDidOccur: this.errorDidOccur
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -17,6 +17,8 @@ interface IParams {
|
||||
isUp: boolean;
|
||||
isLeft: boolean;
|
||||
}
|
||||
import { FaviconRenderFunction, FaviconRenderOptions } from "@element-hq/element-web-module-api";
|
||||
import moduleApi from "./modules/Api.ts"
|
||||
|
||||
const defaults: IParams = {
|
||||
bgColor: "#d00",
|
||||
@ -184,9 +186,9 @@ export default class Favicon {
|
||||
this.readyCb?.();
|
||||
}
|
||||
|
||||
private setIcon(canvas: HTMLCanvasElement): void {
|
||||
private setIcon(src: string): void {
|
||||
setTimeout(() => {
|
||||
this.setIconSrc(canvas.toDataURL("image/png"));
|
||||
this.setIconSrc(src);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@ -209,21 +211,39 @@ export default class Favicon {
|
||||
}
|
||||
}
|
||||
|
||||
public badge(content: number | string, opts?: Partial<IParams>): void {
|
||||
if (!this.isReady) {
|
||||
this.readyCb = (): void => {
|
||||
this.badge(content, opts);
|
||||
};
|
||||
return;
|
||||
/**
|
||||
* Default badge renderer, may be overridden by a module.
|
||||
* @param opts Notification rendering options.
|
||||
* @returns A data URL for the favicon.
|
||||
*/
|
||||
private renderBadge: FaviconRenderFunction = ({notificationCount, errorDidOccur}) => {
|
||||
let bgColor = "#d00";
|
||||
let notif: string | number = notificationCount;
|
||||
|
||||
if (errorDidOccur) {
|
||||
notif = notif || "×";
|
||||
bgColor = "#f00";
|
||||
}
|
||||
|
||||
if (typeof content === "string" || content > 0) {
|
||||
this.circle(content, opts);
|
||||
if (errorDidOccur || notificationCount > 0) {
|
||||
this.circle(notif, {...this.params, bgColor });
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
this.setIcon(this.canvas);
|
||||
return this.canvas.toDataURL("image/png");
|
||||
}
|
||||
|
||||
public badge(opts: FaviconRenderOptions): void {
|
||||
if (!this.isReady) {
|
||||
this.readyCb = (): void => {
|
||||
this.badge(opts);
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
const badgeUrl = moduleApi.faviconApi.renderFavicon(opts) || this.renderBadge(opts);
|
||||
this.setIcon(badgeUrl);
|
||||
}
|
||||
|
||||
private static getLinks(): HTMLLinkElement[] {
|
||||
@ -237,7 +257,7 @@ export default class Favicon {
|
||||
return icons;
|
||||
}
|
||||
|
||||
private static getIcons(): HTMLLinkElement[] {
|
||||
public static getIcons(): HTMLLinkElement[] {
|
||||
// get favicon link elements
|
||||
let elms = Favicon.getLinks();
|
||||
if (elms.length === 0) {
|
||||
|
||||
@ -22,6 +22,7 @@ import { WidgetVariableCustomisations } from "../customisations/WidgetVariables.
|
||||
import { ConfigApi } from "./ConfigApi.ts";
|
||||
import { I18nApi } from "./I18nApi.ts";
|
||||
import { CustomComponentsApi } from "./customComponentApi.ts";
|
||||
import { FaviconApi } from "./faviconApi.ts";
|
||||
|
||||
const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) => {
|
||||
let used = false;
|
||||
@ -61,6 +62,7 @@ class ModuleApi implements Api {
|
||||
public readonly i18n = new I18nApi();
|
||||
public readonly customComponents = new CustomComponentsApi();
|
||||
public readonly rootNode = document.getElementById("matrixchat")!;
|
||||
public readonly faviconApi = new FaviconApi();
|
||||
|
||||
public createRoot(element: Element): Root {
|
||||
return createRoot(element);
|
||||
|
||||
36
src/modules/faviconApi.ts
Normal file
36
src/modules/faviconApi.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2025 New Vector 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 {
|
||||
FaviconApi as IFaviconApi,
|
||||
FaviconRenderFunction,
|
||||
FaviconRenderOptions
|
||||
} from "@element-hq/element-web-module-api";
|
||||
|
||||
|
||||
export class FaviconApi implements IFaviconApi {
|
||||
private registeredFunction?: FaviconRenderFunction;
|
||||
|
||||
public registerRenderer(
|
||||
func: FaviconRenderFunction
|
||||
): void {
|
||||
if (this.registeredFunction) {
|
||||
throw Error('A custom favicon rendering function has already been registered');
|
||||
}
|
||||
this.registeredFunction = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a URL to a rendered favicon if a module has generated one, otherwise
|
||||
* this returns undefined.
|
||||
* @param opts Options to pass to the render function.
|
||||
* @returns A URL string, or undefined.
|
||||
*/
|
||||
public renderFavicon(opts: FaviconRenderOptions): string|undefined {
|
||||
return this.registeredFunction?.(opts);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user