mirror of
https://github.com/DustinBrett/daedalOS.git
synced 2025-12-06 12:20:20 +01:00
Specify preload types + centralize
This commit is contained in:
parent
7779adaa45
commit
ae21174d58
|
|
@ -15,7 +15,6 @@ import {
|
||||||
type YouTubePlayer,
|
type YouTubePlayer,
|
||||||
} from "components/apps/VideoPlayer/types";
|
} from "components/apps/VideoPlayer/types";
|
||||||
import { type ContainerHookProps } from "components/system/Apps/AppContainer";
|
import { type ContainerHookProps } from "components/system/Apps/AppContainer";
|
||||||
import { getMimeType } from "components/system/Files/FileEntry/functions";
|
|
||||||
import useTitle from "components/system/Window/useTitle";
|
import useTitle from "components/system/Window/useTitle";
|
||||||
import useWindowSize from "components/system/Window/useWindowSize";
|
import useWindowSize from "components/system/Window/useWindowSize";
|
||||||
import { useFileSystem } from "contexts/fileSystem";
|
import { useFileSystem } from "contexts/fileSystem";
|
||||||
|
|
@ -24,6 +23,7 @@ import { VIDEO_FALLBACK_MIME_TYPE } from "utils/constants";
|
||||||
import {
|
import {
|
||||||
bufferToUrl,
|
bufferToUrl,
|
||||||
cleanUpBufferUrl,
|
cleanUpBufferUrl,
|
||||||
|
getMimeType,
|
||||||
isSafari,
|
isSafari,
|
||||||
isYouTubeUrl,
|
isYouTubeUrl,
|
||||||
loadFiles,
|
loadFiles,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
import {
|
import {
|
||||||
getDpi,
|
getDpi,
|
||||||
getExtension,
|
getExtension,
|
||||||
|
getMimeType,
|
||||||
imageSrc,
|
imageSrc,
|
||||||
imageSrcs,
|
imageSrcs,
|
||||||
imageToBufferUrl,
|
imageToBufferUrl,
|
||||||
|
|
@ -148,6 +149,7 @@ const Metadata: FC = () => {
|
||||||
{desktopIcons.map((icon) => {
|
{desktopIcons.map((icon) => {
|
||||||
const isSubIcon = icon.includes("/16x16/");
|
const isSubIcon = icon.includes("/16x16/");
|
||||||
const dynamicIcon = !isSubIcon && isDynamicIcon(icon);
|
const dynamicIcon = !isSubIcon && isDynamicIcon(icon);
|
||||||
|
const extension = getExtension(icon);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<link
|
<link
|
||||||
|
|
@ -156,12 +158,13 @@ const Metadata: FC = () => {
|
||||||
href={dynamicIcon || isSubIcon ? undefined : icon}
|
href={dynamicIcon || isSubIcon ? undefined : icon}
|
||||||
imageSrcSet={
|
imageSrcSet={
|
||||||
dynamicIcon
|
dynamicIcon
|
||||||
? imageSrcs(icon, 48, ".webp")
|
? imageSrcs(icon, 48, extension)
|
||||||
: isSubIcon
|
: isSubIcon
|
||||||
? imageSrcs(icon.replace("16x16/", ""), 16, ".webp")
|
? imageSrcs(icon.replace("16x16/", ""), 16, extension)
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
rel="preload"
|
rel="preload"
|
||||||
|
type={getMimeType(extension)}
|
||||||
{...HIGH_PRIORITY_ELEMENT}
|
{...HIGH_PRIORITY_ELEMENT}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -103,3 +103,5 @@ export const BASE_CANVAS_SELECTOR = ":scope > canvas";
|
||||||
export const BASE_VIDEO_SELECTOR = ":scope > video";
|
export const BASE_VIDEO_SELECTOR = ":scope > video";
|
||||||
|
|
||||||
export const STABLE_DIFFUSION_DELAY_IN_MIN = 10;
|
export const STABLE_DIFFUSION_DELAY_IN_MIN = 10;
|
||||||
|
|
||||||
|
export const PRELOAD_ID = "preloadWallpaper";
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
BASE_CANVAS_SELECTOR,
|
BASE_CANVAS_SELECTOR,
|
||||||
BASE_VIDEO_SELECTOR,
|
BASE_VIDEO_SELECTOR,
|
||||||
|
PRELOAD_ID,
|
||||||
REDUCED_MOTION_PERCENT,
|
REDUCED_MOTION_PERCENT,
|
||||||
STABLE_DIFFUSION_DELAY_IN_MIN,
|
STABLE_DIFFUSION_DELAY_IN_MIN,
|
||||||
WALLPAPER_PATHS,
|
WALLPAPER_PATHS,
|
||||||
|
|
@ -41,6 +42,7 @@ import {
|
||||||
isYouTubeUrl,
|
isYouTubeUrl,
|
||||||
jsonFetch,
|
jsonFetch,
|
||||||
parseBgPosition,
|
parseBgPosition,
|
||||||
|
preloadImage,
|
||||||
viewWidth,
|
viewWidth,
|
||||||
} from "utils/functions";
|
} from "utils/functions";
|
||||||
|
|
||||||
|
|
@ -302,22 +304,18 @@ const useWallpaper = (
|
||||||
do {
|
do {
|
||||||
wallpaperUrl = slideshowFiles.shift() || "";
|
wallpaperUrl = slideshowFiles.shift() || "";
|
||||||
|
|
||||||
let [nextWallpaper] = slideshowFiles;
|
const [nextWallpaper] = slideshowFiles;
|
||||||
|
|
||||||
if (nextWallpaper) {
|
if (nextWallpaper) {
|
||||||
const preloadLink = document.createElement("link");
|
document.querySelector(`#${PRELOAD_ID}`)?.remove();
|
||||||
|
|
||||||
if (nextWallpaper.startsWith("/")) {
|
preloadImage(
|
||||||
nextWallpaper = `${window.location.origin}${nextWallpaper}`;
|
nextWallpaper.startsWith("/")
|
||||||
}
|
? `${window.location.origin}${nextWallpaper}`
|
||||||
|
: nextWallpaper,
|
||||||
preloadLink.id = "preloadWallpaper";
|
PRELOAD_ID,
|
||||||
preloadLink.href = nextWallpaper;
|
"auto"
|
||||||
preloadLink.rel = "preload";
|
);
|
||||||
preloadLink.as = "image";
|
|
||||||
|
|
||||||
document.querySelector("#preloadWallpaper")?.remove();
|
|
||||||
document.head.append(preloadLink);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wallpaperUrl.startsWith("/")) {
|
if (wallpaperUrl.startsWith("/")) {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ import {
|
||||||
getExtension,
|
getExtension,
|
||||||
getGifJs,
|
getGifJs,
|
||||||
getHtmlToImage,
|
getHtmlToImage,
|
||||||
|
getMimeType,
|
||||||
imageToBufferUrl,
|
imageToBufferUrl,
|
||||||
isSafari,
|
isSafari,
|
||||||
isYouTubeUrl,
|
isYouTubeUrl,
|
||||||
|
|
@ -146,61 +147,6 @@ export const getProcessByFileExtension = (extension: string): string => {
|
||||||
return defaultProcess;
|
return defaultProcess;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getMimeType = (url: string): string => {
|
|
||||||
switch (getExtension(url)) {
|
|
||||||
case ".ani":
|
|
||||||
case ".cur":
|
|
||||||
case ".ico":
|
|
||||||
return "image/vnd.microsoft.icon";
|
|
||||||
case ".jpg":
|
|
||||||
case ".jpeg":
|
|
||||||
return "image/jpeg";
|
|
||||||
case ".json":
|
|
||||||
return "application/json";
|
|
||||||
case ".html":
|
|
||||||
case ".htm":
|
|
||||||
case ".whtml":
|
|
||||||
return "text/html";
|
|
||||||
case ".m3u":
|
|
||||||
case ".m3u8":
|
|
||||||
return "application/x-mpegURL";
|
|
||||||
case ".m4v":
|
|
||||||
case ".mkv":
|
|
||||||
case ".mov":
|
|
||||||
case ".mp4":
|
|
||||||
return "video/mp4";
|
|
||||||
case ".mp3":
|
|
||||||
return "audio/mpeg";
|
|
||||||
case ".oga":
|
|
||||||
return "audio/ogg";
|
|
||||||
case ".ogg":
|
|
||||||
case ".ogm":
|
|
||||||
case ".ogv":
|
|
||||||
return "video/ogg";
|
|
||||||
case ".pdf":
|
|
||||||
return "application/pdf";
|
|
||||||
case ".png":
|
|
||||||
return "image/png";
|
|
||||||
case ".md":
|
|
||||||
case ".txt":
|
|
||||||
return "text/plain";
|
|
||||||
case ".wav":
|
|
||||||
return "audio/wav";
|
|
||||||
case ".webm":
|
|
||||||
return "video/webm";
|
|
||||||
case ".webp":
|
|
||||||
return "image/webp";
|
|
||||||
case ".xml":
|
|
||||||
return "application/xml";
|
|
||||||
case ".wsz":
|
|
||||||
case ".jsdos":
|
|
||||||
case ".zip":
|
|
||||||
return "application/zip";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getShortcutInfo = (
|
export const getShortcutInfo = (
|
||||||
contents?: Buffer,
|
contents?: Buffer,
|
||||||
shortcutData?: InternetShortcut
|
shortcutData?: InternetShortcut
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { type Position } from "react-rnd";
|
import { type Position } from "react-rnd";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { getMimeType } from "components/system/Files/FileEntry/functions";
|
|
||||||
import { type FocusEntryFunctions } from "components/system/Files/FileManager/useFocusableEntries";
|
import { type FocusEntryFunctions } from "components/system/Files/FileManager/useFocusableEntries";
|
||||||
import { useSession } from "contexts/session";
|
import { useSession } from "contexts/session";
|
||||||
import {
|
import {
|
||||||
getHtmlToImage,
|
getHtmlToImage,
|
||||||
|
getMimeType,
|
||||||
haltEvent,
|
haltEvent,
|
||||||
trimCanvasToTopLeft,
|
trimCanvasToTopLeft,
|
||||||
updateIconPositions,
|
updateIconPositions,
|
||||||
|
|
|
||||||
|
|
@ -456,7 +456,7 @@ const useFolderContextMenu = (
|
||||||
if (isMusicVisualizationRunning) {
|
if (isMusicVisualizationRunning) {
|
||||||
stopGlobalMusicVisualization?.();
|
stopGlobalMusicVisualization?.();
|
||||||
}
|
}
|
||||||
if (item.id) setWallpaper(item.id);
|
setWallpaper(item.id);
|
||||||
},
|
},
|
||||||
label: item.name || item.id,
|
label: item.name || item.id,
|
||||||
toggle: item.startsWith
|
toggle: item.startsWith
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,7 @@ import StyledTaskbarButton from "components/system/Taskbar/StyledTaskbarButton";
|
||||||
import { START_BUTTON_TITLE } from "components/system/Taskbar/functions";
|
import { START_BUTTON_TITLE } from "components/system/Taskbar/functions";
|
||||||
import useTaskbarContextMenu from "components/system/Taskbar/useTaskbarContextMenu";
|
import useTaskbarContextMenu from "components/system/Taskbar/useTaskbarContextMenu";
|
||||||
import { DIV_BUTTON_PROPS } from "utils/constants";
|
import { DIV_BUTTON_PROPS } from "utils/constants";
|
||||||
import {
|
import { label, preloadImage } from "utils/functions";
|
||||||
getDpi,
|
|
||||||
imageSrc,
|
|
||||||
imageSrcs,
|
|
||||||
isDynamicIcon,
|
|
||||||
label,
|
|
||||||
} from "utils/functions";
|
|
||||||
|
|
||||||
type StartButtonProps = {
|
type StartButtonProps = {
|
||||||
startMenuVisible: boolean;
|
startMenuVisible: boolean;
|
||||||
|
|
@ -27,47 +21,10 @@ const StartButton: FC<StartButtonProps> = ({
|
||||||
if (initalizedPreload.current) return;
|
if (initalizedPreload.current) return;
|
||||||
initalizedPreload.current = true;
|
initalizedPreload.current = true;
|
||||||
|
|
||||||
const supportsImageSrcSet = Object.prototype.hasOwnProperty.call(
|
|
||||||
HTMLLinkElement.prototype,
|
|
||||||
"imageSrcset"
|
|
||||||
);
|
|
||||||
const preloadedLinks = [
|
|
||||||
...document.querySelectorAll("link[rel=preload]"),
|
|
||||||
] as HTMLLinkElement[];
|
|
||||||
const startMenuIcons = (await import("public/.index/startMenuIcons.json"))
|
const startMenuIcons = (await import("public/.index/startMenuIcons.json"))
|
||||||
.default;
|
.default;
|
||||||
|
|
||||||
startMenuIcons?.forEach((icon) => {
|
startMenuIcons?.forEach((icon) => preloadImage(icon));
|
||||||
const link = document.createElement("link");
|
|
||||||
|
|
||||||
link.as = "image";
|
|
||||||
link.fetchPriority = "high";
|
|
||||||
link.rel = "preload";
|
|
||||||
link.type = "image/webp";
|
|
||||||
|
|
||||||
if (isDynamicIcon(icon)) {
|
|
||||||
if (supportsImageSrcSet) {
|
|
||||||
link.imageSrcset = imageSrcs(icon, 48, ".webp");
|
|
||||||
} else {
|
|
||||||
const [href] = imageSrc(icon, 48, getDpi(), ".webp").split(" ");
|
|
||||||
|
|
||||||
link.href = href;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
link.href = icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
!preloadedLinks.some(
|
|
||||||
(preloadedLink) =>
|
|
||||||
(link.imageSrcset &&
|
|
||||||
preloadedLink?.imageSrcset?.endsWith(link.imageSrcset)) ||
|
|
||||||
(link.href && preloadedLink?.href?.endsWith(link.href))
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
document.head.append(link);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
setPreloaded(true);
|
setPreloaded(true);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import type IZipFS from "browserfs/dist/node/backend/ZipFS";
|
||||||
import type IIsoFS from "browserfs/dist/node/backend/IsoFS";
|
import type IIsoFS from "browserfs/dist/node/backend/IsoFS";
|
||||||
import type * as IBrowserFS from "browserfs";
|
import type * as IBrowserFS from "browserfs";
|
||||||
import useTransferDialog from "components/system/Dialogs/Transfer/useTransferDialog";
|
import useTransferDialog from "components/system/Dialogs/Transfer/useTransferDialog";
|
||||||
import { getMimeType } from "components/system/Files/FileEntry/functions";
|
|
||||||
import {
|
import {
|
||||||
type InputChangeEvent,
|
type InputChangeEvent,
|
||||||
getEventData,
|
getEventData,
|
||||||
|
|
@ -36,7 +35,7 @@ import {
|
||||||
PROCESS_DELIMITER,
|
PROCESS_DELIMITER,
|
||||||
TRANSITIONS_IN_MILLISECONDS,
|
TRANSITIONS_IN_MILLISECONDS,
|
||||||
} from "utils/constants";
|
} from "utils/constants";
|
||||||
import { bufferToBlob, getExtension } from "utils/functions";
|
import { bufferToBlob, getExtension, getMimeType } from "utils/functions";
|
||||||
|
|
||||||
type FilePasteOperations = Record<string, "copy" | "move">;
|
type FilePasteOperations = Record<string, "copy" | "move">;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ export const imageSrc = (
|
||||||
ratio: number,
|
ratio: number,
|
||||||
extension: string
|
extension: string
|
||||||
): string => {
|
): string => {
|
||||||
const imageName = basename(imagePath, ".webp");
|
const imageName = basename(imagePath, extension);
|
||||||
const [expectedSize, maxIconSize] = MAX_RES_ICON_OVERRIDE[imageName] || [];
|
const [expectedSize, maxIconSize] = MAX_RES_ICON_OVERRIDE[imageName] || [];
|
||||||
const ratioSize = size * ratio;
|
const ratioSize = size * ratio;
|
||||||
const imageSize = Math.min(
|
const imageSize = Math.min(
|
||||||
|
|
@ -804,11 +804,119 @@ export const getYouTubeUrlId = (url: string): string => {
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getMimeType = (url: string): string => {
|
||||||
|
switch (getExtension(url)) {
|
||||||
|
case ".ani":
|
||||||
|
case ".cur":
|
||||||
|
case ".ico":
|
||||||
|
return "image/vnd.microsoft.icon";
|
||||||
|
case ".cache":
|
||||||
|
case ".jpg":
|
||||||
|
case ".jpeg":
|
||||||
|
return "image/jpeg";
|
||||||
|
case ".json":
|
||||||
|
return "application/json";
|
||||||
|
case ".html":
|
||||||
|
case ".htm":
|
||||||
|
case ".whtml":
|
||||||
|
return "text/html";
|
||||||
|
case ".m3u":
|
||||||
|
case ".m3u8":
|
||||||
|
return "application/x-mpegURL";
|
||||||
|
case ".m4v":
|
||||||
|
case ".mkv":
|
||||||
|
case ".mov":
|
||||||
|
case ".mp4":
|
||||||
|
return "video/mp4";
|
||||||
|
case ".mp3":
|
||||||
|
return "audio/mpeg";
|
||||||
|
case ".oga":
|
||||||
|
return "audio/ogg";
|
||||||
|
case ".ogg":
|
||||||
|
case ".ogm":
|
||||||
|
case ".ogv":
|
||||||
|
return "video/ogg";
|
||||||
|
case ".pdf":
|
||||||
|
return "application/pdf";
|
||||||
|
case ".png":
|
||||||
|
return "image/png";
|
||||||
|
case ".md":
|
||||||
|
case ".txt":
|
||||||
|
return "text/plain";
|
||||||
|
case ".wav":
|
||||||
|
return "audio/wav";
|
||||||
|
case ".webm":
|
||||||
|
return "video/webm";
|
||||||
|
case ".webp":
|
||||||
|
return "image/webp";
|
||||||
|
case ".xml":
|
||||||
|
return "application/xml";
|
||||||
|
case ".wsz":
|
||||||
|
case ".jsdos":
|
||||||
|
case ".zip":
|
||||||
|
return "application/zip";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isDynamicIcon = (icon?: string): boolean =>
|
||||||
|
typeof icon === "string" &&
|
||||||
|
(icon.startsWith(ICON_PATH) ||
|
||||||
|
(icon.startsWith(USER_ICON_PATH) && !icon.startsWith(ICON_CACHE)));
|
||||||
|
|
||||||
|
const getPreloadedLinks = (): HTMLLinkElement[] => [
|
||||||
|
...document.querySelectorAll<HTMLLinkElement>("link[rel=preload]"),
|
||||||
|
];
|
||||||
|
|
||||||
|
export const preloadImage = (
|
||||||
|
image: string,
|
||||||
|
id?: string,
|
||||||
|
fetchPriority: "auto" | "high" | "low" = "high"
|
||||||
|
): void => {
|
||||||
|
const extension = getExtension(image);
|
||||||
|
const link = document.createElement("link");
|
||||||
|
|
||||||
|
link.as = "image";
|
||||||
|
if (id) link.id = id;
|
||||||
|
link.fetchPriority = fetchPriority;
|
||||||
|
link.rel = "preload";
|
||||||
|
link.type = getMimeType(extension);
|
||||||
|
|
||||||
|
if (isDynamicIcon(image)) {
|
||||||
|
const supportsImageSrcSet = Object.prototype.hasOwnProperty.call(
|
||||||
|
HTMLLinkElement.prototype,
|
||||||
|
"imageSrcset"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (supportsImageSrcSet) {
|
||||||
|
link.imageSrcset = imageSrcs(image, 48, extension);
|
||||||
|
} else {
|
||||||
|
const [href] = imageSrc(image, 48, getDpi(), extension).split(" ");
|
||||||
|
|
||||||
|
link.href = href;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
link.href = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
const preloadedLinks = getPreloadedLinks();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!preloadedLinks.some(
|
||||||
|
(preloadedLink) =>
|
||||||
|
(link.imageSrcset &&
|
||||||
|
preloadedLink?.imageSrcset?.endsWith(link.imageSrcset)) ||
|
||||||
|
(link.href && preloadedLink?.href?.endsWith(link.href))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
document.head.append(link);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const preloadLibs = (libs: string[] = []): void => {
|
export const preloadLibs = (libs: string[] = []): void => {
|
||||||
const scripts = [...document.scripts];
|
const scripts = [...document.scripts];
|
||||||
const preloadedLinks = [
|
const preloadedLinks = getPreloadedLinks();
|
||||||
...document.querySelectorAll("link[rel=preload]"),
|
|
||||||
] as HTMLLinkElement[];
|
|
||||||
|
|
||||||
// eslint-disable-next-line unicorn/no-array-callback-reference
|
// eslint-disable-next-line unicorn/no-array-callback-reference
|
||||||
libs.map(encodeURI).forEach((lib) => {
|
libs.map(encodeURI).forEach((lib) => {
|
||||||
|
|
@ -877,11 +985,6 @@ export const generatePrettyTimestamp = (): string =>
|
||||||
export const isFileSystemMappingSupported = (): boolean =>
|
export const isFileSystemMappingSupported = (): boolean =>
|
||||||
typeof FileSystemHandle === "function" && "showDirectoryPicker" in window;
|
typeof FileSystemHandle === "function" && "showDirectoryPicker" in window;
|
||||||
|
|
||||||
export const isDynamicIcon = (icon?: string): boolean =>
|
|
||||||
typeof icon === "string" &&
|
|
||||||
(icon.startsWith(ICON_PATH) ||
|
|
||||||
(icon.startsWith(USER_ICON_PATH) && !icon.startsWith(ICON_CACHE)));
|
|
||||||
|
|
||||||
export const hasFinePointer = (): boolean =>
|
export const hasFinePointer = (): boolean =>
|
||||||
window.matchMedia("(pointer: fine)").matches;
|
window.matchMedia("(pointer: fine)").matches;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user