From a2dd0526584ad07d7c627aa88e724d54b532a196 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Fri, 21 Jul 2023 18:23:41 +0200 Subject: [PATCH] Added virtual drive (WIP) --- docs/README.md | 7 + docs/contributing/README.md | 11 +- package-lock.json | 178 ++++++++++++++++++ package.json | 12 +- src/App.js | 2 +- src/components/TaskBar.js | 2 +- .../applications/terminal/Terminal.js | 2 +- src/hooks/VirtualDriveContext.js | 24 +++ src/modules/virtual-drive/virtual-drive.js | 7 + src/modules/virtual-drive/virtual-file.js | 6 + src/modules/virtual-drive/virtual-folder.js | 98 ++++++++++ 11 files changed, 334 insertions(+), 15 deletions(-) create mode 100644 src/hooks/VirtualDriveContext.js create mode 100644 src/modules/virtual-drive/virtual-drive.js create mode 100644 src/modules/virtual-drive/virtual-file.js create mode 100644 src/modules/virtual-drive/virtual-folder.js diff --git a/docs/README.md b/docs/README.md index abf198b..30d3e16 100644 --- a/docs/README.md +++ b/docs/README.md @@ -22,6 +22,13 @@ 1. Run `npm run build`, which will compile all the necessary files to the `build` directory. 2. Upload the contents of the `build` directory to your web server's root folder. +#### Deploy to GitHub Pages + +1. Change the "homepage" property in [package.json](../package.json) to your domain. +2. Make sure the package `gh-pages` is installed. +2. Run `npm run deploy` - This will create a new build by running the redeploy script and then push the build folder to a branch called `gh-pages`. +3. Configure your GitHub Pages to deploy the `gh-pages` branch. + ### Structure - [src](../src) directory diff --git a/docs/contributing/README.md b/docs/contributing/README.md index 17c6130..a3a1c4a 100644 --- a/docs/contributing/README.md +++ b/docs/contributing/README.md @@ -1,13 +1,4 @@ # Contributing -1. Fork this repository. -2. Make and test changes. -3. Create a pull request. -4. Pat yourself on the back. +You can contribute by reporting bugs, suggesting new features, etc. by [creating a new issue](/../../issues). -Alternatively, if you feel like you can't contribute to this project in this way, you can contribute by reporting bugs, suggesting new features, etc. by [creating a new issue](/../../issues). - -## Contribution guidelines - -- Make sure the changes you make are in line with the style of the rest of the project. -- Make sure whatever you add or change is valuable. diff --git a/package-lock.json b/package-lock.json index a43032c..60782cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,12 +15,16 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "core-js": "^3.31.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-draggable": "^4.4.5", "react-scripts": "5.0.1", "react-svg": "^16.1.18", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "gh-pages": "^5.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -5193,6 +5197,15 @@ "node": ">=8" } }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array.prototype.flat": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", @@ -7073,6 +7086,12 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.460.tgz", "integrity": "sha512-kKiHnbrHME7z8E6AYaw0ehyxY5+hdaRmeUbjBO22LZMdqTYCO29EvF0T1cQ3pJ1RN5fyMcHl1Lmcsdt9WWJpJQ==" }, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, "node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -8219,6 +8238,32 @@ "node": ">=10" } }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.1", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/filesize": { "version": "8.0.7", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", @@ -8675,6 +8720,94 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gh-pages": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-5.0.0.tgz", + "integrity": "sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==", + "dev": true, + "dependencies": { + "async": "^3.2.4", + "commander": "^2.18.0", + "email-addresses": "^5.0.0", + "filenamify": "^4.3.0", + "find-cache-dir": "^3.3.1", + "fs-extra": "^8.1.0", + "globby": "^6.1.0" + }, + "bin": { + "gh-pages": "bin/gh-pages.js", + "gh-pages-clean": "bin/gh-pages-clean.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gh-pages/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gh-pages/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/gh-pages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/gh-pages/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gh-pages/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/gh-pages/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -12867,6 +13000,27 @@ "node": ">=0.10.0" } }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -15793,6 +15947,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/style-loader": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", @@ -16276,6 +16442,18 @@ "node": ">=8" } }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", diff --git a/package.json b/package.json index 7e996f6..e2ac09f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,9 @@ { "name": "prozilla-os", "version": "0.1.0", - "private": true, + "private": false, + "author": "Prozilla", + "homepage": "https://os.prozilla.dev/", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0", @@ -10,6 +12,7 @@ "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", + "core-js": "^3.31.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-draggable": "^4.4.5", @@ -21,7 +24,9 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "predeploy": "npm run build", + "deploy": "gh-pages -d build -m \"Deployed build to GitHub Pages\"" }, "eslintConfig": { "extends": [ @@ -40,5 +45,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "gh-pages": "^5.0.0" } } diff --git a/src/App.js b/src/App.js index 94a9eb9..7775cc8 100644 --- a/src/App.js +++ b/src/App.js @@ -1,5 +1,5 @@ import "./App.css"; -import { Taskbar } from "./components/Taskbar.js"; +import { Taskbar } from "./components/TaskBar.js"; import { WindowsManagerProvider } from "./hooks/WindowsManagerContext.js"; import { WindowsView } from "./components/WindowsView.js"; diff --git a/src/components/TaskBar.js b/src/components/TaskBar.js index 5804920..00f1c48 100644 --- a/src/components/TaskBar.js +++ b/src/components/TaskBar.js @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import "./Taskbar.css"; +import "./TaskBar.css"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons"; import ApplicationsManager from "../modules/applications/applications.js"; diff --git a/src/components/applications/terminal/Terminal.js b/src/components/applications/terminal/Terminal.js index 69d2a63..173deef 100644 --- a/src/components/applications/terminal/Terminal.js +++ b/src/components/applications/terminal/Terminal.js @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import styles from "./Terminal.module.css"; import { Command } from "./commands.js"; diff --git a/src/hooks/VirtualDriveContext.js b/src/hooks/VirtualDriveContext.js new file mode 100644 index 0000000..e292de2 --- /dev/null +++ b/src/hooks/VirtualDriveContext.js @@ -0,0 +1,24 @@ +import { createContext, useContext } from "react"; +import { VirtualDrive } from "../modules/virtual-drive/virtual-drive.js"; + +const VirtualDriveContext = createContext(); + +/** + * @returns {React.Provider} + */ +export function VirtualDriveProvider({ children }) { + const virtualDrive = new VirtualDrive(); + + return ( + + {children} + + ); +} + +/** + * @returns {VirtualDrive} + */ +export function useWindowsManager() { + return useContext(VirtualDriveContext); +} \ No newline at end of file diff --git a/src/modules/virtual-drive/virtual-drive.js b/src/modules/virtual-drive/virtual-drive.js new file mode 100644 index 0000000..f824517 --- /dev/null +++ b/src/modules/virtual-drive/virtual-drive.js @@ -0,0 +1,7 @@ +import { VirtualFolder } from "./virtual-folder.js"; + +export class VirtualDrive extends VirtualFolder { + constructor() { + + } +} \ No newline at end of file diff --git a/src/modules/virtual-drive/virtual-file.js b/src/modules/virtual-drive/virtual-file.js new file mode 100644 index 0000000..4e17c4f --- /dev/null +++ b/src/modules/virtual-drive/virtual-file.js @@ -0,0 +1,6 @@ +export class VirtualFile { + constructor(name, extension) { + this.name = name; + this.extension = extension; + } +} \ No newline at end of file diff --git a/src/modules/virtual-drive/virtual-folder.js b/src/modules/virtual-drive/virtual-folder.js new file mode 100644 index 0000000..1806e5f --- /dev/null +++ b/src/modules/virtual-drive/virtual-folder.js @@ -0,0 +1,98 @@ +import { VirtualFile } from "./virtual-file.js"; + +export class VirtualFolder { + static TYPE = { + GENERAL: 0, + MEDIA: 1, + } + + /** + * @param {String} name + * @param {Number} type + */ + constructor(name, type) { + this.name = name; + this.subFolders = []; + this.files = []; + this.type = type ?? this.TYPE.GENERAL; + } + + // add(element) { + + // } + + hasFile(name, extension) { + let exists = false; + + this.files.forEach(({ name: fileName, extension: fileExtension }) => { + if (fileName === name && fileExtension === extension) { + return exists = true; + } + }); + + return exists; + } + + hasFolder(name) { + let exists = false; + + this.folders.forEach(({ name: folderName }) => { + if (folderName === name) { + return exists = true; + } + }); + + return exists; + } + + createFile(name, extension) { + const file = new VirtualFile(name, extension); + this.files.push(file); + file.parent = this; + } + + createFolder(name) { + const newFolder = new VirtualFolder(name); + this.subFolders.push(newFolder); + newFolder.parent = this; + } + + /** + * @param {String} destination + */ + addFile(destination) { + const folderNames = destination.split("/"); + const fileExtendedName = folderNames.pop().split(); + const fileExtendedNameSegments = fileExtendedName.split("."); + + const fileName = fileExtendedNameSegments[0]; + const fileExtension = fileExtendedNameSegments.length > 1 ? fileExtendedNameSegments[1] : "txt"; + + // To do: check if file already exists + + const file = new VirtualFile(fileName, fileExtension); + + const folders = this.addFolder(folderNames.join("/")); + + const parent = folders[folders.length - 1]; + parent.files.push(file); + file.parent = parent; + } + + /** + * @param {String} destination + */ + addFolder(destination) { + if (destination.endsWith("/")) + destination = destination.slice(0, -1); + + const folderNames = destination.split("/"); + + let currentFolder = this; + folderNames.forEach((folderName) => { + if (!currentFolder.hasFolder(folderName)) { + currentFolder.createFolder(folderName); + } + }) + } +} \ No newline at end of file