Dynamic document favicon

This commit is contained in:
Dustin Brett 2022-07-27 11:18:38 -07:00
parent 8884ca4b77
commit f9c0e4819b
2 changed files with 53 additions and 2 deletions

View File

@ -4,17 +4,19 @@ import Head from "next/head";
import desktopIcons from "public/.index/desktopIcons.json";
import { useEffect, useState } from "react";
import {
FAVICON_BASE_PATH,
HIGH_PRIORITY_ELEMENT,
ICON_PATH,
PACKAGE_DATA,
USER_ICON_PATH,
} from "utils/constants";
import { imageSrcs } from "utils/functions";
import { getDpi, imageSrc, imageSrcs, supportsWebp } from "utils/functions";
const { alias, description } = PACKAGE_DATA;
const Metadata: FC = () => {
const [title, setTitle] = useState(alias);
const [favIcon, setFavIcon] = useState("");
const { foregroundId } = useSession();
const { processes: { [foregroundId]: process } = {} } = useProcesses();
@ -22,15 +24,37 @@ const Metadata: FC = () => {
if (process) {
const documentTitle = `${process.title} - ${alias}`;
if (title !== documentTitle) setTitle(documentTitle);
if (title !== documentTitle) {
setTitle(documentTitle);
setFavIcon(process.icon || FAVICON_BASE_PATH);
}
} else {
setTitle(alias);
setFavIcon((currentFavicon) =>
currentFavicon ? FAVICON_BASE_PATH : currentFavicon
);
}
}, [process, title]);
return (
<Head>
<title>{title}</title>
{favIcon && (
<link
href={
favIcon === FAVICON_BASE_PATH
? FAVICON_BASE_PATH
: imageSrc(
favIcon,
16,
getDpi(),
supportsWebp() ? ".webp" : ".png"
).split(" ")[0]
}
rel="icon"
type={supportsWebp() ? "image/webp" : "image/png"}
/>
)}
<meta
content="width=device-width, initial-scale=1, minimum-scale=1"
name="viewport"

View File

@ -18,6 +18,33 @@ export const bufferToBlob = (buffer: Buffer, type?: string): Blob =>
export const bufferToUrl = (buffer: Buffer): string =>
URL.createObjectURL(bufferToBlob(buffer));
let canUseWebp: boolean;
export const supportsWebp = (): boolean => {
if (typeof canUseWebp === "boolean") return canUseWebp;
try {
canUseWebp = document
.createElement("canvas")
.toDataURL("image/webp", 0)
.startsWith("data:image/webp");
return canUseWebp;
} catch {
return false;
}
};
let dpi: number;
export const getDpi = (): number => {
if (typeof dpi === "number") return dpi;
dpi = Math.min(Math.ceil(window.devicePixelRatio), 3);
return dpi;
};
export const imageSrc = (
imagePath: string,
size: number,