Added file explorer interface

This commit is contained in:
Prozilla 2023-07-26 07:34:27 +02:00
parent 3768995852
commit 716f21d3fb
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
3 changed files with 203 additions and 1 deletions

View file

@ -0,0 +1,86 @@
import { useState } from "react";
import { useVirtualRoot } from "../../../hooks/virtual-drive/VirtualRootContext.js";
import styles from "./FileExplorer.module.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowUp, faCaretLeft, faCaretRight, faCog, faDesktop, faFileLines, faHouse, faImage, faSearch } from "@fortawesome/free-solid-svg-icons";
export function FileExplorer() {
const virtualRoot = useVirtualRoot();
const [currentDirectory, setCurrentDirectory] = useState(virtualRoot.navigate("~"));
const [path, setPath] = useState(currentDirectory.path);
const changeDirectory = (path, absolute = false) => {
const directory = absolute ? virtualRoot.navigate(path) : currentDirectory.navigate(path);
console.log(directory);
if (directory) {
setCurrentDirectory(directory);
setPath(directory.path);
}
}
const onPathChange = (event) => {
return setPath(event.target.value);
}
const onKeyDown = (event) => {
const value = event.target.value;
if (event.key === "Enter") {
setCurrentDirectory(virtualRoot.navigate(value));
}
};
return (
<div className={styles.Container}>
<div className={styles.Header}>
<button className={styles["Icon-button"]}>
<FontAwesomeIcon icon={faCaretLeft}/>
</button>
<button className={styles["Icon-button"]}>
<FontAwesomeIcon icon={faCaretRight}/>
</button>
<button className={styles["Icon-button"]} onClick={() => { changeDirectory(".."); }}>
<FontAwesomeIcon icon={faArrowUp}/>
</button>
<input
value={path}
type="text"
className={styles["Path-input"]}
onChange={onPathChange}
onKeyDown={onKeyDown}
/>
<button className={styles["Icon-button"]}>
<FontAwesomeIcon icon={faSearch}/>
</button>
<button className={styles["Icon-button"]}>
<FontAwesomeIcon icon={faCog}/>
</button>
</div>
<div className={styles.Body}>
<div className={styles.Sidebar}>
<button className={styles["Nav-button"]} onClick={() => { changeDirectory("~"); }}>
<FontAwesomeIcon icon={faHouse}/>
Home
</button>
<button className={styles["Nav-button"]} onClick={() => { changeDirectory("~/Desktop"); }}>
<FontAwesomeIcon icon={faDesktop}/>
Desktop
</button>
<button className={styles["Nav-button"]} onClick={() => { changeDirectory("~/Documents"); }}>
<FontAwesomeIcon icon={faFileLines}/>
Documents
</button>
<button className={styles["Nav-button"]} onClick={() => { changeDirectory("~/Images"); }}>
<FontAwesomeIcon icon={faImage}/>
Images
</button>
</div>
<div className={styles.Main}>
</div>
</div>
</div>
);
}

View file

@ -0,0 +1,115 @@
.Container {
--header-height: 3.5rem;
--sidebar-width: 10rem;
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.Header {
display: flex;
gap: 1rem;
align-items: center;
width: 100%;
height: var(--header-height);
padding: 1rem;
background-color: var(--background-color-a);
}
.Icon-button {
position: relative;
height: 1.25rem;
width: auto;
padding: 0;
color: var(--foreground-a);
background: none;
border: none;
outline: none;
aspect-ratio: 1;
cursor: pointer;
}
.Icon-button::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0%);
border-radius: 9999px;
transform: scale(100%);
transform-origin: center;
transition: all 200ms ease-in-out;
}
.Icon-button:hover::after {
background-color: rgba(255, 255, 255, 10%);
transform: scale(150%);
}
.Icon-button svg {
height: 100%;
}
.Path-input {
flex: 1;
padding: 0.25rem 0.5rem;
background-color: var(--background-color-c);
border: none;
border-radius: 0.5rem;
outline: none;
font-family: inherit;
font-size: inherit;
}
.Body {
flex: 1;
display: flex;
width: 100%;
background-color: var(--background-color-c);
}
.Sidebar {
display: flex;
gap: 0.25rem;
flex-direction: column;
min-width: calc(var(--sidebar-width) / 2);
width: var(--sidebar-width);
height: 100%;
max-width: 50%;
padding: 0.5rem;
background-color: var(--background-color-b);
resize: horizontal;
overflow: hidden;
}
.Nav-button {
display: flex;
gap: 0.5rem;
align-items: center;
width: 100%;
padding: 0.5rem;
background: none;
border: none;
border-radius: 0.5rem;
outline: none;
cursor: pointer;
transition: background-color 200ms ease-in-out;
}
.Nav-button:hover {
background-color: rgba(255, 255, 255, 10%);
}
.Nav-button svg {
height: 1.35rem;
aspect-ratio: 1;
}
.Main {
flex: 1;
height: 100%;
}

View file

@ -1,4 +1,5 @@
/* eslint-disable eqeqeq */
import { FileExplorer } from "../../components/applications/file-explorer/FileExplorer.jsx";
import { WebView } from "../../components/applications/templates/WebView.jsx";
import { Terminal } from "../../components/applications/terminal/Terminal.jsx";
import Application from "./application.js";
@ -8,7 +9,7 @@ export default class ApplicationsManager {
new Application("Terminal", "terminal", <Terminal/>),
// new Application("Browser", "browser"),
new Application("Code Editor", "code-editor"),
new Application("File Explorer", "file-explorer"),
new Application("File Explorer", "file-explorer", <FileExplorer/>),
new Application("Media Viewer", "media-viewer"),
new Application("Wordle", "wordle", <WebView source="https://prozilla.dev/wordle"/>),
new Application("Balls", "balls", <WebView source="https://prozilla.dev/ball-maze"/>),