From 447d8b47ca49fe1f956a63752042e00dd8e7650b Mon Sep 17 00:00:00 2001 From: Dustin Brett Date: Sat, 13 Nov 2021 22:57:25 -0800 Subject: [PATCH] Browser search, icon & html support --- components/apps/Browser/index.tsx | 49 ++++++++++++++++--- .../system/Files/FileEntry/extensions.ts | 4 ++ styles/common/Icon.tsx | 5 +- utils/functions.ts | 8 +++ 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/components/apps/Browser/index.tsx b/components/apps/Browser/index.tsx index d8f0dd9c..fb5ade96 100644 --- a/components/apps/Browser/index.tsx +++ b/components/apps/Browser/index.tsx @@ -2,13 +2,19 @@ import { config, HOME_PAGE } from "components/apps/Browser/config"; import { Arrow, Refresh, Stop } from "components/apps/Browser/NavigationIcons"; import StyledBrowser from "components/apps/Browser/StyledBrowser"; import type { ComponentProcessProps } from "components/system/Apps/RenderComponent"; +import { useFileSystem } from "contexts/fileSystem"; import { useProcesses } from "contexts/process"; +import processDirectory from "contexts/process/directory"; +import { extname } from "path"; import { useCallback, useEffect, useRef, useState } from "react"; import Button from "styles/common/Button"; +import { ONE_TIME_PASSIVE_EVENT } from "utils/constants"; +import { isValidUrl } from "utils/functions"; import useHistory from "utils/useHistory"; const Browser = ({ id }: ComponentProcessProps): JSX.Element => { const { + icon: setIcon, url: changeUrl, processes: { [id]: process }, } = useProcesses(); @@ -16,22 +22,49 @@ const Browser = ({ id }: ComponentProcessProps): JSX.Element => { const initialUrl = url || HOME_PAGE; const { canGoBack, canGoForward, history, moveHistory, position } = useHistory(initialUrl, id); + const { exists, readFile } = useFileSystem(); const inputRef = useRef(null); const iframeRef = useRef(null); const [loading, setLoading] = useState(false); + const [srcDoc, setSrcDoc] = useState(""); const changeHistory = (step: number): void => { moveHistory(step); if (inputRef.current) inputRef.current.value = history[position + step]; }; - const setUrl = useCallback((newUrl: string): void => { - const { contentWindow } = iframeRef.current || {}; + const setUrl = useCallback( + async (addressInput: string): Promise => { + const { contentWindow } = iframeRef.current || {}; - if (contentWindow?.location) { - setLoading(true); - contentWindow.location.replace(newUrl); - } - }, []); + if (contentWindow?.location) { + const isHtml = + extname(addressInput) === ".html" && (await exists(addressInput)); + + setLoading(true); + setSrcDoc(isHtml ? (await readFile(addressInput)).toString() : ""); + setIcon(id, processDirectory["Browser"].icon); + + if (!isHtml) { + const addressUrl = isValidUrl(addressInput) + ? addressInput + : `https://www.google.com/search?igu=1&q=${addressInput}`; + + contentWindow.location.replace(addressUrl); + + const favicon = new Image(); + const faviconUrl = `${new URL(addressUrl).origin}/favicon.ico`; + + favicon.addEventListener( + "load", + () => setIcon(id, faviconUrl), + ONE_TIME_PASSIVE_EVENT + ); + favicon.src = faviconUrl; + } + } + }, + [exists, id, readFile, setIcon] + ); useEffect(() => { setUrl(history[position]); @@ -79,6 +112,8 @@ const Browser = ({ id }: ComponentProcessProps): JSX.Element => {