Refactoring
|
|
@ -11,7 +11,7 @@ To see the status and to-do's of each feature, check the [task board](https://pr
|
|||
## Table of Contents
|
||||
|
||||
- [Actions](storage/README.md)
|
||||
- [Applications](applications/README.md)
|
||||
- [Apps](apps/README.md)
|
||||
- [Modals](modals/README.md)
|
||||
- [Settings](settings/README.md)
|
||||
- [Storage](storage/README.md)
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# Applications
|
||||
|
||||
> Related document: [Windows](../windows/README.md)
|
||||
|
||||
Applications (sometimes shortened to apps) are processes that open a window when ran. The window allows the user to view and interact with the app. Apps have a `title`, `id` and a `windowContent` property that refers to the React component of the application interface.
|
||||
|
||||
> Some applications have a different name in the UI, these names are written between brackets and quotation marks. The other name is the one used in code and file/folder names.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [<img src="../../../public/assets/applications/icons/terminal.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Terminal ("Commands")](terminal/README.md)
|
||||
- [<img src="../../../public/assets/applications/icons/file-explorer.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> File Explorer ("Files")](file-explorer/README.md)
|
||||
- [<img src="../../../public/assets/applications/icons/media-viewer.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Media Viewer ("Photos")](media-viewer/README.md)
|
||||
- [<img src="../../../public/assets/applications/icons/text-editor.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Text Editor ("Notes")](text-editor/README.md)
|
||||
- [<img src="../../../public/assets/applications/icons/settings.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Settings](settings/README.md)
|
||||
|
||||
## Common components
|
||||
|
||||
### Header menu
|
||||
|
||||
The header menu is a useful component that can be added to app windows for quick access to useful functions, like saving and opening files. The header menu can also be used to add shortcuts for functions.
|
||||
|
||||
#### Example
|
||||
|
||||
```js
|
||||
// components/applications/.common/HeaderMenu.jsx
|
||||
|
||||
<HeaderMenu
|
||||
options={{
|
||||
"File": {
|
||||
"New": () => {
|
||||
// ...
|
||||
},
|
||||
"Save": () => {
|
||||
// ...
|
||||
},
|
||||
"Exit": () => {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}}
|
||||
shortcuts={{
|
||||
"File": {
|
||||
"New": ["Control", "e"],
|
||||
"Save": ["Control", "s"],
|
||||
"Exit": ["Control", "x"],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## App templates
|
||||
|
||||
### Webview
|
||||
|
||||
The webview template can be used to turn a webpage into an application by simply setting a source property.
|
||||
|
||||
#### Example
|
||||
|
||||
```js
|
||||
// features/applications/applications.js
|
||||
|
||||
import { WebView } from "../../components/applications/templates/WebView.jsx";
|
||||
|
||||
export default class ApplicationsManager {
|
||||
static APPLICATIONS = [
|
||||
// ...
|
||||
new Application("Web App", "web-app", WebView, { source: "https://prozilla.dev/" }),
|
||||
]
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## App examples
|
||||
|
||||
### Adding a new application
|
||||
|
||||
```js
|
||||
// components/applications/example/Example.jsx
|
||||
|
||||
export function Example() {
|
||||
return (
|
||||
<p>Application interface goes here.</p>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// features/applications/applications.js
|
||||
|
||||
import { Example } from "../../components/applications/example/Example.jsx";
|
||||
|
||||
export default class ApplicationsManager {
|
||||
static APPLICATIONS = [
|
||||
// ...
|
||||
new Application("Example App", "example", Example),
|
||||
]
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/applications/icons/media-viewer.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Media Viewer ("Photos")
|
||||
|
||||
An application for viewing media like images and videos.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
|
@ -1,9 +0,0 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/applications/icons/text-editor.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Text Editor ("Notes")
|
||||
|
||||
An application for editing text documents.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
104
docs/features/apps/README.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# Apps
|
||||
|
||||
> Related document: [Windows](../windows/README.md)
|
||||
|
||||
Applications (often shortened to apps) are processes that open a window when ran. The window allows the user to view and interact with the app. Apps have a `title`, `id` and a `windowContent` property that refers to the React component of the application interface.
|
||||
|
||||
> Some apps have a different name in the UI, these names are written between brackets and quotation marks. The other name is the one used in code and file/folder names.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [<img src="../../../public/assets/apps/icons/terminal.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Terminal ("Commands")](terminal/README.md)
|
||||
- [<img src="../../../public/assets/apps/icons/file-explorer.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> File Explorer ("Files")](file-explorer/README.md)
|
||||
- [<img src="../../../public/assets/apps/icons/media-viewer.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Media Viewer ("Photos")](media-viewer/README.md)
|
||||
- [<img src="../../../public/assets/apps/icons/text-editor.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Text Editor ("Notes")](text-editor/README.md)
|
||||
- [<img src="../../../public/assets/apps/icons/settings.svg" width=20 height=20 style="vertical-align: text-bottom; background: none;"/> Settings](settings/README.md)
|
||||
|
||||
## Common components
|
||||
|
||||
### Header menu
|
||||
|
||||
The header menu is a useful component that can be added to app windows for quick access to useful functions, like saving and opening files. The header menu can also be used to add shortcuts for functions.
|
||||
|
||||
#### Example
|
||||
|
||||
```js
|
||||
// components/apps/_common/HeaderMenu.jsx
|
||||
|
||||
<HeaderMenu
|
||||
options={{
|
||||
"File": {
|
||||
"New": () => {
|
||||
// ...
|
||||
},
|
||||
"Save": () => {
|
||||
// ...
|
||||
},
|
||||
"Exit": () => {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
}}
|
||||
shortcuts={{
|
||||
"File": {
|
||||
"New": ["Control", "e"],
|
||||
"Save": ["Control", "s"],
|
||||
"Exit": ["Control", "x"],
|
||||
},
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
## App templates
|
||||
|
||||
### Webview
|
||||
|
||||
The webview template can be used to turn a webpage into an application by simply setting a source property.
|
||||
|
||||
#### Example
|
||||
|
||||
```js
|
||||
// features/apps/apps.js
|
||||
|
||||
import { WebView } from "../../components/apps/templates/WebView.jsx";
|
||||
|
||||
export default class AppsManager {
|
||||
static APPLICATIONS = [
|
||||
// ...
|
||||
new App("Web App", "web-app", WebView, { source: "https://prozilla.dev/" }),
|
||||
]
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## App examples
|
||||
|
||||
### Adding a new app
|
||||
|
||||
```js
|
||||
// components/apps/example/Example.jsx
|
||||
|
||||
export function Example() {
|
||||
return (
|
||||
<p>Application interface goes here.</p>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// features/apps/apps.js
|
||||
|
||||
import { Example } from "../../components/apps/example/Example.jsx";
|
||||
|
||||
export default class AppsManager {
|
||||
static APPLICATIONS = [
|
||||
// ...
|
||||
new App("Example App", "example", Example),
|
||||
]
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/applications/icons/file-explorer.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> File Explorer ("Files")
|
||||
# <img src="../../../../public/assets/apps/icons/file-explorer.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> File Explorer ("Files")
|
||||
|
||||
A tool for exploring and managing files and folders with a user interface.
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
9
docs/features/apps/media-viewer/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/apps/icons/media-viewer.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Media Viewer ("Photos")
|
||||
|
||||
An app for viewing media like images and videos.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
Before Width: | Height: | Size: 210 KiB After Width: | Height: | Size: 210 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/applications/icons/settings.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Settings
|
||||
# <img src="../../../../public/assets/apps/icons/settings.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Settings
|
||||
|
||||
Allows the user to change their settings and personalize their instance of Prozilla OS.
|
||||
|
||||
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 177 KiB |
|
|
@ -1,6 +1,6 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/applications/icons/terminal.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Terminal ("Commands")
|
||||
# <img src="../../../../public/assets/apps/icons/terminal.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Terminal ("Commands")
|
||||
|
||||
A command line tool.
|
||||
|
||||
|
|
@ -10,14 +10,14 @@ A command line tool.
|
|||
|
||||
## Commands
|
||||
|
||||
See [features/applications/terminal/commands.js](../../../../src/features/applications/terminal/commands.js) for a list of commands. You can edit this file to add/remove/edit commands.
|
||||
See [features/apps/terminal/commands.js](../../../../src/features/apps/terminal/commands.js) for a list of commands. You can edit this file to add/remove/edit commands.
|
||||
|
||||
## Examples
|
||||
|
||||
### Touch command
|
||||
|
||||
```js
|
||||
// features/applications/terminal/commands/touch.js
|
||||
// features/apps/terminal/commands/touch.js
|
||||
|
||||
export const touch = new Command("touch")
|
||||
.setRequireArgs(true)
|
||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
9
docs/features/apps/text-editor/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[← Back](../README.md)
|
||||
|
||||
# <img src="../../../../public/assets/apps/icons/text-editor.svg" width=30 height=30 style="vertical-align: middle; background: none;"/> Text Editor ("Notes")
|
||||
|
||||
An app for editing text documents.
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
|
|
@ -11,7 +11,7 @@ The virtual drive is a virtual file and directory system. The root directory is
|
|||
### Component interacting with virtual drive
|
||||
|
||||
```js
|
||||
// components/applications/example/Example.jsx
|
||||
// components/apps/example/Example.jsx
|
||||
|
||||
export function Example() {
|
||||
const virtualRoot = useVirtualRoot();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
# Windows
|
||||
|
||||
> Related document: [Applications](../applications/README.md)
|
||||
> Related document: [Apps](../apps/README.md)
|
||||
|
||||
The windows components are used to view and interact with running applications. Each application opens a window when ran.
|
||||
The windows components are used to view and interact with running applications. Each app opens a window when ran.
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
|
@ -1,7 +1,7 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { formatShortcut } from "../../../features/utils/string.js";
|
||||
import { formatShortcut } from "../../../features/utils/string.utils.js";
|
||||
import styles from "../Actions.module.css";
|
||||
import { ImagePreview } from "../../applications/file-explorer/directory-list/ImagePreview.jsx";
|
||||
import { ImagePreview } from "../../apps/file-explorer/directory-list/ImagePreview.jsx";
|
||||
import { memo } from "react";
|
||||
|
||||
export const ClickAction = memo(({ actionId, label, shortcut, onTrigger, icon }) => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { formatShortcut } from "../../../features/utils/string.js";
|
||||
import { formatShortcut } from "../../../features/utils/string.utils.js";
|
||||
import styles from "../Actions.module.css";
|
||||
import { faCircleDot } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useState } from "react";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { formatShortcut } from "../../../features/utils/string.js";
|
||||
import { formatShortcut } from "../../../features/utils/string.utils.js";
|
||||
import styles from "../Actions.module.css";
|
||||
import { useState } from "react";
|
||||
import { faSquare } from "@fortawesome/free-regular-svg-icons";
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import { useState } from "react";
|
||||
import styles from "./ImagePreview.module.css";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faFile } from "@fortawesome/free-solid-svg-icons";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
export function ImagePreview({ source, className, ...props }) {
|
||||
const [loadingFailed, setLoadingFailed] = useState(false);
|
||||
|
||||
if (loadingFailed)
|
||||
return <FontAwesomeIcon icon={faFile}/>;
|
||||
|
||||
const classNames = [styles["Image-preview"]];
|
||||
if (className != null)
|
||||
classNames.push(className);
|
||||
|
||||
return (<div className={classNames.join(" ")} {...props}>
|
||||
{source.endsWith(".svg")
|
||||
? <ReactSVG src={source}/>
|
||||
: <img src={source} onError={() => { setLoadingFailed(true); }} alt="Preview" draggable="false"/>
|
||||
}
|
||||
</div>);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import { DropdownButton } from "../../utils/dropdown-button/DropdownButton.jsx";
|
|||
import styles from "./HeaderMenu.module.css";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {object} props
|
||||
* @param {Object<string, Object<string, Function>>} props.options
|
||||
* @param {Object<string, Object<string, string[]>>} props.shortcuts
|
||||
*/
|
||||
|
|
@ -2,8 +2,8 @@ import { forwardRef, useEffect, useState } from "react";
|
|||
import styles from "./WebView.module.css";
|
||||
|
||||
/**
|
||||
* @param {Object} props
|
||||
* @param {String} props.source
|
||||
* @param {object} props
|
||||
* @param {string} props.source
|
||||
*/
|
||||
export const WebView = forwardRef(({ source, focus, ...props }, ref) => {
|
||||
const [hovered, setHovered] = useState(false);
|
||||
|
|
@ -22,7 +22,7 @@ export const WebView = forwardRef(({ source, focus, ...props }, ref) => {
|
|||
return () => {
|
||||
window.removeEventListener("blur", onBlur);
|
||||
};
|
||||
}, [hovered]);
|
||||
}, [focus, hovered]);
|
||||
|
||||
const onMouseOver = () => {
|
||||
setHovered(true);
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import styles from "./Browser.module.css";
|
||||
import { WebView } from "../.templates/WebView.jsx";
|
||||
import { WebView } from "../_templates/WebView.jsx";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faCaretLeft, faCaretRight, faHome, faRotateRight } from "@fortawesome/free-solid-svg-icons";
|
||||
import { HOME_URL, SEARCH_URL } from "../../../constants/applications/browser.js";
|
||||
import { isValidUrl } from "../../../features/utils/browser.js";
|
||||
import { HOME_URL, SEARCH_URL } from "../../../config/apps/browser.config.js";
|
||||
import { isValidUrl } from "../../../features/utils/browser.utils.js";
|
||||
import { useHistory } from "../../../hooks/utils/history.js";
|
||||
|
||||
/** @type {import("../../windows/WindowView.jsx").windowProps} */
|
||||
|
|
@ -8,15 +8,15 @@ import { useContextMenu } from "../../../hooks/modals/contextMenu.js";
|
|||
import { QuickAccessButton } from "./QuickAccessButton.jsx";
|
||||
import { useWindowedModal } from "../../../hooks/modals/windowedModal.js";
|
||||
import Vector2 from "../../../features/math/vector2.js";
|
||||
import { DIALOG_CONTENT_TYPES } from "../../../constants/modals.js";
|
||||
import { DIALOG_CONTENT_TYPES } from "../../../config/modals.config.js";
|
||||
import { DirectoryList } from "./directory-list/DirectoryList.jsx";
|
||||
import { Actions } from "../../actions/Actions.jsx";
|
||||
import { ClickAction } from "../../actions/actions/ClickAction.jsx";
|
||||
import utilStyles from "../../../styles/utils.module.css";
|
||||
import { DialogBox } from "../../modals/dialog-box/DialogBox.jsx";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import { APPS, APP_ICONS, APP_NAMES } from "../../../constants/applications.js";
|
||||
import { TITLE_SEPARATOR } from "../../../constants/windows.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
import { APPS, APP_ICONS, APP_NAMES } from "../../../config/apps.config.js";
|
||||
import { TITLE_SEPARATOR } from "../../../config/windows.config.js";
|
||||
import { FileProperties } from "../../modals/file-properties/FileProperties.jsx";
|
||||
import { useHistory } from "../../../hooks/utils/history.js";
|
||||
import { Divider } from "../../actions/actions/Divider.jsx";
|
||||
|
|
@ -83,8 +83,6 @@ export function FileExplorer({ startPath, app, modalsManager }) {
|
|||
|
||||
const directory = absolute ? virtualRoot.navigate(path) : currentDirectory.navigate(path);
|
||||
|
||||
console.debug(directory);
|
||||
|
||||
if (directory != null) {
|
||||
setCurrentDirectory(directory);
|
||||
setPath(directory.root ? "/" : directory.path);
|
||||
|
|
@ -164,6 +162,7 @@ export function FileExplorer({ startPath, app, modalsManager }) {
|
|||
tabIndex={0}
|
||||
className={styles["Icon-button"]}
|
||||
onClick={() => { changeDirectory(".."); }}
|
||||
disabled={currentDirectory.root}
|
||||
>
|
||||
<FontAwesomeIcon icon={faArrowUp}/>
|
||||
</button>
|
||||
|
|
@ -189,6 +188,7 @@ export function FileExplorer({ startPath, app, modalsManager }) {
|
|||
|
||||
// }
|
||||
}}
|
||||
disabled={!currentDirectory.canBeEdited}
|
||||
>
|
||||
<FontAwesomeIcon icon={faPlus}/>
|
||||
</button>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import { VirtualFile } from "../../../../features/virtual-drive/virtualFile.js";
|
||||
import { VirtualFolder } from "../../../../features/virtual-drive/virtualFolder.js";
|
||||
import { VirtualFile } from "../../../../features/virtual-drive/file/virtualFile.js";
|
||||
import { VirtualFolder } from "../../../../features/virtual-drive/folder/virtualFolder.js";
|
||||
import { Interactable } from "../../../utils/interactable/Interactable.jsx";
|
||||
import styles from "./DirectoryList.module.css";
|
||||
import { ImagePreview } from "./ImagePreview.jsx";
|
||||
|
|
@ -159,7 +159,7 @@ export function DirectoryList({ directory, showHidden = false, folderClassName,
|
|||
}}
|
||||
>
|
||||
<div className={styles["Folder-icon"]}>
|
||||
<ImagePreview source={folder.getIconUrl()}/>
|
||||
<ImagePreview source={folder.getIconUrl()} onError={() => { folder.setIconUrl(null); }}/>
|
||||
</div>
|
||||
<p>{folder.name}</p>
|
||||
</Interactable>
|
||||
|
|
@ -181,7 +181,7 @@ export function DirectoryList({ directory, showHidden = false, folderClassName,
|
|||
}}
|
||||
>
|
||||
<div className={styles["File-icon"]}>
|
||||
<ImagePreview source={file.getIconUrl()}/>
|
||||
<ImagePreview source={file.getIconUrl()} onError={() => { file.setIconUrl(null); }}/>
|
||||
</div>
|
||||
<p>{file.id}</p>
|
||||
</Interactable>
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { useState } from "react";
|
||||
import styles from "./ImagePreview.module.css";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import AppsManager from "../../../../features/apps/appsManager.js";
|
||||
import { APPS } from "../../../../config/apps.config.js";
|
||||
|
||||
export function ImagePreview({ source, className, onError, ...props }) {
|
||||
const [loadingFailed, setLoadingFailed] = useState(false);
|
||||
|
||||
const onLoadingError = () => {
|
||||
setLoadingFailed(true);
|
||||
onError?.();
|
||||
};
|
||||
|
||||
const classNames = [styles["Image-preview"]];
|
||||
if (className != null)
|
||||
classNames.push(className);
|
||||
|
||||
return (<div className={classNames.join(" ")} {...props}>
|
||||
{loadingFailed
|
||||
? <ReactSVG src={AppsManager.getAppIconUrl(APPS.FILE_EXPLORER, "file")}/>
|
||||
: source.endsWith(".svg")
|
||||
? <ReactSVG src={source} onError={onLoadingError}/>
|
||||
: <img src={source} onError={onLoadingError} alt="Preview" draggable="false"/>
|
||||
}
|
||||
</div>);
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
align-items: center;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Image-preview > * {
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import { useEffect } from "react";
|
||||
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
|
||||
import styles from "./MediaViewer.module.css";
|
||||
import { APPS } from "../../../constants/applications.js";
|
||||
import { APPS } from "../../../config/apps.config.js";
|
||||
|
||||
/**
|
||||
* @param {import("../../windows/WindowView.jsx").windowProps} props
|
||||
|
|
@ -4,7 +4,7 @@ import utilStyles from "../../../styles/utils.module.css";
|
|||
import Vector2 from "../../../features/math/vector2.js";
|
||||
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
|
||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.js";
|
||||
import { NAME } from "../../../constants/branding.js";
|
||||
import { NAME } from "../../../config/branding.config.js";
|
||||
|
||||
export function AboutSettings() {
|
||||
const windowsManager = useWindowsManager();
|
||||
|
|
@ -21,7 +21,7 @@ export function AboutSettings() {
|
|||
event.preventDefault();
|
||||
windowsManager.open("text-editor", {
|
||||
mode: "view",
|
||||
file: virtualRoot.navigate("~/Documents").findFile("info", "md"),
|
||||
file: virtualRoot.navigate("~/Documents/info.md"),
|
||||
size: new Vector2(575, 675),
|
||||
});
|
||||
}}
|
||||
|
|
@ -3,7 +3,7 @@ import { SettingsManager } from "../../../features/settings/settingsManager.js";
|
|||
import styles from "./Settings.module.css";
|
||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.js";
|
||||
import { useSettingsManager } from "../../../hooks/settings/settingsManagerContext.js";
|
||||
import { WALLPAPERS_PATH } from "../../../constants/applications/settings.js";
|
||||
import { WALLPAPERS_PATH } from "../../../config/apps/settings.config.js";
|
||||
|
||||
export function AppearanceSettings() {
|
||||
const virtualRoot = useVirtualRoot();
|
||||
|
|
@ -4,9 +4,9 @@ import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.
|
|||
import { clamp } from "../../../features/math/clamp.js";
|
||||
import { OutputLine } from "./OutputLine.jsx";
|
||||
import { InputLine } from "./InputLine.jsx";
|
||||
import { ANSI, HOSTNAME, USERNAME } from "../../../constants/applications/terminal.js";
|
||||
import CommandsManager from "../../../features/applications/terminal/commands.js";
|
||||
import { removeFromArray } from "../../../features/utils/array.js";
|
||||
import { ANSI, HOSTNAME, USERNAME } from "../../../config/apps/terminal.config.js";
|
||||
import CommandsManager from "../../../features/apps/terminal/commands.js";
|
||||
import { removeFromArray } from "../../../features/utils/array.utils.js";
|
||||
|
||||
/**
|
||||
* @param {import("../../windows/WindowView.jsx").windowProps} props
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import styles from "./TextEditor.module.css";
|
||||
import { HeaderMenu } from "../.common/HeaderMenu.jsx";
|
||||
import { HeaderMenu } from "../_common/HeaderMenu.jsx";
|
||||
import Markdown from "markdown-to-jsx";
|
||||
import { DEFAULT_ZOOM, ZOOM_FACTOR } from "../../../constants/applications/textEditor.js";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import { TITLE_SEPARATOR } from "../../../constants/windows.js";
|
||||
import { DEFAULT_ZOOM, ZOOM_FACTOR } from "../../../config/apps/textEditor.config.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
import { TITLE_SEPARATOR } from "../../../config/windows.config.js";
|
||||
|
||||
/**
|
||||
* @param {import("../../windows/WindowView.jsx").windowProps} props
|
||||
|
|
@ -7,11 +7,11 @@ import { useModals } from "../../hooks/modals/modals.js";
|
|||
import { ModalsView } from "../modals/ModalsView.jsx";
|
||||
import { useWindowsManager } from "../../hooks/windows/windowsManagerContext.js";
|
||||
import { useContextMenu } from "../../hooks/modals/contextMenu.js";
|
||||
import { FALLBACK_ICON_SIZE, FALLBACK_WALLPAPER } from "../../constants/desktop.js";
|
||||
import { reloadViewport } from "../../features/utils/browser.js";
|
||||
import { FALLBACK_ICON_SIZE, FALLBACK_WALLPAPER } from "../../config/desktop.config.js";
|
||||
import { reloadViewport } from "../../features/utils/browser.utils.js";
|
||||
import { useVirtualRoot } from "../../hooks/virtual-drive/virtualRootContext.js";
|
||||
import { DirectoryList } from "../applications/file-explorer/directory-list/DirectoryList.jsx";
|
||||
import { APPS, APP_ICONS, APP_NAMES } from "../../constants/applications.js";
|
||||
import { DirectoryList } from "../apps/file-explorer/directory-list/DirectoryList.jsx";
|
||||
import { APPS, APP_ICONS, APP_NAMES } from "../../config/apps.config.js";
|
||||
import Vector2 from "../../features/math/vector2.js";
|
||||
import { Actions } from "../actions/Actions.jsx";
|
||||
import { ClickAction } from "../actions/actions/ClickAction.jsx";
|
||||
|
|
@ -20,7 +20,7 @@ import { ToggleAction } from "../actions/actions/ToggleAction.jsx";
|
|||
import { DropdownAction } from "../actions/actions/DropdownAction.jsx";
|
||||
import { RadioAction } from "../actions/actions/RadioAction.jsx";
|
||||
import { Divider } from "../actions/actions/Divider.jsx";
|
||||
import { isValidInteger } from "../../features/utils/number.js";
|
||||
import { isValidInteger } from "../../features/utils/number.utils.js";
|
||||
|
||||
export const Desktop = memo(() => {
|
||||
const settingsManager = useSettingsManager();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { memo, useEffect, useRef } from "react";
|
||||
import { Modal } from "../../features/modals/modal.js";
|
||||
import ModalsManager from "../../features/modals/modals.js";
|
||||
import ModalsManager from "../../features/modals/modalsManager.js";
|
||||
import { ModalView } from "./ModalView.jsx";
|
||||
import styles from "./ModalsView.module.css";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { DIALOG_CONTENT_TYPES } from "../../../constants/modals.js";
|
||||
import { WindowedModal } from "../.templates/WindowedModal.jsx";
|
||||
import { DIALOG_CONTENT_TYPES } from "../../../config/modals.config.js";
|
||||
import { WindowedModal } from "../_templates/WindowedModal.jsx";
|
||||
|
||||
export function DialogBox({ modal, params, children, ...props }) {
|
||||
const onClick = (event) => {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import { ImagePreview } from "../../applications/file-explorer/directory-list/ImagePreview.jsx";
|
||||
import { WindowedModal } from "../.templates/WindowedModal.jsx";
|
||||
import { ImagePreview } from "../../apps/file-explorer/directory-list/ImagePreview.jsx";
|
||||
import { WindowedModal } from "../_templates/WindowedModal.jsx";
|
||||
import styles from "./FileProperties.module.css";
|
||||
import utilStyles from "../../../styles/utils.module.css";
|
||||
import Modal from "../../../features/modals/modal.js";
|
||||
import { VirtualFile } from "../../../features/virtual-drive/virtualFile.js";
|
||||
import { VirtualFile } from "../../../features/virtual-drive/file/virtualFile.js";
|
||||
import { StorageManager } from "../../../features/storage/storageManager.js";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
|
|
@ -14,7 +14,7 @@ import AppsManager from "../../../features/applications/applications.js";
|
|||
* @param {VirtualFile} props.file
|
||||
*/
|
||||
export function FileProperties({ modal, params, file, ...props }) {
|
||||
const associatedApp = AppsManager.getFileApp(file.extension);
|
||||
const associatedApp = AppsManager.getAppByFileExtension(file.extension);
|
||||
|
||||
return <WindowedModal className={styles.Container} modal={modal} params={params} {...props}>
|
||||
<span className={styles["Section"]}>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { memo, useEffect, useMemo, useRef, useState } from "react";
|
|||
import styles from "./Taskbar.module.css";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faCog, faSearch } from "@fortawesome/free-solid-svg-icons";
|
||||
import AppsManager from "../../features/applications/applications.js";
|
||||
import AppsManager from "../../features/apps/appsManager.js";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { HomeMenu } from "./menus/HomeMenu.jsx";
|
||||
import OutsideClickListener from "../../hooks/utils/outsideClick.js";
|
||||
|
|
@ -17,10 +17,10 @@ import { useContextMenu } from "../../hooks/modals/contextMenu.js";
|
|||
import { Actions } from "../actions/Actions.jsx";
|
||||
import { useModals } from "../../hooks/modals/modals.js";
|
||||
import { ClickAction } from "../actions/actions/ClickAction.jsx";
|
||||
import { APPS, APP_NAMES } from "../../constants/applications.js";
|
||||
import { APPS, APP_NAMES } from "../../config/apps.config.js";
|
||||
import { useWindowsManager } from "../../hooks/windows/windowsManagerContext.js";
|
||||
import { ModalsView } from "../modals/ModalsView.jsx";
|
||||
import { TASKBAR_HEIGHT } from "../../constants/taskBar.js";
|
||||
import { TASKBAR_HEIGHT } from "../../config/taskbar.config.js";
|
||||
import { useSettingsManager } from "../../hooks/settings/settingsManagerContext.js";
|
||||
import { SettingsManager } from "../../features/settings/settingsManager.js";
|
||||
import { useWindows } from "../../hooks/windows/windowsContext.js";
|
||||
|
|
@ -50,7 +50,7 @@ export const Taskbar = memo(() => {
|
|||
});
|
||||
const [pins, setPins] = useState([]);
|
||||
|
||||
const apps = useMemo(() => AppsManager.APPLICATIONS.sort((appA, appB) => {
|
||||
const apps = useMemo(() => AppsManager.APPS.sort((appA, appB) => {
|
||||
const indexA = pins.indexOf(appA.id);
|
||||
const indexB = pins.indexOf(appB.id);
|
||||
if (indexA < 0 && indexB > 0) {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
import { memo } from "react";
|
||||
import Application from "../../../features/applications/application.js";
|
||||
import App from "../../../features/apps/app.js";
|
||||
import styles from "./AppIcon.module.css";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { useSettingsManager } from "../../../hooks/settings/settingsManagerContext.js";
|
||||
import { useContextMenu } from "../../../hooks/modals/contextMenu.js";
|
||||
import ModalsManager from "../../../features/modals/modals.js";
|
||||
import ModalsManager from "../../../features/modals/modalsManager.js";
|
||||
import { Actions } from "../../actions/Actions.jsx";
|
||||
import { ClickAction } from "../../actions/actions/ClickAction.jsx";
|
||||
import { faThumbTack, faTimes } from "@fortawesome/free-solid-svg-icons";
|
||||
import { SettingsManager } from "../../../features/settings/settingsManager.js";
|
||||
import { removeFromArray } from "../../../features/utils/array.js";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import { removeFromArray } from "../../../features/utils/array.utils.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
* @param {Application} props.app
|
||||
* @param {App} props.app
|
||||
* @param {ModalsManager} props.modalsManager
|
||||
* @param {string[]} props.pins
|
||||
* @param {boolean} props.focused
|
||||
|
|
@ -76,7 +76,7 @@ export const AppButton = memo(({ app, windowsManager, modalsManager, pins, activ
|
|||
}}
|
||||
title={app.name}
|
||||
>
|
||||
<ReactSVG src={`${process.env.PUBLIC_URL}/assets/applications/icons/${app.id}.svg`}/>
|
||||
<ReactSVG src={`${process.env.PUBLIC_URL}/assets/apps/icons/${app.id}.svg`}/>
|
||||
</button>
|
||||
);
|
||||
});
|
||||
|
|
@ -3,16 +3,16 @@ import styles from "./HomeMenu.module.css";
|
|||
import appStyles from "./AppList.module.css";
|
||||
import { faCircleInfo, faFileLines, faGear, faImage, faPowerOff } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { closeViewport } from "../../../features/utils/browser.js";
|
||||
import { closeViewport } from "../../../features/utils/browser.utils.js";
|
||||
import { useKeyboardListener } from "../../../hooks/utils/keyboard.js";
|
||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext.js";
|
||||
import { useEffect, useState } from "react";
|
||||
import Vector2 from "../../../features/math/vector2.js";
|
||||
import utilStyles from "../../../styles/utils.module.css";
|
||||
import { APPS } from "../../../constants/applications.js";
|
||||
import { NAME } from "../../../constants/branding.js";
|
||||
import { APPS } from "../../../config/apps.config.js";
|
||||
import { NAME } from "../../../config/branding.config.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
|
|
@ -76,7 +76,7 @@ export function HomeMenu({ active, setActive, search }) {
|
|||
setActive(false);
|
||||
windowsManager.open("text-editor", {
|
||||
mode: "view",
|
||||
file: virtualRoot.navigate("~/Documents").findFile("info", "md"),
|
||||
file: virtualRoot.navigate("~/Documents/info.md"),
|
||||
size: new Vector2(575, 675),
|
||||
});
|
||||
}}>
|
||||
|
|
@ -98,7 +98,7 @@ export function HomeMenu({ active, setActive, search }) {
|
|||
<div className={styles.Apps}>
|
||||
<h1 className={utilStyles["Text-bold"]}>{NAME}</h1>
|
||||
<div className={appStyles["App-list"]}>
|
||||
{AppsManager.APPLICATIONS.map(({ name, id }) =>
|
||||
{AppsManager.APPS.map(({ name, id }) =>
|
||||
<button
|
||||
key={id}
|
||||
className={appStyles["App-button"]}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import styles from "./SearchMenu.module.css";
|
||||
import appStyles from "./AppList.module.css";
|
||||
import AppsManager from "../../../features/applications/applications.js";
|
||||
import AppsManager from "../../../features/apps/appsManager.js";
|
||||
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext.js";
|
||||
import { ReactSVG } from "react-svg";
|
||||
import { useEffect } from "react";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useKeyboardListener } from "../../../hooks/utils/keyboard.js";
|
||||
|
||||
/**
|
||||
|
|
@ -32,7 +31,7 @@ export function SearchMenu({ active, setActive, searchQuery, setSearchQuery, inp
|
|||
}, [inputRef]);
|
||||
|
||||
useEffect(() => {
|
||||
setApps(AppsManager.APPLICATIONS.filter(({ name }) =>
|
||||
setApps(AppsManager.APPS.filter(({ name }) =>
|
||||
name.toLowerCase().includes(searchQuery.toLowerCase().trim())
|
||||
));
|
||||
}, [searchQuery]);
|
||||
|
|
|
|||
|
|
@ -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 { formatShortcut } from "../../../features/utils/string.utils.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from "react";
|
||||
import { INTERACTIBLE_DOUBLE_CLICK_DELAY } from "../../../constants/utils.js";
|
||||
import { INTERACTIBLE_DOUBLE_CLICK_DELAY } from "../../../config/utils.config.js";
|
||||
|
||||
let timeoutId = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,33 +5,33 @@ import { ReactSVG } from "react-svg";
|
|||
import { useWindowsManager } from "../../hooks/windows/windowsManagerContext.js";
|
||||
import Draggable from "react-draggable";
|
||||
import { memo, useEffect, useRef, useState } from "react";
|
||||
import Application from "../../features/applications/application.js";
|
||||
import App from "../../features/apps/app.js";
|
||||
import Vector2 from "../../features/math/vector2.js";
|
||||
import { faWindowMaximize } from "@fortawesome/free-regular-svg-icons";
|
||||
import utilStyles from "../../styles/utils.module.css";
|
||||
import { useModals } from "../../hooks/modals/modals.js";
|
||||
import { ModalsView } from "../modals/ModalsView.jsx";
|
||||
import { useContextMenu } from "../../hooks/modals/contextMenu.js";
|
||||
import AppsManager from "../../features/applications/applications.js";
|
||||
import AppsManager from "../../features/apps/appsManager.js";
|
||||
import { ClickAction } from "../actions/actions/ClickAction.jsx";
|
||||
import { Actions } from "../actions/Actions.jsx";
|
||||
import { useScreenDimensions } from "../../hooks/utils/screen.js";
|
||||
|
||||
/**
|
||||
* @typedef {object} windowProps
|
||||
* @property {Application} app
|
||||
* @property {App} app
|
||||
* @property {Function} setTitle
|
||||
* @property {Function} setIconUrl
|
||||
* @property {Function} close
|
||||
* @property {Function} focus
|
||||
* @property {boolean} active
|
||||
* @property {import("../../features/modals/modals.js").default} modalsManager
|
||||
* @property {import("../../features/modals/modalsManager.js").default} modalsManager
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
* @param {string} props.id
|
||||
* @param {Application} props.app
|
||||
* @param {App} props.app
|
||||
* @param {Vector2} props.size
|
||||
* @param {Vector2} props.position
|
||||
* @param {boolean} props.focused
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const WindowsView = memo(() => {
|
|||
|
||||
// Launch startup apps
|
||||
useEffect(() => {
|
||||
const settings = settingsManager.get(SettingsManager.VIRTUAL_PATHS.applications);
|
||||
const settings = settingsManager.get(SettingsManager.VIRTUAL_PATHS.apps);
|
||||
settings.get("startup", (value) => {
|
||||
if (value !== "")
|
||||
windowsManager.startup(value?.split(","));
|
||||
|
|
|
|||
23
src/config/apps.config.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export const APPS = {
|
||||
TERMINAL: "terminal",
|
||||
SETTINGS: "settings",
|
||||
MEDIA_VIEWER: "media-viewer",
|
||||
TEXT_EDITOR: "text-editor",
|
||||
FILE_EXPLORER: "file-explorer"
|
||||
};
|
||||
|
||||
export const APP_NAMES = {
|
||||
TERMINAL: "Commands",
|
||||
SETTINGS: "Settings",
|
||||
MEDIA_VIEWER: "Photos",
|
||||
TEXT_EDITOR: "Notes",
|
||||
FILE_EXPLORER: "Files"
|
||||
};
|
||||
|
||||
export const APP_ICONS = {
|
||||
TERMINAL: `${process.env.PUBLIC_URL}/assets/apps/icons/${APPS.TERMINAL}.svg`,
|
||||
SETTINGS: `${process.env.PUBLIC_URL}/assets/apps/icons/${APPS.SETTINGS}.svg`,
|
||||
MEDIA_VIEWER: `${process.env.PUBLIC_URL}/assets/apps/icons/${APPS.MEDIA_VIEWER}.svg`,
|
||||
TEXT_EDITOR: `${process.env.PUBLIC_URL}/assets/apps/icons/${APPS.TEXT_EDITOR}.svg`,
|
||||
FILE_EXPLORER: `${process.env.PUBLIC_URL}/assets/apps/icons/${APPS.FILE_EXPLORER}.svg`,
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { ANSI } from "./applications/terminal.js";
|
||||
import { ANSI } from "./apps/terminal.config.js";
|
||||
|
||||
export const NAME = "Prozilla OS";
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
export const APPS = {
|
||||
TERMINAL: "terminal",
|
||||
SETTINGS: "settings",
|
||||
MEDIA_VIEWER: "media-viewer",
|
||||
TEXT_EDITOR: "text-editor",
|
||||
FILE_EXPLORER: "file-explorer"
|
||||
};
|
||||
|
||||
export const APP_NAMES = {
|
||||
TERMINAL: "Commands",
|
||||
SETTINGS: "Settings",
|
||||
MEDIA_VIEWER: "Photos",
|
||||
TEXT_EDITOR: "Notes",
|
||||
FILE_EXPLORER: "Files"
|
||||
};
|
||||
|
||||
export const APP_ICONS = {
|
||||
TERMINAL: `${process.env.PUBLIC_URL}/assets/applications/icons/${APPS.TERMINAL}.svg`,
|
||||
SETTINGS: `${process.env.PUBLIC_URL}/assets/applications/icons/${APPS.SETTINGS}.svg`,
|
||||
MEDIA_VIEWER: `${process.env.PUBLIC_URL}/assets/applications/icons/${APPS.MEDIA_VIEWER}.svg`,
|
||||
TEXT_EDITOR: `${process.env.PUBLIC_URL}/assets/applications/icons/${APPS.TEXT_EDITOR}.svg`,
|
||||
FILE_EXPLORER: `${process.env.PUBLIC_URL}/assets/applications/icons/${APPS.FILE_EXPLORER}.svg`,
|
||||
};
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
import Application from "./application.js";
|
||||
import { FileExplorer } from "../../components/applications/file-explorer/FileExplorer.jsx";
|
||||
import { MediaViewer } from "../../components/applications/media-viewer/MediaViewer.jsx";
|
||||
import { WebView } from "../../components/applications/.templates/WebView.jsx";
|
||||
import { Terminal } from "../../components/applications/terminal/Terminal.jsx";
|
||||
import { TextEditor } from "../../components/applications/text-editor/TextEditor.jsx";
|
||||
import { Settings } from "../../components/applications/settings/Settings.jsx";
|
||||
// import { Calculator } from "../../components/applications/calculator/Calculator.jsx";
|
||||
import Vector2 from "../math/vector2.js";
|
||||
import { APPS } from "../../constants/applications.js";
|
||||
import { Browser } from "../../components/applications/browser/Browser.jsx";
|
||||
|
||||
export default class AppsManager {
|
||||
static APPLICATIONS = [
|
||||
new Application("Commands", APPS.TERMINAL, Terminal),
|
||||
new Application("Settings", APPS.SETTINGS, Settings),
|
||||
new Application("Photos", APPS.MEDIA_VIEWER, MediaViewer),
|
||||
// new Application("Browser", "browser"),
|
||||
// new Application("Calculator", "calculator", Calculator, { size: new Vector2(400, 600) }),
|
||||
new Application("Notes", APPS.TEXT_EDITOR, TextEditor),
|
||||
// new Application("Code Editor", "code-editor"),
|
||||
new Application("Files", APPS.FILE_EXPLORER, FileExplorer),
|
||||
new Application("Wordle", "wordle", WebView, {
|
||||
source: "https://prozilla.dev/wordle",
|
||||
size: new Vector2(400, 650)
|
||||
}),
|
||||
new Application("Balls", "balls", WebView, {
|
||||
source: "https://prozilla.dev/ball-maze",
|
||||
size: new Vector2(600, 600)
|
||||
}),
|
||||
new Application("Minesweeper", "minesweeper", WebView, {
|
||||
source: "https://prozilla.dev/minesweeper",
|
||||
size: new Vector2(500, 580)
|
||||
}),
|
||||
new Application("Browser", "browser", Browser, {
|
||||
size: new Vector2(700, 500)
|
||||
}),
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @returns {Application | null}
|
||||
*/
|
||||
static getApp(id) {
|
||||
let application = null;
|
||||
|
||||
this.APPLICATIONS.forEach((app) => {
|
||||
if (app.id === id) {
|
||||
application = app;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the application associated with a file extension
|
||||
* @param {string} fileExtension
|
||||
* @returns {Application}
|
||||
*/
|
||||
static getFileApp(fileExtension) {
|
||||
let app = null;
|
||||
|
||||
// eslint-disable-next-line default-case
|
||||
switch (fileExtension) {
|
||||
case "png":
|
||||
app = this.getApp(APPS.MEDIA_VIEWER);
|
||||
break;
|
||||
case "txt":
|
||||
case "md":
|
||||
case "xml":
|
||||
app = this.getApp(APPS.TEXT_EDITOR);
|
||||
break;
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url of an icon inside the icons folder or the default icon of an app
|
||||
* @param {string} appId
|
||||
* @param {string | null} iconName
|
||||
* @returns {string}
|
||||
*/
|
||||
static getAppIconUrl(appId, iconName) {
|
||||
if (iconName == null) {
|
||||
return `${process.env.PUBLIC_URL}/assets/applications/icons/${appId}.svg`;
|
||||
} else {
|
||||
return `${process.env.PUBLIC_URL}/assets/applications/${appId}/icons/${iconName}.svg`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
|
||||
export default class Application {
|
||||
export default class App {
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {string} id
|
||||
93
src/features/apps/appsManager.js
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import App from "./app.js";
|
||||
import { FileExplorer } from "../../components/apps/file-explorer/FileExplorer.jsx";
|
||||
import { MediaViewer } from "../../components/apps/media-viewer/MediaViewer.jsx";
|
||||
import { WebView } from "../../components/apps/_templates/WebView.jsx";
|
||||
import { Terminal } from "../../components/apps/terminal/Terminal.jsx";
|
||||
import { TextEditor } from "../../components/apps/text-editor/TextEditor.jsx";
|
||||
import { Settings } from "../../components/apps/settings/Settings.jsx";
|
||||
// import { Calculator } from "../../components/apps/calculator/Calculator.jsx";
|
||||
import Vector2 from "../math/vector2.js";
|
||||
import { APPS } from "../../config/apps.config.js";
|
||||
import { Browser } from "../../components/apps/browser/Browser.jsx";
|
||||
|
||||
export default class AppsManager {
|
||||
static APPS = [
|
||||
new App("Commands", APPS.TERMINAL, Terminal),
|
||||
new App("Settings", APPS.SETTINGS, Settings),
|
||||
new App("Photos", APPS.MEDIA_VIEWER, MediaViewer),
|
||||
// new App("Browser", "browser"),
|
||||
// new App("Calculator", "calculator", Calculator, { size: new Vector2(400, 600) }),
|
||||
new App("Notes", APPS.TEXT_EDITOR, TextEditor),
|
||||
// new App("Code Editor", "code-editor"),
|
||||
new App("Files", APPS.FILE_EXPLORER, FileExplorer),
|
||||
new App("Wordle", "wordle", WebView, {
|
||||
source: "https://prozilla.dev/wordle",
|
||||
size: new Vector2(400, 650)
|
||||
}),
|
||||
new App("Balls", "balls", WebView, {
|
||||
source: "https://prozilla.dev/ball-maze",
|
||||
size: new Vector2(600, 600)
|
||||
}),
|
||||
new App("Minesweeper", "minesweeper", WebView, {
|
||||
source: "https://prozilla.dev/minesweeper",
|
||||
size: new Vector2(500, 580)
|
||||
}),
|
||||
new App("Browser", "browser", Browser, {
|
||||
size: new Vector2(700, 500)
|
||||
}),
|
||||
];
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @returns {App | null}
|
||||
*/
|
||||
static getAppById(id) {
|
||||
let application = null;
|
||||
|
||||
this.APPS.forEach((app) => {
|
||||
if (app.id === id) {
|
||||
application = app;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
return application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the app associated with a file extension
|
||||
* @param {string} fileExtension
|
||||
* @returns {App}
|
||||
*/
|
||||
static getAppByFileExtension(fileExtension) {
|
||||
let app = null;
|
||||
|
||||
// eslint-disable-next-line default-case
|
||||
switch (fileExtension) {
|
||||
case "png":
|
||||
app = this.getAppById(APPS.MEDIA_VIEWER);
|
||||
break;
|
||||
case "txt":
|
||||
case "md":
|
||||
case "xml":
|
||||
app = this.getAppById(APPS.TEXT_EDITOR);
|
||||
break;
|
||||
}
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the url of an icon inside the icons folder or the default icon of an app
|
||||
* @param {string} appId
|
||||
* @param {string | null} iconName
|
||||
* @returns {string}
|
||||
*/
|
||||
static getAppIconUrl(appId, iconName) {
|
||||
if (iconName == null) {
|
||||
return `${process.env.PUBLIC_URL}/assets/apps/icons/${appId}.svg`;
|
||||
} else {
|
||||
return `${process.env.PUBLIC_URL}/assets/apps/${appId}/icons/${iconName}.svg`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { VirtualFolder } from "../../virtual-drive/virtualFolder.js";
|
||||
import { VirtualRoot } from "../../virtual-drive/virtualRoot.js";
|
||||
import { VirtualFolder } from "../../virtual-drive/folder/virtualFolder.js";
|
||||
import { VirtualRoot } from "../../virtual-drive/root/virtualRoot.js";
|
||||
|
||||
/**
|
||||
* @callback executeType
|
||||