diff --git a/components/apps/Browser/config.ts b/components/apps/Browser/config.ts index d3e1e5dd..30225cc4 100644 --- a/components/apps/Browser/config.ts +++ b/components/apps/Browser/config.ts @@ -65,8 +65,6 @@ export const bookmarks: Bookmark[] = [ export const HOME_PAGE = "https://www.google.com/webhp?igu=1"; -export const LOCAL_HOST = new Set(["127.0.0.1", "localhost"]); - export const NOT_FOUND = '404 Not Found

Not Found

The requested URL was not found on this server.

'; diff --git a/components/apps/Browser/index.tsx b/components/apps/Browser/index.tsx index 475584b1..4f750caf 100644 --- a/components/apps/Browser/index.tsx +++ b/components/apps/Browser/index.tsx @@ -20,7 +20,6 @@ import StyledBrowser from "components/apps/Browser/StyledBrowser"; import { DINO_GAME, HOME_PAGE, - LOCAL_HOST, NOT_FOUND, PROXIES, bookmarks, @@ -41,6 +40,7 @@ import { } from "utils/constants"; import { GOOGLE_SEARCH_QUERY, + LOCAL_HOST, getExtension, getUrlOrSearch, haltEvent, diff --git a/components/apps/Photos/index.tsx b/components/apps/Photos/index.tsx index f63ff546..d6d16f55 100644 --- a/components/apps/Photos/index.tsx +++ b/components/apps/Photos/index.tsx @@ -16,7 +16,11 @@ import { useProcesses } from "contexts/process"; import { useViewport } from "contexts/viewport"; import useDoubleClick from "hooks/useDoubleClick"; import Button from "styles/common/Button"; -import { HIGH_PRIORITY_ELEMENT, IMAGE_FILE_EXTENSIONS } from "utils/constants"; +import { + HIGH_PRIORITY_ELEMENT, + IMAGE_FILE_EXTENSIONS, + NATIVE_IMAGE_FORMATS, +} from "utils/constants"; import { bufferToUrl, getExtension, @@ -24,7 +28,6 @@ import { haltEvent, label, } from "utils/functions"; -import { decodeImageToBuffer } from "utils/imageDecoder"; const { maxScale, minScale } = panZoomConfig; @@ -45,9 +48,15 @@ const Photos: FC = ({ id }) => { ); const { fullscreenElement, toggleFullscreen } = useViewport(); const loadPhoto = useCallback(async (): Promise => { - const fileContents = await readFile(url); + let fileContents = await readFile(url); const ext = getExtension(url); - const imageBuffer = await decodeImageToBuffer(ext, fileContents); + + if (!NATIVE_IMAGE_FORMATS.has(ext)) { + const { decodeImageToBuffer } = await import("utils/imageDecoder"); + const decodedData = await decodeImageToBuffer(ext, fileContents); + + if (decodedData) fileContents = decodedData; + } setSrc((currentSrc) => { const [currentUrl] = Object.keys(currentSrc); @@ -58,7 +67,7 @@ const Photos: FC = ({ id }) => { } return { - [url]: bufferToUrl(imageBuffer || fileContents, getMimeType(url)), + [url]: bufferToUrl(fileContents, getMimeType(url)), }; }); prependFileToTitle(basename(url)); diff --git a/components/system/Desktop/Wallpapers/types.ts b/components/system/Desktop/Wallpapers/types.ts index 6a9633c9..6a9ea7b8 100644 --- a/components/system/Desktop/Wallpapers/types.ts +++ b/components/system/Desktop/Wallpapers/types.ts @@ -14,7 +14,7 @@ declare global { export type WallpaperConfig = | Partial | Partial - | VantaWavesConfig; + | Partial; export type WallpaperFunc = ( el: HTMLElement | null, diff --git a/components/system/Desktop/Wallpapers/useWallpaper.ts b/components/system/Desktop/Wallpapers/useWallpaper.ts index 245825fb..dfe57c81 100644 --- a/components/system/Desktop/Wallpapers/useWallpaper.ts +++ b/components/system/Desktop/Wallpapers/useWallpaper.ts @@ -16,7 +16,6 @@ import { type WallpaperMessage, type WallpaperConfig, } from "components/system/Desktop/Wallpapers/types"; -import { config as vantaConfig } from "components/system/Desktop/Wallpapers/vantaWaves/config"; import { useFileSystem } from "contexts/fileSystem"; import { useSession } from "contexts/session"; import useWorker from "hooks/useWorker"; @@ -26,6 +25,7 @@ import { IMAGE_FILE_EXTENSIONS, MILLISECONDS_IN_DAY, MILLISECONDS_IN_MINUTE, + NATIVE_IMAGE_FORMATS, PICTURES_FOLDER, PROMPT_FILE, SLIDESHOW_FILE, @@ -63,7 +63,7 @@ const useWallpaper = ( ); const vantaWireframe = wallpaperImage === "VANTA WIREFRAME"; const wallpaperWorker = useWorker( - WALLPAPER_WORKERS[wallpaperName], + sessionLoaded ? WALLPAPER_WORKERS[wallpaperName] : undefined, undefined, vantaWireframe ? "Wireframe" : "" ); @@ -107,12 +107,13 @@ const useWallpaper = ( if (wallpaperName === "VANTA") { config = { - ...vantaConfig, - waveSpeed: - vantaConfig.waveSpeed * - (prefersReducedMotion ? REDUCED_MOTION_PERCENT : 1), + material: { + options: { + wireframe: vantaWireframe || !isTopWindow, + }, + }, + waveSpeed: prefersReducedMotion ? REDUCED_MOTION_PERCENT : 1, }; - vantaConfig.material.options.wireframe = vantaWireframe || !isTopWindow; } else if (wallpaperImage.startsWith("MATRIX")) { config = { animationSpeed: prefersReducedMotion ? REDUCED_MOTION_PERCENT : 1, @@ -374,14 +375,17 @@ const useWallpaper = ( } } } else if (await exists(wallpaperImage)) { - const { decodeImageToBuffer } = await import("utils/imageDecoder"); - const fileData = await readFile(wallpaperImage); - const imageBuffer = await decodeImageToBuffer( - getExtension(wallpaperImage), - fileData - ); + let fileData = await readFile(wallpaperImage); + const imgExt = getExtension(wallpaperImage); - wallpaperUrl = bufferToUrl(imageBuffer || fileData); + if (!NATIVE_IMAGE_FORMATS.has(imgExt)) { + const { decodeImageToBuffer } = await import("utils/imageDecoder"); + const decodedData = await decodeImageToBuffer(imgExt, fileData); + + if (decodedData) fileData = decodedData; + } + + wallpaperUrl = bufferToUrl(fileData); } if (wallpaperUrl) { diff --git a/components/system/Desktop/Wallpapers/vantaWaves/index.ts b/components/system/Desktop/Wallpapers/vantaWaves/index.ts index a203971f..b85ed754 100644 --- a/components/system/Desktop/Wallpapers/vantaWaves/index.ts +++ b/components/system/Desktop/Wallpapers/vantaWaves/index.ts @@ -1,5 +1,8 @@ import { type WallpaperConfig } from "components/system/Desktop/Wallpapers/types"; -import { disableControls } from "components/system/Desktop/Wallpapers/vantaWaves/config"; +import { + config as vantaConfig, + disableControls, +} from "components/system/Desktop/Wallpapers/vantaWaves/config"; import { type VantaWavesConfig } from "components/system/Desktop/Wallpapers/vantaWaves/types"; import { loadFiles } from "utils/functions"; @@ -28,10 +31,18 @@ const vantaWaves = ( if (WAVES) { try { + const { material, waveSpeed } = config as VantaWavesConfig; + const wavesConfig = { + ...vantaConfig, + waveSpeed: vantaConfig.waveSpeed * waveSpeed, + }; + + wavesConfig.material.options.wireframe = material.options.wireframe; + WAVES({ el, ...disableControls, - ...(config as VantaWavesConfig), + ...wavesConfig, }); } catch { fallback?.(); diff --git a/components/system/Desktop/Wallpapers/vantaWaves/wallpaper.worker.ts b/components/system/Desktop/Wallpapers/vantaWaves/wallpaper.worker.ts index 6d9c7e9a..d04e9ea3 100644 --- a/components/system/Desktop/Wallpapers/vantaWaves/wallpaper.worker.ts +++ b/components/system/Desktop/Wallpapers/vantaWaves/wallpaper.worker.ts @@ -1,7 +1,7 @@ import { type OffscreenRenderProps } from "components/system/Desktop/Wallpapers/types"; import { libs } from "components/system/Desktop/Wallpapers/vantaWaves"; import { - config, + config as vantaConfig, disableControls, } from "components/system/Desktop/Wallpapers/vantaWaves/config"; import { @@ -30,11 +30,7 @@ globalThis.addEventListener( waveEffect?.renderer.setSize(width, height); waveEffect?.resize(); } else { - const { - canvas, - config: offscreenConfig, - devicePixelRatio, - } = data as OffscreenRenderProps; + const { canvas, config, devicePixelRatio } = data as OffscreenRenderProps; const { VANTA: { current: currentEffect = waveEffect, WAVES } = {} } = globalThis; @@ -42,8 +38,16 @@ globalThis.addEventListener( if (currentEffect) currentEffect.destroy(); try { + const { material, waveSpeed } = config as VantaWavesConfig; + const wavesConfig = { + ...vantaConfig, + waveSpeed: vantaConfig.waveSpeed * waveSpeed, + }; + + wavesConfig.material.options.wireframe = material.options.wireframe; + waveEffect = WAVES({ - ...((offscreenConfig || config) as VantaWavesConfig), + ...wavesConfig, ...disableControls, canvas, devicePixelRatio, diff --git a/components/system/Files/FileEntry/functions.ts b/components/system/Files/FileEntry/functions.ts index 0e5823b5..ffc193a1 100644 --- a/components/system/Files/FileEntry/functions.ts +++ b/components/system/Files/FileEntry/functions.ts @@ -28,6 +28,7 @@ import { MAX_ICON_SIZE, MAX_THUMBNAIL_FILE_SIZE, MOUNTED_FOLDER_ICON, + NATIVE_IMAGE_FORMATS, NEW_FOLDER_ICON, ONE_TIME_PASSIVE_EVENT, PHOTO_ICON, @@ -365,14 +366,23 @@ export const getInfoWithExtension = ( getInfoByFileExtension(PHOTO_ICON, (signal) => fs.readFile(path, async (error, contents = Buffer.from("")) => { if (!error && contents.length > 0 && !signal.aborted) { - const { decodeImageToBuffer } = await import("utils/imageDecoder"); + let image = contents; + + if (!NATIVE_IMAGE_FORMATS.has(extension)) { + const { decodeImageToBuffer } = await import("utils/imageDecoder"); + + if (!signal.aborted) { + const decodedImage = await decodeImageToBuffer( + extension, + contents + ); + + if (decodedImage) image = decodedImage; + } + } if (!signal.aborted) { - const image = await decodeImageToBuffer(extension, contents); - - if (image && !signal.aborted) { - getInfoByFileExtension(bufferToUrl(image, getMimeType(path))); - } + getInfoByFileExtension(bufferToUrl(image, getMimeType(path))); } } }) diff --git a/components/system/Files/FileManager/Columns/index.tsx b/components/system/Files/FileManager/Columns/index.tsx index 7f38e0aa..fa4f8b4c 100644 --- a/components/system/Files/FileManager/Columns/index.tsx +++ b/components/system/Files/FileManager/Columns/index.tsx @@ -1,5 +1,6 @@ import { memo, useRef } from "react"; import { useTheme } from "styled-components"; +import dynamic from "next/dynamic"; import { sortFiles } from "components/system/Files/FileManager/functions"; import { type SortBy } from "components/system/Files/FileManager/useSortBy"; import StyledColumns from "components/system/Files/FileManager/Columns/StyledColumns"; @@ -11,7 +12,10 @@ import { } from "components/system/Files/FileManager/Columns/constants"; import { useSession } from "contexts/session"; import { type Files } from "components/system/Files/FileManager/useFolder"; -import { Down } from "components/apps/FileExplorer/NavigationIcons"; + +const Down = dynamic(() => + import("components/apps/FileExplorer/NavigationIcons").then((mod) => mod.Down) +); type ColumnsProps = { columns: ColumnsObject; diff --git a/components/system/Taskbar/Search/Icons.tsx b/components/system/Taskbar/Search/Icons.tsx index ba3f6bc5..abfbea95 100644 --- a/components/system/Taskbar/Search/Icons.tsx +++ b/components/system/Taskbar/Search/Icons.tsx @@ -1,25 +1,5 @@ import { memo } from "react"; -export const Search = memo(() => ( - - - -)); - export const RightArrow = memo(() => ( diff --git a/components/system/Taskbar/Search/SearchButton.tsx b/components/system/Taskbar/Search/SearchButton.tsx index 163d58c6..44d457ec 100644 --- a/components/system/Taskbar/Search/SearchButton.tsx +++ b/components/system/Taskbar/Search/SearchButton.tsx @@ -1,5 +1,5 @@ import { useTheme } from "styled-components"; -import { Search as SearchIcon } from "components/system/Taskbar/Search/Icons"; +import { memo } from "react"; import StyledTaskbarButton from "components/system/Taskbar/StyledTaskbarButton"; import { importSearch, @@ -15,6 +15,26 @@ type StartButtonProps = { toggleSearch: (showMenu?: boolean) => void; }; +const SearchIcon = memo(() => ( + + + +)); + const SearchButton: FC = ({ searchVisible, toggleSearch, diff --git a/contexts/fileSystem/core.ts b/contexts/fileSystem/core.ts index 41072900..44addac6 100644 --- a/contexts/fileSystem/core.ts +++ b/contexts/fileSystem/core.ts @@ -1,5 +1,5 @@ import { extname, join } from "path"; -import { openDB } from "idb"; +import { type openDB } from "idb"; import { type Mount, type ExtendedEmscriptenFileSystem, @@ -34,7 +34,7 @@ export const UNKNOWN_SIZE = -1; export const UNKNOWN_STATE_CODES = new Set(["EIO", "ENOENT"]); export const KEYVAL_STORE_NAME = "keyval"; -const KEYVAL_DB = `${KEYVAL_STORE_NAME}-store`; +export const KEYVAL_DB = `${KEYVAL_STORE_NAME}-store`; const IDX_SIZE = 1; const IDX_MTIME = 2; @@ -158,8 +158,28 @@ export const supportsIndexedDB = (): Promise => } }); -export const getKeyValStore = (): ReturnType => - openDB(KEYVAL_DB, 1, { +export const hasIndexedDB = async (name: string): Promise => + new Promise((resolve) => { + try { + const db = window.indexedDB.open(name); + + db.addEventListener("upgradeneeded", () => { + db.transaction?.abort(); + resolve(false); + }); + db.addEventListener("success", () => { + db.result.close(); + resolve(true); + }); + db.addEventListener("error", () => resolve(false)); + db.addEventListener("blocked", () => resolve(false)); + } catch { + resolve(false); + } + }); + +export const getKeyValStore = async (): ReturnType => + (await import("idb")).openDB(KEYVAL_DB, 1, { upgrade: (db) => db.createObjectStore(KEYVAL_STORE_NAME), }); diff --git a/contexts/fileSystem/useFileSystemContextState.ts b/contexts/fileSystem/useFileSystemContextState.ts index 11f4b91e..7717ebba 100644 --- a/contexts/fileSystem/useFileSystemContextState.ts +++ b/contexts/fileSystem/useFileSystemContextState.ts @@ -20,7 +20,9 @@ import { import { type NewPath } from "components/system/Files/FileManager/useFolder"; import { getFileSystemHandles, + hasIndexedDB, isMountedFolder, + KEYVAL_DB, } from "contexts/fileSystem/core"; import useAsyncFs, { type AsyncFS, @@ -617,25 +619,27 @@ const useFileSystemContextState = (): FileSystemContextState => { let mappedOntoDesktop = false; - await Promise.all( - Object.entries(await getFileSystemHandles()).map( - async ([handleDirectory, handle]) => { - if (!(await exists(handleDirectory))) { - try { - const mapDirectory = SYSTEM_DIRECTORIES.has(handleDirectory) - ? handleDirectory - : dirname(handleDirectory); + if (await hasIndexedDB(KEYVAL_DB)) { + await Promise.all( + Object.entries(await getFileSystemHandles()).map( + async ([handleDirectory, handle]) => { + if (!(await exists(handleDirectory))) { + try { + const mapDirectory = SYSTEM_DIRECTORIES.has(handleDirectory) + ? handleDirectory + : dirname(handleDirectory); - await mapFs(mapDirectory, handle); + await mapFs(mapDirectory, handle); - if (mapDirectory === DESKTOP_PATH) mappedOntoDesktop = true; - } catch { - // Ignore failure + if (mapDirectory === DESKTOP_PATH) mappedOntoDesktop = true; + } catch { + // Ignore failure + } } } - } - ) - ); + ) + ); + } if (mappedOntoDesktop) updateFolder(DESKTOP_PATH); }; diff --git a/utils/constants.ts b/utils/constants.ts index e3826e9a..45c9ab0b 100644 --- a/utils/constants.ts +++ b/utils/constants.ts @@ -96,14 +96,10 @@ export const TIFF_IMAGE_FORMATS = new Set([ export const CLIPBOARD_FILE_EXTENSIONS = new Set([".jpeg", ".jpg", ".png"]); -export const IMAGE_FILE_EXTENSIONS = new Set([ - ...HEIF_IMAGE_FORMATS, - ...TIFF_IMAGE_FORMATS, - ".ani", +export const NATIVE_IMAGE_FORMATS = new Set([ ".apng", ".avif", ".bmp", - ".cur", ".gif", ".ico", ".jfif", @@ -111,16 +107,24 @@ export const IMAGE_FILE_EXTENSIONS = new Set([ ".jpe", ".jpeg", ".jpg", - ".jxl", ".pjp", ".pjpeg", ".png", ".svg", - ".qoi", ".webp", ".xbm", ]); +export const IMAGE_FILE_EXTENSIONS = new Set([ + ...NATIVE_IMAGE_FORMATS, + ...HEIF_IMAGE_FORMATS, + ...TIFF_IMAGE_FORMATS, + ".ani", + ".cur", + ".jxl", + ".qoi", +]); + export const UNSUPPORTED_SLIDESHOW_EXTENSIONS = new Set([ ...HEIF_IMAGE_FORMATS, ...TIFF_IMAGE_FORMATS, diff --git a/utils/functions.ts b/utils/functions.ts index 51ab7006..3900274d 100644 --- a/utils/functions.ts +++ b/utils/functions.ts @@ -26,9 +26,6 @@ import { TIMESTAMP_DATE_FORMAT, USER_ICON_PATH, } from "utils/constants"; -import { LOCAL_HOST } from "components/apps/Browser/config"; - -export const GOOGLE_SEARCH_QUERY = "https://www.google.com/search?igu=1&q="; export const bufferToBlob = (buffer: Buffer, type?: string): Blob => new Blob([buffer], type ? { type } : undefined); @@ -805,6 +802,9 @@ export const getTZOffsetISOString = (): string => { ).toISOString(); }; +export const LOCAL_HOST = new Set(["127.0.0.1", "localhost"]); +export const GOOGLE_SEARCH_QUERY = "https://www.google.com/search?igu=1&q="; + export const getUrlOrSearch = async (input: string): Promise => { const isIpfs = input.startsWith("ipfs://"); const hasHttpSchema =