From 2fab7d51931dd9b7c3d0ea25a274d62b336f0893 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Sun, 17 Dec 2023 14:39:24 +0100 Subject: [PATCH] Added interactable component --- package.json | 1 + public/documents/links.md | 15 ++ .../applications/.common/HeaderMenu.jsx | 2 +- .../file-explorer/FileExplorer.jsx | 46 ++++-- .../directory-list/DirectoryList.jsx | 147 ++++++++++++++++-- .../directory-list/DirectoryList.module.css | 21 ++- .../applications/media-viewer/MediaViewer.jsx | 2 +- .../applications/settings/AboutSettings.jsx | 2 +- .../applications/settings/StorageSettings.jsx | 4 +- src/components/desktop/Desktop.jsx | 40 +++-- src/components/taskbar/menus/HomeMenu.jsx | 2 +- src/components/utils/{ => button}/Button.jsx | 0 .../utils/{ => button}/Button.module.css | 0 .../{ => dropdown-button}/DropdownButton.jsx | 4 +- .../DropdownButton.module.css | 0 .../utils/interactable/Interactable.jsx | 34 ++++ .../utils/{ => progress-bar}/ProgressBar.jsx | 2 +- .../{ => progress-bar}/ProgressBar.module.css | 0 src/constants/applications/settings.js | 2 +- src/constants/utils.js | 1 + src/features/applications/application.js | 2 +- src/features/virtual-drive/defaultData.js | 117 ++++++++++++++ src/features/virtual-drive/virtualBase.js | 2 +- src/features/virtual-drive/virtualFolder.js | 6 +- src/features/virtual-drive/virtualRoot.js | 99 +----------- 25 files changed, 386 insertions(+), 165 deletions(-) create mode 100644 public/documents/links.md rename src/components/utils/{ => button}/Button.jsx (100%) rename src/components/utils/{ => button}/Button.module.css (100%) rename src/components/utils/{ => dropdown-button}/DropdownButton.jsx (89%) rename src/components/utils/{ => dropdown-button}/DropdownButton.module.css (100%) create mode 100644 src/components/utils/interactable/Interactable.jsx rename src/components/utils/{ => progress-bar}/ProgressBar.jsx (91%) rename src/components/utils/{ => progress-bar}/ProgressBar.module.css (100%) create mode 100644 src/constants/utils.js create mode 100644 src/features/virtual-drive/defaultData.js diff --git a/package.json b/package.json index 177da2a..6cfa4d5 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "error", "double" ], + "object-curly-spacing": ["warn", "always"], "default-case": "off", "arrow-parens": "error", "space-infix-ops": "warn", diff --git a/public/documents/links.md b/public/documents/links.md new file mode 100644 index 0000000..a553811 --- /dev/null +++ b/public/documents/links.md @@ -0,0 +1,15 @@ +# Links + +**ProzillaOS** + +- GitHub: https://github.com/Prozilla/Prozilla-OS + +**Prozilla** + +- Website: https://prozilla.dev/ +- Ko-fi: https://ko-fi.com/prozilla + +**Crumbling City** + +- Website: https://daisygames.org/crumbling-city/ +- Steam page: https://store.steampowered.com/app/1520290/Crumbling_City/ \ No newline at end of file diff --git a/src/components/applications/.common/HeaderMenu.jsx b/src/components/applications/.common/HeaderMenu.jsx index eb800b7..76d8304 100644 --- a/src/components/applications/.common/HeaderMenu.jsx +++ b/src/components/applications/.common/HeaderMenu.jsx @@ -1,5 +1,5 @@ import { useShortcuts } from "../../../hooks/utils/keyboard.js"; -import { DropdownButton } from "../../utils/DropdownButton.jsx"; +import { DropdownButton } from "../../utils/dropdown-button/DropdownButton.jsx"; import styles from "./HeaderMenu.module.css"; /** diff --git a/src/components/applications/file-explorer/FileExplorer.jsx b/src/components/applications/file-explorer/FileExplorer.jsx index ec0b80e..0c9601b 100644 --- a/src/components/applications/file-explorer/FileExplorer.jsx +++ b/src/components/applications/file-explorer/FileExplorer.jsx @@ -112,6 +112,20 @@ export function FileExplorer({ startPath, app, modalsManager }) { const directory = virtualRoot.navigate(value); + if (directory == null) { + openWindowedModal({ + title: "Error", + iconUrl: AppsManager.getAppIconUrl(APPS.FILE_EXPLORER), + size: new Vector2(300, 150), + Modal: (props) => + +

Invalid path: "{value}"

+ +
+ }); + return; + } + setCurrentDirectory(directory); setPath(directory.root ? "/" : directory.path); } @@ -185,24 +199,24 @@ export function FileExplorer({ startPath, app, modalsManager }) {
{ changeDirectory("~"); }} icon={faHouse}/> { changeDirectory("~/Desktop"); }} icon={faDesktop}/> - { changeDirectory("~/Images"); }} icon={faImage}/> + { changeDirectory("~/Pictures"); }} icon={faImage}/> { changeDirectory("~/Documents"); }} icon={faFileLines}/>
-
- { - event.preventDefault(); - windowsManager.openFile(file); - }} - onClickFolder={(event, folder) => { - changeDirectory(folder.linkedPath ?? folder.name); - }} - onContextMenuFile={onContextMenuFile} - onContextMenuFolder={onContextMenuFolder} - /> -
+ { + event.preventDefault(); + windowsManager.openFile(file, { mode: "view" }); + }} + onClickFolder={(event, folder) => { + changeDirectory(folder.linkedPath ?? folder.name); + }} + onContextMenuFile={onContextMenuFile} + onContextMenuFolder={onContextMenuFolder} + />

diff --git a/src/components/applications/file-explorer/directory-list/DirectoryList.jsx b/src/components/applications/file-explorer/directory-list/DirectoryList.jsx index bc67dff..f7c3441 100644 --- a/src/components/applications/file-explorer/directory-list/DirectoryList.jsx +++ b/src/components/applications/file-explorer/directory-list/DirectoryList.jsx @@ -1,5 +1,7 @@ +import { useEffect, useRef, useState } from "react"; import { VirtualFile } from "../../../../features/virtual-drive/virtualFile.js"; import { VirtualFolder } from "../../../../features/virtual-drive/virtualFolder.js"; +import { Interactable } from "../../../utils/interactable/Interactable.jsx"; import styles from "./DirectoryList.module.css"; import { ImagePreview } from "./ImagePreview.jsx"; @@ -19,36 +21,145 @@ import { ImagePreview } from "./ImagePreview.jsx"; * @param {object} props * @param {VirtualFolder} props.directory * @param {boolean} props.showHidden - * @param {string} props.folderClassname - * @param {string} props.fileClassname + * @param {string} props.folderClassName + * @param {string} props.fileClassName + * @param {string} props.className * @param {fileEvent} props.onContextMenuFile * @param {folderEvent} props.onContextMenuFolder * @param {fileEvent} props.onClickFile * @param {folderEvent} props.onClickFolder */ -export function DirectoryList({ directory, showHidden = false, folderClassname, fileClassname, - onContextMenuFile, onContextMenuFolder, onClickFile, onClickFolder }) { - if (!directory) - return null; +export function DirectoryList({ directory, showHidden = false, folderClassName, fileClassName, className, + onContextMenuFile, onContextMenuFolder, onClickFile, onClickFolder, ...props }) { + const [selectedFolders, setSelectedFolders] = useState([]); + const [selectedFiles, setSelectedFiles] = useState([]); + const ref = useRef(null); + const [rectSelectStart, setRectSelectStart] = useState(null); + const [rectSelectEnd, setRectSelectEnd] = useState(null); + + useEffect(() => { + clearSelection(); + }, [directory]); + + useEffect(() => { + const onMoveRectSelect = (event) => { + if (rectSelectStart == null) + return; + + event.preventDefault(); + setRectSelectEnd({ x: event.clientX, y: event.clientY }); + }; + const onStopRectSelect = (event) => { + if (rectSelectStart == null || rectSelectEnd == null) { + setRectSelectStart(null); + setRectSelectEnd(null); + return; + } + + event.preventDefault(); + setRectSelectStart(null); + setRectSelectEnd(null); + }; + + document.addEventListener("mousemove", onMoveRectSelect); + document.addEventListener("pointermove", onMoveRectSelect); + document.addEventListener("mouseup", onStopRectSelect); + document.addEventListener("pointerup", onStopRectSelect); + + return () => { + document.removeEventListener("mousemove", onMoveRectSelect); + document.removeEventListener("pointermove", onMoveRectSelect); + document.removeEventListener("mouseup", onStopRectSelect); + document.removeEventListener("pointerup", onStopRectSelect); + }; + }); + + if (!directory) + return; + + const clearSelection = () => { + setSelectedFolders([]); + setSelectedFiles([]); + }; + const selectFolder = (folder, exclusive = false) => { + setSelectedFolders(exclusive ? [folder.id] : [...selectedFolders, folder.id]); + if (exclusive) + setSelectedFiles([]); + }; + const selectFile = (file, exclusive = false) => { + setSelectedFiles(exclusive ? [file.id] : [...selectedFiles, file.id]); + if (exclusive) + setSelectedFolders([]); + }; + + const onStartRectSelect = (event) => { + setRectSelectStart({ x: event.clientX, y: event.clientY }); + }; + const getRectSelectStyle = () => { + let x, y, width, height = null; + const containerRect = ref.current?.getBoundingClientRect(); + + if (rectSelectStart.x < rectSelectEnd.x) { + x = rectSelectStart.x; + width = rectSelectEnd.x - rectSelectStart.x; + } else { + x = rectSelectEnd.x; + width = rectSelectStart.x - rectSelectEnd.x; + } + if (rectSelectStart.y < rectSelectEnd.y) { + y = rectSelectStart.y; + height = rectSelectEnd.y - rectSelectStart.y; + } else { + y = rectSelectEnd.y; + height = rectSelectStart.y - rectSelectEnd.y; + } + + if (containerRect) { + x -= containerRect.x; + y -= containerRect.y; + } + + + return { top: y, left: x, width, height }; + }; + + const classNames = [styles.Container]; const folderClassNames = [styles["Folder-button"]]; const fileClassNames = [styles["File-button"]]; - if (folderClassname) - folderClassNames.push(folderClassname); - if (fileClassname) - fileClassNames.push(fileClassname); + if (className) + classNames.push(className); + if (folderClassName) + folderClassNames.push(folderClassName); + if (fileClassName) + fileClassNames.push(fileClassName); - return <> + return

+ {rectSelectStart != null && rectSelectEnd != null + ?
+ : null + } {directory?.getSubFolders(showHidden)?.map((folder) => -

{folder.name}

- + )} {directory?.getFiles(showHidden)?.map((file) => -

{file.id}

- + )} - ; + ; } \ No newline at end of file diff --git a/src/components/applications/file-explorer/directory-list/DirectoryList.module.css b/src/components/applications/file-explorer/directory-list/DirectoryList.module.css index dc76e85..e25f190 100644 --- a/src/components/applications/file-explorer/directory-list/DirectoryList.module.css +++ b/src/components/applications/file-explorer/directory-list/DirectoryList.module.css @@ -1,3 +1,9 @@ +.Container { + position: relative; + width: 100%; + height: 100%; +} + .File-button, .Folder-button { display: flex; gap: 0.25rem; @@ -15,11 +21,16 @@ transition: background-color 100ms ease-in-out; } +.File-button[data-selected=true], +.Folder-button[data-selected=true] { + background-color: hsla(var(--background-color-a-hsl), 40%) !important; +} + .File-button:hover, .Folder-button:hover, .File-button:focus-visible, .Folder-button:focus-visible { - background-color: hsla(var(--background-color-a-hsl), 35%); + background-color: hsla(var(--background-color-a-hsl), 20%); } .File-button p, .Folder-button p { @@ -37,4 +48,12 @@ width: 50%; height: auto; aspect-ratio: 1; +} + +.Selection-rect { + opacity: 25%; + position: absolute; + border-radius: 0.25rem; + background-color: var(--blue-b); + border: 0.25rem solid var(--blue-a); } \ No newline at end of file diff --git a/src/components/applications/media-viewer/MediaViewer.jsx b/src/components/applications/media-viewer/MediaViewer.jsx index 95d1322..40a177d 100644 --- a/src/components/applications/media-viewer/MediaViewer.jsx +++ b/src/components/applications/media-viewer/MediaViewer.jsx @@ -17,7 +17,7 @@ export function MediaViewer({ file, close, setTitle }) { if (file == null) { setTimeout(() => { - windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Images" }); + windowsManager.open(APPS.FILE_EXPLORER, { startPath: "~/Pictures" }); close(); }, 10); return; diff --git a/src/components/applications/settings/AboutSettings.jsx b/src/components/applications/settings/AboutSettings.jsx index 8f74830..9a21633 100644 --- a/src/components/applications/settings/AboutSettings.jsx +++ b/src/components/applications/settings/AboutSettings.jsx @@ -1,4 +1,4 @@ -import { Button } from "../../utils/Button.jsx"; +import { Button } from "../../utils/button/Button.jsx"; import styles from "./Settings.module.css"; import utilStyles from "../../../styles/utils.module.css"; import Vector2 from "../../../features/math/vector2.js"; diff --git a/src/components/applications/settings/StorageSettings.jsx b/src/components/applications/settings/StorageSettings.jsx index 83277e9..98a5c57 100644 --- a/src/components/applications/settings/StorageSettings.jsx +++ b/src/components/applications/settings/StorageSettings.jsx @@ -1,8 +1,8 @@ import styles from "./Settings.module.css"; import utilStyles from "../../../styles/utils.module.css"; import { round } from "../../../features/math/round.js"; -import { ProgressBar } from "../../utils/ProgressBar.jsx"; -import { Button } from "../../utils/Button.jsx"; +import { ProgressBar } from "../../utils/progress-bar/ProgressBar.jsx"; +import { Button } from "../../utils/button/Button.jsx"; import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.js"; import { StorageManager } from "../../../features/storage/storageManager.js"; diff --git a/src/components/desktop/Desktop.jsx b/src/components/desktop/Desktop.jsx index 2f1e916..c8ce8d3 100644 --- a/src/components/desktop/Desktop.jsx +++ b/src/components/desktop/Desktop.jsx @@ -85,29 +85,27 @@ export const Desktop = memo(() => { onContextMenu={onContextMenu} > -
- { - event.preventDefault(); + { + event.preventDefault(); - const options = {}; - if (file.name === "info.md") { - options.mode = "view"; - options.size = new Vector2(575, 675); - } + const options = { mode: "view" }; + if (file.name === "info.md") { + options.size = new Vector2(575, 675); + } - windowsManager.openFile(file, options); - }} - onClickFolder={(event, { linkedPath, path }) => { - windowsManager.open(APPS.FILE_EXPLORER, { startPath: linkedPath ?? path }); - }} - onContextMenuFile={onContextMenuFile} - onContextMenuFolder={onContextMenuFolder} - /> -
+ windowsManager.openFile(file, options); + }} + onClickFolder={(event, { linkedPath, path }) => { + windowsManager.open(APPS.FILE_EXPLORER, { startPath: linkedPath ?? path }); + }} + onContextMenuFile={onContextMenuFile} + onContextMenuFolder={onContextMenuFolder} + /> {wallpaper ? Desktop wallpaper : null diff --git a/src/components/taskbar/menus/HomeMenu.jsx b/src/components/taskbar/menus/HomeMenu.jsx index 47c6a94..30092ab 100644 --- a/src/components/taskbar/menus/HomeMenu.jsx +++ b/src/components/taskbar/menus/HomeMenu.jsx @@ -83,7 +83,7 @@ export function HomeMenu({ active, setActive, search }) { diff --git a/src/components/utils/Button.jsx b/src/components/utils/button/Button.jsx similarity index 100% rename from src/components/utils/Button.jsx rename to src/components/utils/button/Button.jsx diff --git a/src/components/utils/Button.module.css b/src/components/utils/button/Button.module.css similarity index 100% rename from src/components/utils/Button.module.css rename to src/components/utils/button/Button.module.css diff --git a/src/components/utils/DropdownButton.jsx b/src/components/utils/dropdown-button/DropdownButton.jsx similarity index 89% rename from src/components/utils/DropdownButton.jsx rename to src/components/utils/dropdown-button/DropdownButton.jsx index b5f0b67..8f37533 100644 --- a/src/components/utils/DropdownButton.jsx +++ b/src/components/utils/dropdown-button/DropdownButton.jsx @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; import styles from "./DropdownButton.module.css"; -import OutsideClickListener from "../../hooks/utils/outsideClick.js"; -import { formatShortcut } from "../../features/utils/string.js"; +import OutsideClickListener from "../../../hooks/utils/outsideClick.js"; +import { formatShortcut } from "../../../features/utils/string.js"; /** * @param {object} props diff --git a/src/components/utils/DropdownButton.module.css b/src/components/utils/dropdown-button/DropdownButton.module.css similarity index 100% rename from src/components/utils/DropdownButton.module.css rename to src/components/utils/dropdown-button/DropdownButton.module.css diff --git a/src/components/utils/interactable/Interactable.jsx b/src/components/utils/interactable/Interactable.jsx new file mode 100644 index 0000000..17790e6 --- /dev/null +++ b/src/components/utils/interactable/Interactable.jsx @@ -0,0 +1,34 @@ +import { useState } from "react"; +import { INTERACTIBLE_DOUBLE_CLICK_DELAY } from "../../../constants/utils.js"; + +let timeoutId = null; + +export function Interactable({ onClick, onDoubleClick, children, ...props }) { + const [clicked, setClicked] = useState(false); + + const onButtonClick = (event) => { + event.preventDefault(); + event.stopPropagation(); + + if (timeoutId != null) + clearTimeout(timeoutId); + + if (clicked) { + setClicked(false); + onDoubleClick?.(event); + + return; + } + + setClicked(true); + onClick?.(event); + + timeoutId = setTimeout(() => { + setClicked(false); + }, INTERACTIBLE_DOUBLE_CLICK_DELAY); + }; + + return ; +} \ No newline at end of file diff --git a/src/components/utils/ProgressBar.jsx b/src/components/utils/progress-bar/ProgressBar.jsx similarity index 91% rename from src/components/utils/ProgressBar.jsx rename to src/components/utils/progress-bar/ProgressBar.jsx index c7fd3c9..4a0d239 100644 --- a/src/components/utils/ProgressBar.jsx +++ b/src/components/utils/progress-bar/ProgressBar.jsx @@ -1,4 +1,4 @@ -import { clamp } from "../../features/math/clamp.js"; +import { clamp } from "../../../features/math/clamp.js"; import styles from "./ProgressBar.module.css"; /** diff --git a/src/components/utils/ProgressBar.module.css b/src/components/utils/progress-bar/ProgressBar.module.css similarity index 100% rename from src/components/utils/ProgressBar.module.css rename to src/components/utils/progress-bar/ProgressBar.module.css diff --git a/src/constants/applications/settings.js b/src/constants/applications/settings.js index f218aa6..d718f97 100644 --- a/src/constants/applications/settings.js +++ b/src/constants/applications/settings.js @@ -1 +1 @@ -export const WALLPAPERS_PATH = "~/Images/Wallpapers"; \ No newline at end of file +export const WALLPAPERS_PATH = "~/Pictures/Wallpapers"; \ No newline at end of file diff --git a/src/constants/utils.js b/src/constants/utils.js new file mode 100644 index 0000000..725ba52 --- /dev/null +++ b/src/constants/utils.js @@ -0,0 +1 @@ +export const INTERACTIBLE_DOUBLE_CLICK_DELAY = 250; \ No newline at end of file diff --git a/src/features/applications/application.js b/src/features/applications/application.js index 1216178..a50c142 100644 --- a/src/features/applications/application.js +++ b/src/features/applications/application.js @@ -15,7 +15,7 @@ export default class Application { } WindowContent = (props) => { - props = {...props, ...this.windowOptions}; + props = { ...props, ...this.windowOptions }; if (this.windowContent == null) { return null; diff --git a/src/features/virtual-drive/defaultData.js b/src/features/virtual-drive/defaultData.js new file mode 100644 index 0000000..a9924b3 --- /dev/null +++ b/src/features/virtual-drive/defaultData.js @@ -0,0 +1,117 @@ +import { APPS } from "../../constants/applications.js"; +import { WALLPAPERS } from "../../constants/desktop.js"; +import AppsManager from "../applications/applications.js"; +import { VirtualRoot } from "./virtualRoot.js"; + +/** + * Loads default data on the virtual root + * @param {VirtualRoot} virtualRoot + */ +export function loadDefaultData(virtualRoot) { + virtualRoot.createFolder("bin", (folder) => { + folder.createFiles([ + { name: "echo" }, + { name: "cd" }, + { name: "ls" }, + { name: "clear" }, + ]); + }); + + virtualRoot.createFolder("dev", (folder) => { + folder.createFiles([ + { name: "null" }, + { name: "zero" }, + { name: "random" }, + ]); + }); + + virtualRoot.createFolder("etc"); + + virtualRoot.createFolder("usr", (folder) => { + folder.createFolders(["bin", "sbin", "lib", "share"]); + }); + + const linkedPaths = {}; + + virtualRoot.createFolder("home", (folder) => { + folder.createFolder("prozilla-os", (folder) => { + folder.setAlias("~") + .createFolder(".config", (folder) => { + folder.createFile("desktop", "xml", (file) => { + file.setSource("/config/desktop.xml"); + }).createFile("taskbar", "xml", (file) => { + file.setSource("/config/taskbar.xml"); + }); + }) + .createFolder("Pictures", (folder) => { + folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-images")); + folder.createFolder("Wallpapers", (folder) => { + folder.setProtected(true); + for (let i = 0; i < WALLPAPERS.length; i++) { + const source = WALLPAPERS[i]; + folder.createFile(`Wallpaper${i + 1}`, "png", (file) => { + file.setSource(source); + }); + } + }).createFile("ProzillaOS", "png", (file) => { + file.setSource("/assets/banner-logo-title.png"); + }).createFolder("Crumbling City", (folder) => { + folder.createFile("Japan", "png", (file) => { + file.setSource("https://daisygames.org/media/Games/Crumbling%20City/CrumblingCityRelease.png"); + }).createFile("City Center", "png", (file) => { + file.setSource("https://daisygames.org/media/Games/Crumbling%20City/Screenshot_City_Firegun.png"); + }).createFile("Farms", "png", (file) => { + file.setSource("https://daisygames.org/media/Games/Crumbling%20City/Screenshot_Farms_Hammer.png"); + }); + }); + linkedPaths.images = folder.path; + }) + .createFolder("Documents", (folder) => { + folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-text")); + folder.createFile("text", "txt", (file) => { + file.setContent("Hello world!"); + }).createFile("info", "md", (file) => { + file.setProtected(true) + .setSource("/documents/info.md") + .setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file-info")); + linkedPaths.info = file.path; + }).createFile("links", "md", (file) => { + file.setProtected(true) + .setSource("/documents/links.md"); + linkedPaths.links = file.path; + }); + linkedPaths.documents = folder.path; + }) + .createFolder("Desktop", (folder) => { + folder.createFileLink("info.md", (fileLink) => { + fileLink.setLinkedPath(linkedPaths.info); + }).createFileLink("links.md", (fileLink) => { + fileLink.setLinkedPath(linkedPaths.links); + }).createFolderLink("Pictures", (folderLink) => { + folderLink.setLinkedPath(linkedPaths.images); + }).createFolderLink("Documents", (folderLink) => { + folderLink.setLinkedPath(linkedPaths.documents); + }); + }); + }); + }); + + virtualRoot.createFolder("lib"); + virtualRoot.createFolder("sbin"); + virtualRoot.createFolder("tmp"); + virtualRoot.createFolder("var"); + virtualRoot.createFolder("boot"); + + virtualRoot.createFolder("proc", (folder) => { + folder.createFiles([ + { name: "cpuinfo" }, + { name: "meminfo" }, + ]); + }); + + virtualRoot.createFolder("var"); + virtualRoot.createFolder("opt"); + virtualRoot.createFolder("media"); + virtualRoot.createFolder("mnt"); + virtualRoot.createFolder("srv"); +} \ No newline at end of file diff --git a/src/features/virtual-drive/virtualBase.js b/src/features/virtual-drive/virtualBase.js index 5cefc8c..584107e 100644 --- a/src/features/virtual-drive/virtualBase.js +++ b/src/features/virtual-drive/virtualBase.js @@ -32,7 +32,7 @@ export class VirtualBase extends EventEmitter { /** * @param {string} alias - * @returns {ThisType} + * @returns {VirtualBase} */ setAlias(alias) { if (this.alias === alias || !this.canBeEdited) diff --git a/src/features/virtual-drive/virtualFolder.js b/src/features/virtual-drive/virtualFolder.js index 60c7d87..2016348 100644 --- a/src/features/virtual-drive/virtualFolder.js +++ b/src/features/virtual-drive/virtualFolder.js @@ -29,7 +29,7 @@ export class VirtualFolder extends VirtualBase { /** * @param {string} alias - * @returns {ThisType} + * @returns {VirtualFolder} */ setAlias(alias) { return super.setAlias(alias); @@ -39,7 +39,7 @@ export class VirtualFolder extends VirtualBase { * Returns true if this folder contains a file matching a name and extension * @param {string} name * @param {string} extension - * @returns {ThisType} + * @returns {VirtualFolder} */ hasFile(name, extension) { return this.findFile(name, extension) !== null; @@ -130,7 +130,7 @@ export class VirtualFolder extends VirtualBase { if (!this.canBeEdited) return; - files.forEach(({name, extension}) => { + files.forEach(({ name, extension }) => { this.createFile(name, extension); }); diff --git a/src/features/virtual-drive/virtualRoot.js b/src/features/virtual-drive/virtualRoot.js index 09e2328..91d216b 100644 --- a/src/features/virtual-drive/virtualRoot.js +++ b/src/features/virtual-drive/virtualRoot.js @@ -1,8 +1,6 @@ -import { APPS } from "../../constants/applications.js"; -import { WALLPAPERS } from "../../constants/desktop.js"; -import AppsManager from "../applications/applications.js"; import { StorageManager } from "../storage/storageManager.js"; import { VirtualFolderLink } from "./VirtualFolderLink.js"; +import { loadDefaultData } from "./defaultData.js"; import { VirtualFile } from "./virtualFile.js"; import { VirtualFolder } from "./virtualFolder.js"; @@ -24,98 +22,7 @@ export class VirtualRoot extends VirtualFolder { } loadDefaultData() { - this.createFolder("bin", (folder) => { - folder.createFiles([ - { name: "echo" }, - { name: "cd" }, - { name: "ls" }, - { name: "clear" }, - ]); - }); - - this.createFolder("dev", (folder) => { - folder.createFiles([ - { name: "null" }, - { name: "zero" }, - { name: "random" }, - ]); - }); - - this.createFolder("etc"); - - this.createFolder("usr", (folder) => { - folder.createFolders(["bin", "sbin", "lib", "share"]); - }); - - const linkedPaths = {}; - - this.createFolder("home", (folder) => { - folder.createFolder("prozilla-os", (folder) => { - folder.setAlias("~") - .createFolder(".config", (folder) => { - folder.createFile("desktop", "xml", (file) => { - file.setSource("/config/desktop.xml"); - }).createFile("taskbar", "xml", (file) => { - file.setSource("/config/taskbar.xml"); - }); - }) - .createFolder("Images", (folder) => { - folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-images")); - folder.createFolder("Wallpapers", (folder) => { - folder.setProtected(true); - for (let i = 0; i < WALLPAPERS.length; i++) { - const source = WALLPAPERS[i]; - folder.createFile(`Wallpaper${i + 1}`, "png", (file) => { - file.setSource(source); - }); - } - }).createFile("ProzillaOS", "png", (file) => { - file.setSource("/assets/banner-logo-title.png"); - }); - linkedPaths.images = folder.path; - }) - .createFolder("Documents", (folder) => { - folder.setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "folder-text")); - folder.createFile("text", "txt", (file) => { - file.setContent("Hello world!"); - }).createFile("info", "md", (file) => { - file.setProtected(true) - .setSource("/documents/info.md") - .setIconUrl(AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file-info")); - linkedPaths.info = file.path; - }); - linkedPaths.documents = folder.path; - }) - .createFolder("Desktop", (folder) => { - folder.createFileLink("info.md", (fileLink) => { - fileLink.setLinkedPath(linkedPaths.info); - }).createFolderLink("Images", (folderLink) => { - folderLink.setLinkedPath(linkedPaths.images); - }).createFolderLink("Documents", (folderLink) => { - folderLink.setLinkedPath(linkedPaths.documents); - }); - }); - }); - }); - - this.createFolder("lib"); - this.createFolder("sbin"); - this.createFolder("tmp"); - this.createFolder("var"); - this.createFolder("boot"); - - this.createFolder("proc", (folder) => { - folder.createFiles([ - { name: "cpuinfo" }, - { name: "meminfo" }, - ]); - }); - - this.createFolder("var"); - this.createFolder("opt"); - this.createFolder("media"); - this.createFolder("mnt"); - this.createFolder("srv"); + loadDefaultData(this); } loadData() { @@ -132,7 +39,7 @@ export class VirtualRoot extends VirtualFolder { if (object == null) return; - const shortcuts = {...object.scs}; + const shortcuts = { ...object.scs }; const addFile = ({ nam: name,