Added linting rules + updated docs
This commit is contained in:
parent
6f990ba66a
commit
e223747795
35 changed files with 298 additions and 99 deletions
|
|
@ -33,6 +33,10 @@
|
|||
2. Run `npm run deploy` - This will create a new build by running the redeploy script, add a CNAME pointing to your domain and then push the build folder to a branch called `gh-pages`.
|
||||
3. Configure your GitHub Pages to deploy the `gh-pages` branch to your domain.
|
||||
|
||||
Once the initial setup is complete, you can simply run `npm run deploy` and your website will be built and deployed to GitHub Pages.
|
||||
|
||||
> Note: When the deployment process is complete, you won't see the changes reflected on your website until a few moments later. This is because GitHub Pages needs to run its own build step before the website updates. You can view details about this process in the Actions tab on GitHub.
|
||||
|
||||
### Structure
|
||||
|
||||
- [src](../src) directory
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
Most code for features can be found in the [features](../../src/features) directory. This directory is a library that is mostly used by files in the [components](../../src/components) and [hooks](../../src/hooks) directory.
|
||||
|
||||
> Note: Inside this part of the docs you will often see mentions of directories like `features` or `components`. These paths are relative to the `src` directory. The respective paths relative to the root of this project are `src/features` and `src/components`.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Applications](applications/README.md)
|
||||
|
|
|
|||
114
package-lock.json
generated
114
package-lock.json
generated
|
|
@ -27,6 +27,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"eslint-plugin-jsdoc": "^46.4.6",
|
||||
"gh-pages": "^5.0.0"
|
||||
}
|
||||
},
|
||||
|
|
@ -2315,6 +2316,20 @@
|
|||
"postcss-selector-parser": "^6.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@es-joy/jsdoccomment": {
|
||||
"version": "0.40.1",
|
||||
"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.40.1.tgz",
|
||||
"integrity": "sha512-YORCdZSusAlBrFpZ77pJjc5r1bQs5caPWtAu+WWmiSo+8XaUzseapVrfAtiRFbQWnrBxxLLEwF6f6ZG/UgCQCg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"comment-parser": "1.4.0",
|
||||
"esquery": "^1.5.0",
|
||||
"jsdoc-type-pratt-parser": "~4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
|
|
@ -5154,6 +5169,15 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/are-docs-informative": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
|
||||
"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
|
|
@ -6136,6 +6160,15 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/comment-parser": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.0.tgz",
|
||||
"integrity": "sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/common-path-prefix": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz",
|
||||
|
|
@ -7556,6 +7589,41 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsdoc": {
|
||||
"version": "46.4.6",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.6.tgz",
|
||||
"integrity": "sha512-z4SWYnJfOqftZI+b3RM9AtWL1vF/sLWE/LlO9yOKDof9yN2+n3zOdOJTGX/pRE/xnPsooOLG2Rq6e4d+XW3lNw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@es-joy/jsdoccomment": "~0.40.1",
|
||||
"are-docs-informative": "^0.0.2",
|
||||
"comment-parser": "1.4.0",
|
||||
"debug": "^4.3.4",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"esquery": "^1.5.0",
|
||||
"is-builtin-module": "^3.2.1",
|
||||
"semver": "^7.5.4",
|
||||
"spdx-expression-parse": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.0.0 || ^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsx-a11y": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz",
|
||||
|
|
@ -9517,6 +9585,21 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-builtin-module": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
|
||||
"integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"builtin-modules": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-callable": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||
|
|
@ -11923,6 +12006,15 @@
|
|||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdoc-type-pratt-parser": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
|
||||
"integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsdom": {
|
||||
"version": "16.7.0",
|
||||
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
|
||||
|
|
@ -15735,6 +15827,28 @@
|
|||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||
"deprecated": "Please use @jridgewell/sourcemap-codec instead"
|
||||
},
|
||||
"node_modules/spdx-exceptions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
|
||||
"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/spdx-expression-parse": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
|
||||
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"spdx-exceptions": "^2.1.0",
|
||||
"spdx-license-ids": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spdx-license-ids": {
|
||||
"version": "3.0.13",
|
||||
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
|
||||
"integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/spdy": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
|
||||
|
|
|
|||
33
package.json
33
package.json
|
|
@ -35,7 +35,37 @@
|
|||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"jsdoc"
|
||||
],
|
||||
"rules": {
|
||||
"indent": ["error", "tab", { "SwitchCase": 1 }],
|
||||
|
||||
"jsdoc/no-undefined-types": "warn",
|
||||
"jsdoc/require-param": "warn",
|
||||
"jsdoc/check-tag-names": "warn",
|
||||
"jsdoc/check-types": ["warn", {}],
|
||||
"jsdoc/check-values": "warn",
|
||||
"jsdoc/empty-tags": "warn",
|
||||
"jsdoc/check-param-names": "warn",
|
||||
"jsdoc/check-property-names": "warn",
|
||||
"jsdoc/check-access": "warn",
|
||||
"jsdoc/check-alignment": "warn",
|
||||
"jsdoc/multiline-blocks": "warn",
|
||||
"jsdoc/no-blank-block-descriptions": "warn",
|
||||
"jsdoc/require-hyphen-before-param-description": "warn"
|
||||
},
|
||||
"settings": {
|
||||
"jsdoc": {
|
||||
"preferredTypes": {
|
||||
"Object":"object",
|
||||
"object.<>":"Object<>",
|
||||
"Object.<>":"Object<>",
|
||||
"object<>":"Object<>"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
|
@ -51,6 +81,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"eslint-plugin-jsdoc": "^46.4.6",
|
||||
"gh-pages": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import styles from "./HeaderMenu.module.css";
|
|||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {Object<String, Object<String, Function>>} props.options
|
||||
* @param {Object<String, Object<String, Array<String>>>} props.shortcuts
|
||||
* @param {Object<String, Object<string, function>>} props.options
|
||||
* @param {Object<String, Object<string, string[]>>} props.shortcuts
|
||||
*/
|
||||
export function HeaderMenu({ options, shortcuts }) {
|
||||
const [activeKeys, setActiveKeys] = useState([]);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { VirtualFile } from "../../../features/virtual-drive/virtual-file.js";
|
|||
import { useWindowsManager } from "../../../hooks/windows/WindowsManagerContext.js";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {VirtualFile} props.file
|
||||
*/
|
||||
function FilePreview({ file }) {
|
||||
|
|
|
|||
|
|
@ -4,10 +4,9 @@ import { useWindowsManager } from "../../../hooks/windows/WindowsManagerContext.
|
|||
import styles from "./MediaViewer.module.css";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {VirtualFile} props.file
|
||||
* @returns
|
||||
* @param {Function} props.close
|
||||
*/
|
||||
export function MediaViewer({ file, close }) {
|
||||
const windowsManager = useWindowsManager();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { SettingsManager } from "../../../features/settings/settings.js";
|
|||
import { VirtualRoot } from "../../../features/virtual-drive/virtual-root.js";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {VirtualRoot} props.virtualRoot
|
||||
* @param {SettingsManager} props.settingsManager
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ const USERNAME = "user";
|
|||
const HOSTNAME = "prozilla-os";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {String} props.text
|
||||
* @param {object} props
|
||||
* @param {string} props.text
|
||||
*/
|
||||
function OutputLine({ text }) {
|
||||
return (
|
||||
|
|
@ -17,9 +17,9 @@ function OutputLine({ text }) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {String} props.value
|
||||
* @param {String} props.prefix
|
||||
* @param {object} props
|
||||
* @param {string} props.value
|
||||
* @param {string} props.prefix
|
||||
* @param {Function} props.onChange
|
||||
* @param {Function} props.onKeyUp
|
||||
* @param {Function} props.onKeyDown
|
||||
|
|
|
|||
|
|
@ -9,8 +9,11 @@ const defaultZoom = 16;
|
|||
const zoomSpeed = 4;
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {VirtualFile} props.file
|
||||
* @param {Function} props.setTitle
|
||||
* @param {Function} props.close
|
||||
* @param {string} props.mode
|
||||
*/
|
||||
export function TextEditor({ file, setTitle, close, mode }) {
|
||||
const [currentFile, setCurrentFile] = useState(file);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import ApplicationsManager from "../../features/applications/applications.js";
|
|||
import { useWindows } from "../../hooks/windows/WindowsContext.js";
|
||||
import { useWindowsManager } from "../../hooks/windows/WindowsManagerContext.js";
|
||||
import { ReactSVG } from "react-svg";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import Application from "../../features/applications/application.js";
|
||||
import { HomeMenu } from "./menus/HomeMenu.jsx";
|
||||
import OutsideClickListener from "../../hooks/utils/outsideClick.js";
|
||||
|
|
@ -18,7 +17,7 @@ import { Calendar } from "./indicators/Calendar.jsx";
|
|||
import { useScrollWithShadow } from "../../hooks/utils/scrollWithShadows.js";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {Application} props.app
|
||||
*/
|
||||
function AppButton({ app }) {
|
||||
|
|
@ -96,7 +95,7 @@ export function Taskbar() {
|
|||
|
||||
const search = (query) => {
|
||||
updateShowSearch(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles["Task-bar"]}>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ import { closeTab } from "../../../features/utils/browser.js";
|
|||
import { useKeyboardListener } from "../../../hooks/utils/keyboard.js";
|
||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/VirtualRootContext.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
* @param {boolean} props.active
|
||||
* @param {Function} props.setActive
|
||||
* @param {Function} props.search
|
||||
*/
|
||||
export function HomeMenu({ active, setActive, search }) {
|
||||
const windowsManager = useWindowsManager();
|
||||
const virtualRoot = useVirtualRoot();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,14 @@ import { ReactSVG } from "react-svg";
|
|||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
* @param {boolean} props.active
|
||||
* @param {Function} props.setActive
|
||||
* @param {string} props.searchQuery
|
||||
* @param {Function} props.setSearchQuery
|
||||
* @param {import("react").ElementRef} props.inputRef
|
||||
*/
|
||||
export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inputRef }) {
|
||||
const windowsManager = useWindowsManager();
|
||||
const [apps, setApps] = useState(null);
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import OutsideClickListener from "../../hooks/utils/outsideClick.js";
|
|||
import { formatShortcut } from "../../features/utils/string.js";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {String} props.label
|
||||
* @param {Object.<string, Function>} props.options
|
||||
* @param {object} props
|
||||
* @param {string} props.label
|
||||
* @param {Object<string, Function>} props.options
|
||||
* @param {Object<string, string[]>} props.shortcuts
|
||||
*/
|
||||
export function DropdownButton({ label, options, shortcuts }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
|
@ -33,7 +34,7 @@ export function DropdownButton({ label, options, shortcuts }) {
|
|||
)}
|
||||
</div>)
|
||||
: null
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</OutsideClickListener>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ import Application from "../../features/applications/application.js";
|
|||
import Vector2 from "../../features/math/vector2.js";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {String} props.id
|
||||
* @param {object} props
|
||||
* @param {string} props.id
|
||||
* @param {Application} props.app
|
||||
* @param {Vector2} props.size
|
||||
* @param {Vector2} props.position
|
||||
* @param {boolean} props.focused
|
||||
* @param {Function} props.onInteract
|
||||
* @param {object} props.options
|
||||
*/
|
||||
export function Window({ id, app, size, position, focused = false, onInteract, options }) {
|
||||
const windowsManager = useWindowsManager();
|
||||
|
|
@ -28,18 +29,18 @@ export function Window({ id, app, size, position, focused = false, onInteract, o
|
|||
const [minimized, setMinimized] = useState(false);
|
||||
|
||||
const [screenWidth, setScreenWidth] = useState(100);
|
||||
const [screenHeight, setScreenHeight] = useState(100);
|
||||
const [screenHeight, setScreenHeight] = useState(100);
|
||||
|
||||
const [title, setTitle] = useState(app.name);
|
||||
|
||||
useEffect(() => {
|
||||
const resizeObserver = new ResizeObserver((event) => {
|
||||
setScreenWidth(event[0].contentBoxSize[0].inlineSize);
|
||||
setScreenHeight(event[0].contentBoxSize[0].blockSize);
|
||||
});
|
||||
useEffect(() => {
|
||||
const resizeObserver = new ResizeObserver((event) => {
|
||||
setScreenWidth(event[0].contentBoxSize[0].inlineSize);
|
||||
setScreenHeight(event[0].contentBoxSize[0].blockSize);
|
||||
});
|
||||
|
||||
resizeObserver.observe(document.getElementById("root"));
|
||||
});
|
||||
resizeObserver.observe(document.getElementById("root"));
|
||||
});
|
||||
|
||||
const close = () => {
|
||||
windowsManager.close(id);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import React from "react";
|
||||
|
||||
export default class Application {
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {String} id
|
||||
* @param {string} name
|
||||
* @param {string} id
|
||||
* @param {React.ReactElement} windowContent
|
||||
* @param {Object|null} windowOptions - Default window options
|
||||
* @param {object | null} windowOptions - Default window options
|
||||
*/
|
||||
constructor(name, id, windowContent, windowOptions) {
|
||||
Object.assign(this, { name, id, windowContent, windowOptions });
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export default class ApplicationsManager {
|
|||
]
|
||||
|
||||
/**
|
||||
* @param {String} id
|
||||
* @param {string} id
|
||||
* @returns {Application}
|
||||
*/
|
||||
static getApplication(id) {
|
||||
|
|
@ -40,7 +40,7 @@ export default class ApplicationsManager {
|
|||
|
||||
/**
|
||||
* Get the application associated with a file extension
|
||||
* @param {String} fileExtension
|
||||
* @param {string} fileExtension
|
||||
* @returns {Application}
|
||||
*/
|
||||
static getFileApplication(fileExtension) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export class Command {
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @param {Function} execute
|
||||
*/
|
||||
constructor(name, execute) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* @param {number} min
|
||||
* @param {number} max
|
||||
* @returns {number}
|
||||
*/
|
||||
export function randomRange(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ export class Settings {
|
|||
|
||||
/**
|
||||
* @param {VirtualRoot} virtualRoot
|
||||
* @param {String} path
|
||||
* @param {string} path
|
||||
*/
|
||||
constructor(virtualRoot, path) {
|
||||
this.#virtualRoot = virtualRoot;
|
||||
|
|
@ -63,7 +63,7 @@ export class Settings {
|
|||
|
||||
/**
|
||||
* Checks if xml doc is missing
|
||||
* @returns {Promise<Boolean>}
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async isMissingXmlDoc() {
|
||||
if (this.xmlDoc == null)
|
||||
|
|
@ -74,14 +74,14 @@ export class Settings {
|
|||
|
||||
/**
|
||||
* @callback valueCallback
|
||||
* @param {String} value
|
||||
* @param {string} value
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets a value by a given key if it exists or calls a callback function whenever the value changes
|
||||
* @param {String} key
|
||||
* @param {string} key
|
||||
* @param {valueCallback} callback
|
||||
* @returns {Promise<String|null>}
|
||||
* @returns {Promise<string | null>}
|
||||
*/
|
||||
async get(key, callback) {
|
||||
if (await this.isMissingXmlDoc())
|
||||
|
|
@ -107,8 +107,8 @@ export class Settings {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} key
|
||||
* @param {String} value
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
async set(key, value) {
|
||||
if (await this.isMissingXmlDoc())
|
||||
|
|
@ -123,14 +123,14 @@ export class Settings {
|
|||
|
||||
export class SettingsManager {
|
||||
/**
|
||||
* @type {Object<String, String>}
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
static VIRTUAL_PATHS = {
|
||||
"desktop": "~/.config/desktop.xml"
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {Object<String, Settings>}
|
||||
* @type {Object<string, Settings>}
|
||||
*/
|
||||
#pathToSettings = {};
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ export class SettingsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} path
|
||||
* @param {string} path
|
||||
* @returns {Settings}
|
||||
*/
|
||||
get(path) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* @param {*} item
|
||||
* @param {*[]} array
|
||||
*/
|
||||
export function removeFromArray(item, array) {
|
||||
const index = array.indexOf(item);
|
||||
if (index !== -1) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
export class EventEmitter {
|
||||
/**
|
||||
* @type {Object<String, String>}
|
||||
* @type {Object<string, string>}
|
||||
*/
|
||||
static EVENT_NAMES = {};
|
||||
|
||||
/**
|
||||
* @type {Object<String, Array<Function>>}
|
||||
* @type {Object<string, Array<Function>>}
|
||||
*/
|
||||
#events = {}
|
||||
|
||||
/**
|
||||
* Add event listener for an event
|
||||
* @param {EVENT_NAMES} eventName
|
||||
* @param {EventEmitter.EVENT_NAMES} eventName
|
||||
* @param {Function} callback
|
||||
*/
|
||||
on(eventName, callback) {
|
||||
|
|
@ -23,7 +23,7 @@ export class EventEmitter {
|
|||
|
||||
/**
|
||||
* Remove event listener for an event
|
||||
* @param {EVENT_NAMES} eventName
|
||||
* @param {string} eventName
|
||||
* @param {Function} callback
|
||||
*/
|
||||
off(eventName, callback) {
|
||||
|
|
@ -36,7 +36,7 @@ export class EventEmitter {
|
|||
|
||||
/**
|
||||
* Dispatch event
|
||||
* @param {EVENT_NAMES} eventName
|
||||
* @param {string} eventName
|
||||
* @param {*} data
|
||||
*/
|
||||
emit(eventName, data) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
/**
|
||||
* @param {string[]} shortcut
|
||||
* @returns {string}
|
||||
*/
|
||||
export function formatShortcut(shortcut) {
|
||||
const specialKeys = [];
|
||||
const singleKeys = [];
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { VirtualRoot } from "./virtual-root.js";
|
|||
|
||||
export class VirtualBase extends EventEmitter {
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
*/
|
||||
constructor(name) {
|
||||
super();
|
||||
|
|
@ -16,7 +16,7 @@ export class VirtualBase extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @returns {VirtualBase}
|
||||
*/
|
||||
setName(name) {
|
||||
|
|
@ -26,7 +26,7 @@ export class VirtualBase extends EventEmitter {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} alias
|
||||
* @param {string} alias
|
||||
* @returns {ThisType}
|
||||
*/
|
||||
setAlias(alias) {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ export class VirtualFile extends VirtualBase {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {String=} extension
|
||||
* @param {string} name
|
||||
* @param {string=} extension
|
||||
*/
|
||||
constructor(name, extension) {
|
||||
super(name);
|
||||
|
|
@ -22,7 +22,7 @@ export class VirtualFile extends VirtualBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} alias
|
||||
* @param {string} alias
|
||||
* @returns {VirtualFile}
|
||||
*/
|
||||
setAlias(alias) {
|
||||
|
|
@ -31,7 +31,7 @@ export class VirtualFile extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Sets the source of this file and removes the content
|
||||
* @param {String} source
|
||||
* @param {string} source
|
||||
* @returns {VirtualFile}
|
||||
*/
|
||||
setSource(source) {
|
||||
|
|
@ -46,7 +46,7 @@ export class VirtualFile extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Sets the content of this file and removes the source
|
||||
* @param {String|*} content
|
||||
* @param {string | *} content
|
||||
* @returns {VirtualFile}
|
||||
*/
|
||||
setContent(content) {
|
||||
|
|
@ -67,7 +67,7 @@ export class VirtualFile extends VirtualBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return {Promise<String|null>}
|
||||
* @returns {Promise<string | null>}
|
||||
*/
|
||||
async read() {
|
||||
if (this.content != null)
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ export class VirtualFolder extends VirtualBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} name
|
||||
* @param {Number} type
|
||||
* @param {string} name
|
||||
* @param {number} type
|
||||
*/
|
||||
constructor(name, type) {
|
||||
super(name);
|
||||
|
|
@ -23,7 +23,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} alias
|
||||
* @param {string} alias
|
||||
* @returns {VirtualFolder}
|
||||
*/
|
||||
setAlias(alias) {
|
||||
|
|
@ -32,8 +32,8 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Returns true if this folder contains a file matching a name and extension
|
||||
* @param {String} name
|
||||
* @param {String} extension
|
||||
* @param {string} name
|
||||
* @param {string} extension
|
||||
* @returns {VirtualFile}
|
||||
*/
|
||||
hasFile(name, extension) {
|
||||
|
|
@ -42,7 +42,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Returns true if this folder contains a folder matching a name
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasFolder(name) {
|
||||
|
|
@ -51,8 +51,8 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Finds and returns a file inside this folder matching a name and extension
|
||||
* @param {String} name
|
||||
* @param {String} extension
|
||||
* @param {string} name
|
||||
* @param {string} extension
|
||||
* @returns {VirtualFile}
|
||||
*/
|
||||
findFile(name, extension) {
|
||||
|
|
@ -69,7 +69,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Finds and returns a folder inside this folder matching a name
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @returns {VirtualFolder}
|
||||
*/
|
||||
findSubFolder(name) {
|
||||
|
|
@ -91,8 +91,8 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Creates a file with a name and extension
|
||||
* @param {String} name
|
||||
* @param {String} extension
|
||||
* @param {string} name
|
||||
* @param {string} extension
|
||||
* @param {createFileCallback} callback
|
||||
* @returns {VirtualFolder}
|
||||
*/
|
||||
|
|
@ -107,9 +107,9 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Creates files based on an array of objects with file names and extensions
|
||||
* @param {Object[]} files
|
||||
* @param {String} Object[].name
|
||||
* @param {String} Object[].extension
|
||||
* @param {object[]} files
|
||||
* @param {string} files.name
|
||||
* @param {string} files.extension
|
||||
* @returns {VirtualFolder}
|
||||
*/
|
||||
createFiles(files) {
|
||||
|
|
@ -127,7 +127,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Creates a folder with a name
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @returns {VirtualFolder}
|
||||
* @param {createFolderCallback} callback
|
||||
*/
|
||||
|
|
@ -142,7 +142,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Creates folders based on an array of folder names
|
||||
* @param {String[]} folders
|
||||
* @param {string[]} folders
|
||||
* @returns {VirtualFolder}
|
||||
*/
|
||||
createFolders(folders) {
|
||||
|
|
@ -156,7 +156,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
/**
|
||||
* Adds a file at a destination
|
||||
* @deprecated
|
||||
* @param {String} destination
|
||||
* @param {string} destination
|
||||
*/
|
||||
addFile(destination) {
|
||||
const folderNames = destination.split("/");
|
||||
|
|
@ -182,7 +182,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
/**
|
||||
* Adds a folder at a destination
|
||||
* @deprecated
|
||||
* @param {String} destination
|
||||
* @param {string} destination
|
||||
*/
|
||||
addFolder(destination) {
|
||||
if (destination.endsWith("/"))
|
||||
|
|
@ -218,7 +218,7 @@ export class VirtualFolder extends VirtualBase {
|
|||
|
||||
/**
|
||||
* Returns the file or folder at a relative path or null if it doesn't exist
|
||||
* @param {String} relativePath
|
||||
* @param {string} relativePath
|
||||
* @returns {VirtualFile|VirtualFolder|null}
|
||||
*/
|
||||
navigate(relativePath) {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ export class VirtualRoot extends VirtualFolder {
|
|||
|
||||
/**
|
||||
* Adds a shortcut to a file or folder
|
||||
* @param {String} name
|
||||
* @param {string} name
|
||||
* @param {VirtualFile|VirtualFolder} destination
|
||||
* @returns {VirtualRoot}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ export default class WindowsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} appId
|
||||
* @param {Object|null} options
|
||||
* @returns {Object}
|
||||
* @param {string} appId
|
||||
* @param {object | null} options
|
||||
* @returns {object}
|
||||
*/
|
||||
open(appId, options) {
|
||||
const app = ApplicationsManager.getApplication(appId);
|
||||
|
|
@ -45,7 +45,7 @@ export default class WindowsManager {
|
|||
|
||||
/**
|
||||
* @param {VirtualFile} file
|
||||
* @returns {Object}
|
||||
* @returns {object}
|
||||
*/
|
||||
openFile(file) {
|
||||
const app = ApplicationsManager.getFileApplication(file.extension);
|
||||
|
|
@ -54,7 +54,7 @@ export default class WindowsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} windowId
|
||||
* @param {string} windowId
|
||||
*/
|
||||
close(windowId) {
|
||||
windowId = windowId.toString();
|
||||
|
|
@ -72,7 +72,7 @@ export default class WindowsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Object} window
|
||||
* @param {string} windowId
|
||||
*/
|
||||
focus(windowId) {
|
||||
windowId = windowId.toString();
|
||||
|
|
@ -89,8 +89,8 @@ export default class WindowsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {String} appId
|
||||
* @returns {Boolean}
|
||||
* @param {string} appId
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAppActive(appId) {
|
||||
let active = false;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ const SettingsContext = createContext();
|
|||
|
||||
/**
|
||||
* Note: needs to be inside a virtual root provider
|
||||
* @returns {React.Provider<SettingsManager>}
|
||||
* @param props
|
||||
* @param props.children
|
||||
* @returns {import("react").Provider<SettingsManager>}
|
||||
*/
|
||||
export function SettingsProvider({ children }) {
|
||||
const virtualRoot = useVirtualRoot();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect } from "react";
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {object} params
|
||||
* @param {Function} params.onKeyDown
|
||||
* @param {Function} params.onKeyUp
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2,15 +2,18 @@
|
|||
* https://stackoverflow.com/a/42234988
|
||||
*/
|
||||
|
||||
import React, { useRef, useEffect } from "react";
|
||||
import { useRef, useEffect } from "react";
|
||||
|
||||
/**
|
||||
* Hook that alerts clicks outside of the passed ref
|
||||
* @param {import("react").ElementRef} ref
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function useOutsideClickListener(ref, callback) {
|
||||
useEffect(() => {
|
||||
/**
|
||||
* Alert if clicked on outside of element
|
||||
* @param event
|
||||
*/
|
||||
function handleClickOutside(event) {
|
||||
if (ref.current && !ref.current.contains(event.target)) {
|
||||
|
|
@ -27,8 +30,9 @@ function useOutsideClickListener(ref, callback) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {Function} props.onOutsideClick
|
||||
* @param {import("react").ElementType} props.children
|
||||
*/
|
||||
export default function OutsideClickListener({ onOutsideClick, children }) {
|
||||
const wrapperRef = useRef(null);
|
||||
|
|
|
|||
|
|
@ -7,16 +7,16 @@ import React, { useCallback, useEffect, useRef } from "react";
|
|||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* @param {Object} options
|
||||
* @param {object} options
|
||||
* @param {React.ElementRef} options.ref
|
||||
* @param {Boolean=true} options.horizontal
|
||||
* @param {Boolean=true} options.dynamicOffset
|
||||
* @param {Number=1} options.dynamicOffsetFactor
|
||||
* @param {Object} options.shadow
|
||||
* @param {object} options.shadow
|
||||
* @param {Number=8} options.shadow.offset
|
||||
* @param {Number=5} options.shadow.blurRadius
|
||||
* @param {Number=-5} options.shadow.spreadRadius
|
||||
* @param {Object} options.shadow.color
|
||||
* @param {object} options.shadow.color
|
||||
* @param {Number=0} options.shadow.color.r
|
||||
* @param {Number=0} options.shadow.color.g
|
||||
* @param {Number=0} options.shadow.color.b
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import { VirtualRoot } from "../../features/virtual-drive/virtual-root.js";
|
|||
const VirtualRootContext = createContext();
|
||||
|
||||
/**
|
||||
* @returns {React.Provider<VirtualRoot>}
|
||||
* @param props
|
||||
* @param props.children
|
||||
* @returns {import("react").Provider<VirtualRoot>}
|
||||
*/
|
||||
export function VirtualRootProvider({ children }) {
|
||||
const virtualRoot = new VirtualRoot().init();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import { createContext, useCallback, useContext, useState } from "react";
|
|||
const WindowsContext = createContext();
|
||||
|
||||
/**
|
||||
* @returns {React.Provider<any>}
|
||||
* @param props
|
||||
* @param props.children
|
||||
* @param props.windowsManager
|
||||
* @returns {import("react").Provider<any>}
|
||||
*/
|
||||
export function WindowsProvider({ children, windowsManager }) {
|
||||
const [windows, setWindows] = useState([]);
|
||||
|
|
@ -22,6 +25,9 @@ export function WindowsProvider({ children, windowsManager }) {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {object[]}
|
||||
*/
|
||||
export function useWindows() {
|
||||
return useContext(WindowsContext);
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ import { WindowsProvider } from "./WindowsContext.js";
|
|||
const WindowsManagerContext = createContext();
|
||||
|
||||
/**
|
||||
* @returns {React.Provider<any>}
|
||||
* @param {object} props
|
||||
* @param {import("react").ElementType} props.children
|
||||
* @returns {import("react").Provider<any>}
|
||||
*/
|
||||
export function WindowsManagerProvider({ children }) {
|
||||
const windowsManager = new WindowsManager();
|
||||
|
|
|
|||
Loading…
Reference in a new issue