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
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
import RuntimeConfig from '@app/features/app/state/RuntimeConfig';
|
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 DesktopBackgroundGateway from '@app/features/gateway/transport/DesktopBackgroundGateway';
|
||||||
import GuildReadState from '@app/features/guild/state/GuildReadState';
|
import GuildReadState from '@app/features/guild/state/GuildReadState';
|
||||||
import {Logger} from '@app/features/platform/utils/AppLogger';
|
import {Logger} from '@app/features/platform/utils/AppLogger';
|
||||||
@@ -18,14 +19,40 @@ const logger = new Logger('AppBadge');
|
|||||||
const UNREAD_INDICATOR = -1;
|
const UNREAD_INDICATOR = -1;
|
||||||
|
|
||||||
let favico: Favico | null = null;
|
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 => {
|
const initFavico = (): Favico | null => {
|
||||||
if (favico) return favico;
|
if (favico) return favico;
|
||||||
try {
|
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;
|
return favico;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.warn('Failed to initialize Favico', e);
|
logger.warn('Failed to initialize Favico', e);
|
||||||
|
releaseFavico();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -39,7 +66,11 @@ const setElectronBadge = (badge: number): void => {
|
|||||||
logger.warn('Failed to set Electron badge', e);
|
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;
|
if (badge === 0 && favico === null) return;
|
||||||
const fav = initFavico();
|
const fav = initFavico();
|
||||||
if (!fav) return;
|
if (!fav) return;
|
||||||
@@ -69,9 +100,9 @@ const setPwaBadge = (badge: number): void => {
|
|||||||
logger.warn('Failed to set PWA badge', e);
|
logger.warn('Failed to set PWA badge', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const setBadge = (badge: number): void => {
|
const setBadge = (badge: number, faviconSource: string | null): void => {
|
||||||
setElectronBadge(badge);
|
setElectronBadge(badge);
|
||||||
setFaviconBadge(badge);
|
setFaviconBadge(badge, faviconSource);
|
||||||
setPwaBadge(badge);
|
setPwaBadge(badge);
|
||||||
};
|
};
|
||||||
export const AppBadge: React.FC = observer(() => {
|
export const AppBadge: React.FC = observer(() => {
|
||||||
@@ -89,15 +120,16 @@ export const AppBadge: React.FC = observer(() => {
|
|||||||
} else if (hasUnread && unreadMessageBadgeEnabled) {
|
} else if (hasUnread && unreadMessageBadgeEnabled) {
|
||||||
badge = UNREAD_INDICATOR;
|
badge = UNREAD_INDICATOR;
|
||||||
}
|
}
|
||||||
|
const faviconSource = getDocumentFaviconUrl(RuntimeConfig.getSnapshotOrNull()?.appPublic ?? null);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setBadge(badge);
|
setBadge(badge, faviconSource);
|
||||||
}, [badge]);
|
}, [badge, faviconSource]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
updateDocumentTitleBadge(totalCount, hasUnread && unreadMessageBadgeEnabled);
|
updateDocumentTitleBadge(totalCount, hasUnread && unreadMessageBadgeEnabled);
|
||||||
}, [totalCount, hasUnread, unreadMessageBadgeEnabled]);
|
}, [totalCount, hasUnread, unreadMessageBadgeEnabled]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
setBadge(0);
|
setBadge(0, favicoSource);
|
||||||
updateDocumentTitleBadge(0, false);
|
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 {
|
export function applyRuntimeDocumentBranding(appPublic: InstanceAppPublic): void {
|
||||||
applyDocumentBranding(
|
applyDocumentBranding(
|
||||||
appPublic.branding.product_name,
|
appPublic.branding.product_name,
|
||||||
appPublic.branding.favicon_url ?? appPublic.branding.icon_url,
|
getDocumentFaviconUrl(appPublic),
|
||||||
appPublic.branding.theme_color,
|
appPublic.branding.theme_color,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -88,7 +93,7 @@ export function applyRuntimeDocumentBranding(appPublic: InstanceAppPublic): void
|
|||||||
export function applyDefaultAppShellDocumentBranding(): void {
|
export function applyDefaultAppShellDocumentBranding(): void {
|
||||||
applyDocumentBranding(
|
applyDocumentBranding(
|
||||||
DEFAULT_APP_SHELL_BRANDING.productName,
|
DEFAULT_APP_SHELL_BRANDING.productName,
|
||||||
DEFAULT_APP_SHELL_BRANDING.faviconUrl,
|
getDocumentFaviconUrl(null),
|
||||||
DEFAULT_APP_SHELL_BRANDING.themeColor,
|
DEFAULT_APP_SHELL_BRANDING.themeColor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user