Added file explorer interface
This commit is contained in:
parent
3768995852
commit
716f21d3fb
3 changed files with 203 additions and 1 deletions
86
src/components/applications/file-explorer/FileExplorer.jsx
Normal file
86
src/components/applications/file-explorer/FileExplorer.jsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -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%;
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/* eslint-disable eqeqeq */
|
/* eslint-disable eqeqeq */
|
||||||
|
import { FileExplorer } from "../../components/applications/file-explorer/FileExplorer.jsx";
|
||||||
import { WebView } from "../../components/applications/templates/WebView.jsx";
|
import { WebView } from "../../components/applications/templates/WebView.jsx";
|
||||||
import { Terminal } from "../../components/applications/terminal/Terminal.jsx";
|
import { Terminal } from "../../components/applications/terminal/Terminal.jsx";
|
||||||
import Application from "./application.js";
|
import Application from "./application.js";
|
||||||
|
|
@ -8,7 +9,7 @@ export default class ApplicationsManager {
|
||||||
new Application("Terminal", "terminal", <Terminal/>),
|
new Application("Terminal", "terminal", <Terminal/>),
|
||||||
// new Application("Browser", "browser"),
|
// new Application("Browser", "browser"),
|
||||||
new Application("Code Editor", "code-editor"),
|
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("Media Viewer", "media-viewer"),
|
||||||
new Application("Wordle", "wordle", <WebView source="https://prozilla.dev/wordle"/>),
|
new Application("Wordle", "wordle", <WebView source="https://prozilla.dev/wordle"/>),
|
||||||
new Application("Balls", "balls", <WebView source="https://prozilla.dev/ball-maze"/>),
|
new Application("Balls", "balls", <WebView source="https://prozilla.dev/ball-maze"/>),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue