Added virtual drive (WIP)

This commit is contained in:
Prozilla 2023-07-21 18:23:41 +02:00
parent 9db8ffc2e0
commit a2dd052658
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
11 changed files with 334 additions and 15 deletions

View file

@ -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

View file

@ -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.

178
package-lock.json generated
View file

@ -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",

View file

@ -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"
}
}

View file

@ -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";

View file

@ -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";

View file

@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useState } from "react";
import styles from "./Terminal.module.css";
import { Command } from "./commands.js";

View file

@ -0,0 +1,24 @@
import { createContext, useContext } from "react";
import { VirtualDrive } from "../modules/virtual-drive/virtual-drive.js";
const VirtualDriveContext = createContext();
/**
* @returns {React.Provider<any>}
*/
export function VirtualDriveProvider({ children }) {
const virtualDrive = new VirtualDrive();
return (
<VirtualDriveContext.Provider value={virtualDrive}>
{children}
</VirtualDriveContext.Provider>
);
}
/**
* @returns {VirtualDrive}
*/
export function useWindowsManager() {
return useContext(VirtualDriveContext);
}

View file

@ -0,0 +1,7 @@
import { VirtualFolder } from "./virtual-folder.js";
export class VirtualDrive extends VirtualFolder {
constructor() {
}
}

View file

@ -0,0 +1,6 @@
export class VirtualFile {
constructor(name, extension) {
this.name = name;
this.extension = extension;
}
}

View file

@ -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);
}
})
}
}