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. 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. 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 ### Structure
- [src](../src) directory - [src](../src) directory

View file

@ -1,13 +1,4 @@
# Contributing # Contributing
1. Fork this repository. You can contribute by reporting bugs, suggesting new features, etc. by [creating a new issue](/../../issues).
2. Make and test changes.
3. Create a pull request.
4. Pat yourself on the back.
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/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"core-js": "^3.31.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-draggable": "^4.4.5", "react-draggable": "^4.4.5",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-svg": "^16.1.18", "react-svg": "^16.1.18",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
},
"devDependencies": {
"gh-pages": "^5.0.0"
} }
}, },
"node_modules/@aashutoshrathi/word-wrap": { "node_modules/@aashutoshrathi/word-wrap": {
@ -5193,6 +5197,15 @@
"node": ">=8" "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": { "node_modules/array.prototype.flat": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", "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", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.460.tgz",
"integrity": "sha512-kKiHnbrHME7z8E6AYaw0ehyxY5+hdaRmeUbjBO22LZMdqTYCO29EvF0T1cQ3pJ1RN5fyMcHl1Lmcsdt9WWJpJQ==" "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": { "node_modules/emittery": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz",
@ -8219,6 +8238,32 @@
"node": ">=10" "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": { "node_modules/filesize": {
"version": "8.0.7", "version": "8.0.7",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz",
@ -8675,6 +8720,94 @@
"url": "https://github.com/sponsors/ljharb" "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": { "node_modules/glob": {
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@ -12867,6 +13000,27 @@
"node": ">=0.10.0" "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": { "node_modules/pirates": {
"version": "4.0.6", "version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
@ -15793,6 +15947,18 @@
"url": "https://github.com/sponsors/sindresorhus" "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": { "node_modules/style-loader": {
"version": "3.3.3", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz",
@ -16276,6 +16442,18 @@
"node": ">=8" "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": { "node_modules/tryer": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",

View file

@ -1,7 +1,9 @@
{ {
"name": "prozilla-os", "name": "prozilla-os",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": false,
"author": "Prozilla",
"homepage": "https://os.prozilla.dev/",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.4.0", "@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0", "@fortawesome/free-regular-svg-icons": "^6.4.0",
@ -10,6 +12,7 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0", "@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"core-js": "^3.31.1",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-draggable": "^4.4.5", "react-draggable": "^4.4.5",
@ -21,7 +24,9 @@
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"test": "react-scripts test", "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": { "eslintConfig": {
"extends": [ "extends": [
@ -40,5 +45,8 @@
"last 1 firefox version", "last 1 firefox version",
"last 1 safari version" "last 1 safari version"
] ]
},
"devDependencies": {
"gh-pages": "^5.0.0"
} }
} }

View file

@ -1,5 +1,5 @@
import "./App.css"; import "./App.css";
import { Taskbar } from "./components/Taskbar.js"; import { Taskbar } from "./components/TaskBar.js";
import { WindowsManagerProvider } from "./hooks/WindowsManagerContext.js"; import { WindowsManagerProvider } from "./hooks/WindowsManagerContext.js";
import { WindowsView } from "./components/WindowsView.js"; import { WindowsView } from "./components/WindowsView.js";

View file

@ -1,5 +1,5 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import "./Taskbar.css"; import "./TaskBar.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons"; import { faBatteryFull, faSearch, faVolumeHigh, faWifi } from "@fortawesome/free-solid-svg-icons";
import ApplicationsManager from "../modules/applications/applications.js"; 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 styles from "./Terminal.module.css";
import { Command } from "./commands.js"; 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);
}
})
}
}