mirror of
https://github.com/DustinBrett/daedalOS.git
synced 2026-01-15 12:15:02 +00:00
Browser search, icon & html support
This commit is contained in:
@@ -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<HTMLInputElement | null>(null);
|
||||
const iframeRef = useRef<HTMLIFrameElement | null>(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<void> => {
|
||||
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 => {
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
onLoad={() => setLoading(false)}
|
||||
srcDoc={srcDoc || undefined}
|
||||
style={{ backgroundColor: srcDoc ? "#fff" : "initial" }}
|
||||
title={id}
|
||||
{...config}
|
||||
/>
|
||||
|
||||
@@ -5,6 +5,10 @@ type Extension = {
|
||||
};
|
||||
|
||||
const extensions = {
|
||||
".html": {
|
||||
process: ["Browser", "MonacoEditor"],
|
||||
type: "HTML Document",
|
||||
},
|
||||
".img": {
|
||||
icon: "image",
|
||||
process: ["V86"],
|
||||
|
||||
@@ -14,7 +14,10 @@ const StyledIcon = styled.img.attrs<IconProps>(
|
||||
draggable: false,
|
||||
height: displaySize || imgSize,
|
||||
src:
|
||||
!src || src.startsWith("blob:")
|
||||
!src ||
|
||||
src.startsWith("blob:") ||
|
||||
src.startsWith("http:") ||
|
||||
src.startsWith("https:")
|
||||
? src
|
||||
: join(dirname(src), `${imgSize}x${imgSize}`, basename(src)),
|
||||
width: displaySize || imgSize,
|
||||
|
||||
@@ -98,3 +98,11 @@ export const getTimezoneOffsetISOString = (): string => {
|
||||
date.getTime() - date.getTimezoneOffset() * 60000
|
||||
).toISOString();
|
||||
};
|
||||
|
||||
export const isValidUrl = (url: string): boolean => {
|
||||
try {
|
||||
return typeof new URL(url) === "object";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user