import { memo, useCallback, useEffect, useMemo, useState } from "react"; import Head from "next/head"; import { useFileSystem } from "contexts/fileSystem"; import { useProcesses } from "contexts/process"; import { useSession } from "contexts/session"; import desktopIcons from "public/.index/desktopIcons.json"; import { FAVICON_BASE_PATH, HIGH_PRIORITY_ELEMENT, ONE_TIME_PASSIVE_EVENT, PACKAGE_DATA, } from "utils/constants"; import { getDpi, getExtension, getMimeType, imageSrc, imageSrcs, isDynamicIcon, } from "utils/functions"; const { alias, author, description } = PACKAGE_DATA; const Metadata: FC = () => { const [title, setTitle] = useState(alias); const [favIcon, setFavIcon] = useState(""); const { readFile } = useFileSystem(); const [customCursor, setCustomCursor] = useState(""); const { cursor, foregroundId } = useSession(); const { processes: { [foregroundId]: process } = {} } = useProcesses(); const { icon: processIcon, hideTaskbarEntry, title: processTitle, } = process || {}; const resetFaviconAndTitle = useCallback((): void => { setTitle(alias); setFavIcon((currentFavicon) => currentFavicon ? FAVICON_BASE_PATH : currentFavicon ); }, []); const currentFavIcon = useMemo( () => isDynamicIcon(favIcon) ? imageSrc(favIcon, 16, getDpi(), getExtension(favIcon)).split(" ")[0] : favIcon, [favIcon] ); const favIconMimeType = useMemo( () => getMimeType(currentFavIcon), [currentFavIcon] ); const getCursor = useCallback( async (path: string) => { const imageBuffer = await readFile(path); if (!imageBuffer?.length) return ""; const { cursorToCss } = await import("utils/imageDecoder"); return cursorToCss(imageBuffer, path); }, [readFile] ); useEffect(() => { if (!hideTaskbarEntry && (processIcon || processTitle)) { const documentTitle = processTitle ? `${processTitle} - ${alias}` : alias; if (title !== documentTitle) setTitle(documentTitle); if (favIcon !== processIcon || !favIcon) { setFavIcon(encodeURI(processIcon) || FAVICON_BASE_PATH); } } else { resetFaviconAndTitle(); } }, [ favIcon, hideTaskbarEntry, processIcon, processTitle, resetFaviconAndTitle, title, ]); useEffect(() => { const onVisibilityChange = (): void => { if (document.visibilityState === "visible") resetFaviconAndTitle(); }; const onBeforeUnload = (): void => { const faviconLinkElement = document.querySelector("link[rel=icon]"); if (faviconLinkElement instanceof HTMLLinkElement) { try { faviconLinkElement.href = FAVICON_BASE_PATH; } catch { // Ignore failure to set link href } } }; window.addEventListener( "beforeunload", onBeforeUnload, ONE_TIME_PASSIVE_EVENT ); document.addEventListener("visibilitychange", onVisibilityChange, { passive: true, }); return () => { window.removeEventListener("beforeunload", onBeforeUnload); document.removeEventListener("visibilitychange", onVisibilityChange); }; }, [resetFaviconAndTitle]); useEffect(() => { if (cursor) getCursor(cursor).then(setCustomCursor); }, [cursor, getCursor]); return (