mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(app): redraw the favicon badge when branding changes (#3314)
This commit is contained in:
1 parent
4ecbe9603c
commit
4b1afc953f
2 files changed
+46
-9
No files matched your search
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
import RuntimeConfig from '@app/features/app/state/RuntimeConfig';
|
||||
import {getDocumentFaviconUrl} from '@app/features/app/state/RuntimeDocumentBranding';
|
||||
import DesktopBackgroundGateway from '@app/features/gateway/transport/DesktopBackgroundGateway';
|
||||
import GuildReadState from '@app/features/guild/state/GuildReadState';
|
||||
import {Logger} from '@app/features/platform/utils/AppLogger';
|
||||
@@ -18,14 +19,40 @@ const logger = new Logger('AppBadge');
|
||||
const UNREAD_INDICATOR = -1;
|
||||
|
||||
let favico: Favico | null = null;
|
||||
let favicoLink: HTMLLinkElement | null = null;
|
||||
let favicoLinkHref: string | null = null;
|
||||
let favicoSource: string | null = null;
|
||||
|
||||
const findIconLink = (): HTMLLinkElement | null => {
|
||||
const links = document.head.querySelectorAll<HTMLLinkElement>('link');
|
||||
for (let index = links.length - 1; index >= 0; index--) {
|
||||
if (/(^|\s)icon(\s|$)/i.test(links[index].getAttribute('rel') ?? '')) {
|
||||
return links[index];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const releaseFavico = (): void => {
|
||||
if (favicoLink !== null && favicoLinkHref !== null && favicoLink.getAttribute('href')?.startsWith('data:')) {
|
||||
favicoLink.setAttribute('href', favicoLinkHref);
|
||||
}
|
||||
favico = null;
|
||||
favicoLink = null;
|
||||
favicoLinkHref = null;
|
||||
};
|
||||
|
||||
const initFavico = (): Favico | null => {
|
||||
if (favico) return favico;
|
||||
try {
|
||||
favico = new Favico({animation: 'none'});
|
||||
const link = findIconLink();
|
||||
favicoLink = link;
|
||||
favicoLinkHref = link?.getAttribute('href') ?? null;
|
||||
favico = new Favico(link === null ? {animation: 'none'} : {animation: 'none', element: link});
|
||||
return favico;
|
||||
} catch (e) {
|
||||
logger.warn('Failed to initialize Favico', e);
|
||||
releaseFavico();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -39,7 +66,11 @@ const setElectronBadge = (badge: number): void => {
|
||||
logger.warn('Failed to set Electron badge', e);
|
||||
}
|
||||
};
|
||||
const setFaviconBadge = (badge: number): void => {
|
||||
const setFaviconBadge = (badge: number, source: string | null): void => {
|
||||
if (source !== favicoSource) {
|
||||
releaseFavico();
|
||||
favicoSource = source;
|
||||
}
|
||||
if (badge === 0 && favico === null) return;
|
||||
const fav = initFavico();
|
||||
if (!fav) return;
|
||||
@@ -69,9 +100,9 @@ const setPwaBadge = (badge: number): void => {
|
||||
logger.warn('Failed to set PWA badge', e);
|
||||
}
|
||||
};
|
||||
const setBadge = (badge: number): void => {
|
||||
const setBadge = (badge: number, faviconSource: string | null): void => {
|
||||
setElectronBadge(badge);
|
||||
setFaviconBadge(badge);
|
||||
setFaviconBadge(badge, faviconSource);
|
||||
setPwaBadge(badge);
|
||||
};
|
||||
export const AppBadge: React.FC = observer(() => {
|
||||
@@ -89,15 +120,16 @@ export const AppBadge: React.FC = observer(() => {
|
||||
} else if (hasUnread && unreadMessageBadgeEnabled) {
|
||||
badge = UNREAD_INDICATOR;
|
||||
}
|
||||
const faviconSource = getDocumentFaviconUrl(RuntimeConfig.getSnapshotOrNull()?.appPublic ?? null);
|
||||
useEffect(() => {
|
||||
setBadge(badge);
|
||||
}, [badge]);
|
||||
setBadge(badge, faviconSource);
|
||||
}, [badge, faviconSource]);
|
||||
useEffect(() => {
|
||||
updateDocumentTitleBadge(totalCount, hasUnread && unreadMessageBadgeEnabled);
|
||||
}, [totalCount, hasUnread, unreadMessageBadgeEnabled]);
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setBadge(0);
|
||||
setBadge(0, favicoSource);
|
||||
updateDocumentTitleBadge(0, false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -77,10 +77,15 @@ function applyDocumentBranding(productName: string, faviconUrl: string | null, t
|
||||
}
|
||||
}
|
||||
|
||||
export function getDocumentFaviconUrl(appPublic: InstanceAppPublic | null): string | null {
|
||||
if (appPublic === null) return DEFAULT_APP_SHELL_BRANDING.faviconUrl;
|
||||
return appPublic.branding.favicon_url ?? appPublic.branding.icon_url;
|
||||
}
|
||||
|
||||
export function applyRuntimeDocumentBranding(appPublic: InstanceAppPublic): void {
|
||||
applyDocumentBranding(
|
||||
appPublic.branding.product_name,
|
||||
appPublic.branding.favicon_url ?? appPublic.branding.icon_url,
|
||||
getDocumentFaviconUrl(appPublic),
|
||||
appPublic.branding.theme_color,
|
||||
);
|
||||
}
|
||||
@@ -88,7 +93,7 @@ export function applyRuntimeDocumentBranding(appPublic: InstanceAppPublic): void
|
||||
export function applyDefaultAppShellDocumentBranding(): void {
|
||||
applyDocumentBranding(
|
||||
DEFAULT_APP_SHELL_BRANDING.productName,
|
||||
DEFAULT_APP_SHELL_BRANDING.faviconUrl,
|
||||
getDocumentFaviconUrl(null),
|
||||
DEFAULT_APP_SHELL_BRANDING.themeColor,
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user