ProzillaOS/packages/apps/browser/components/Browser.tsx
2024-06-16 21:46:44 +02:00

114 lines
No EOL
3 KiB
TypeScript

import { ChangeEventHandler, KeyboardEventHandler, useEffect, useRef, useState } from "react";
import styles from "./Browser.module.css";
import { WebView } from "../_utils/web-view/WebView";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretLeft, faCaretRight, faHome, faRotateRight } from "@fortawesome/free-solid-svg-icons";
import { HOME_URL, SEARCH_URL } from "../../../config/apps/browser.config";
import { isValidUrl } from "../../../features/_utils/browser.utils";
import { useHistory } from "../../../hooks/_utils/history";
import { WindowProps } from "../../windows/WindowView";
interface BrowserProps extends WindowProps {
url?: string;
}
export function Browser({ url: startUrl = HOME_URL, focus }: BrowserProps) {
const [url, setUrl] = useState<string>(startUrl);
const [input, setInput] = useState(startUrl);
const { history, pushState, stateIndex, undo, redo, undoAvailable, redoAvailable } = useHistory(startUrl);
const ref = useRef<HTMLIFrameElement>(null);
useEffect(() => {
if (history.length === 0)
return;
setUrl(history[stateIndex]);
}, [history, stateIndex]);
const reload = () => {
if (ref.current == null || ref.current.contentWindow == null)
return;
ref.current.contentWindow.location.href = url;
};
const updateUrl = (newUrl: string) => {
if (url === newUrl) {
return reload();
}
setUrl(newUrl);
setInput(newUrl);
pushState(newUrl);
};
const onInputChange = (event: Event) => {
setInput((event.target as HTMLInputElement).value);
};
const onKeyDown = (event: KeyboardEvent) => {
const value = (event.target as HTMLInputElement).value;
if (event.key === "Enter" && value !== "") {
if (isValidUrl(value)) {
updateUrl(value);
} else {
updateUrl(`${SEARCH_URL}&q=${value}`);
}
}
};
return (<div className={styles.Browser}>
<div className={styles.Header}>
<div className={styles.NavBar}>
<button
title="Back"
tabIndex={0}
className={styles.IconButton}
onClick={() => { undo(); }}
disabled={!undoAvailable}
>
<FontAwesomeIcon icon={faCaretLeft}/>
</button>
<button
title="Forward"
tabIndex={0}
className={styles.IconButton}
onClick={() => { redo(); }}
disabled={!redoAvailable}
>
<FontAwesomeIcon icon={faCaretRight}/>
</button>
<button
title="Reload"
tabIndex={0}
className={styles.IconButton}
onClick={reload}
>
<FontAwesomeIcon icon={faRotateRight}/>
</button>
<button
title="Home"
tabIndex={0}
className={styles.IconButton}
onClick={() => { updateUrl(HOME_URL); }}
>
<FontAwesomeIcon icon={faHome}/>
</button>
<input
value={input}
type="text"
aria-label="Search bar"
className={styles.SearchBar}
tabIndex={0}
onChange={onInputChange as unknown as ChangeEventHandler}
onKeyDown={onKeyDown as unknown as KeyboardEventHandler}
/>
</div>
<div className={styles.Bookmarks}>
</div>
</div>
<WebView ref={ref} source={url} title="Browser" focus={focus}/>
</div>);
}