Added terminal and text editor apps
This commit is contained in:
parent
32155b80d7
commit
443b5c8766
75 changed files with 643 additions and 376 deletions
|
|
@ -22,9 +22,8 @@
|
||||||
"packages:release": "pnpm changeset publish"
|
"packages:release": "pnpm changeset publish"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/prozilla-os",
|
"packages/*",
|
||||||
"packages/core",
|
"packages/apps/*"
|
||||||
"packages/apps/file-explorer"
|
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
# @prozilla-os/file-explorer
|
# @prozilla-os/file-explorer
|
||||||
|
|
||||||
|
## 1.0.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Added terminal and text editor app + adjusted links in app packages
|
||||||
|
- Updated dependencies
|
||||||
|
- @prozilla-os/core@1.0.11
|
||||||
|
|
||||||
## 1.0.7
|
## 1.0.7
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ function App() {
|
||||||
- [npm][npm]
|
- [npm][npm]
|
||||||
- [Ko-fi][ko-fi]
|
- [Ko-fi][ko-fi]
|
||||||
|
|
||||||
[website]: https://os.prozilla.dev/
|
[website]: https://os.prozilla.dev/file-explorer
|
||||||
[github]: https://github.com/prozilla-os/ProzillaOS/tree/convert-to-monorepo/packages/apps/file-explorer
|
[github]: https://github.com/prozilla-os/ProzillaOS/tree/convert-to-monorepo/packages/apps/file-explorer
|
||||||
[npm]: https://www.npmjs.com/package/@prozilla-os/file-explorer
|
[npm]: https://www.npmjs.com/package/@prozilla-os/file-explorer
|
||||||
[ko-fi]: https://ko-fi.com/prozilla
|
[ko-fi]: https://ko-fi.com/prozilla
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "@prozilla-os/file-explorer",
|
"name": "@prozilla-os/file-explorer",
|
||||||
"description": "A standard ProzillaOS application for browsing files.",
|
"description": "A standard ProzillaOS application for browsing files.",
|
||||||
"version": "1.0.7",
|
"version": "1.0.8",
|
||||||
|
"homepage": "https://os.prozilla.dev/file-explorer",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Prozilla",
|
"name": "Prozilla",
|
||||||
"email": "business@prozilla.dev",
|
"email": "business@prozilla.dev",
|
||||||
|
|
@ -14,7 +15,7 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/Prozilla/ProzillaOS.git",
|
"url": "git+https://github.com/prozilla-os/ProzillaOS.git",
|
||||||
"directory": "packages/apps/file-explorer"
|
"directory": "packages/apps/file-explorer"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
import { App } from "@prozilla-os/core";
|
import { App } from "@prozilla-os/core";
|
||||||
import { FileExplorer } from "./components/FileExplorer";
|
import { FileExplorer } from "./components/FileExplorer";
|
||||||
import { VirtualBase } from "@prozilla-os/core/src/features/virtual-drive/virtualBase";
|
|
||||||
|
|
||||||
const fileExplorer = new App("File Explorer", "file-explorer", FileExplorer)
|
const fileExplorer = new App("File Explorer", "file-explorer", FileExplorer)
|
||||||
.setIconUrl("https://os.prozilla.dev/assets/apps/icons/file-explorer.svg");
|
.setIconUrl("https://os.prozilla.dev/assets/apps/icons/file-explorer.svg");
|
||||||
|
|
||||||
export { fileExplorer };
|
export { fileExplorer };
|
||||||
export { FileSelectorMode } from "./types/index.d";
|
export { FileSelectorMode } from "./types/index.d";
|
||||||
VirtualBase;
|
|
||||||
9
packages/apps/terminal/CHANGELOG.md
Normal file
9
packages/apps/terminal/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# @prozilla-os/terminal
|
||||||
|
|
||||||
|
## 1.0.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Added terminal and text editor app + adjusted links in app packages
|
||||||
|
- Updated dependencies
|
||||||
|
- @prozilla-os/core@1.0.11
|
||||||
64
packages/apps/terminal/README.md
Normal file
64
packages/apps/terminal/README.md
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<div align="center">
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
<a href="https://os.prozilla.dev/"><img src="https://os.prozilla.dev/assets/logo.svg" height="200" alt="ProzillaOS" /></a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS/blob/main/LICENSE.md"><img alt="License" src="https://img.shields.io/github/license/Prozilla/ProzillaOS?style=flat-square&color=FF4D5B&label=License"></a>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS"><img alt="Stars" src="https://img.shields.io/github/stars/Prozilla/ProzillaOS?style=flat-square&color=FED24C&label=%E2%AD%90"></a>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS"><img alt="Forks" src="https://img.shields.io/github/forks/Prozilla/ProzillaOS?style=flat-square&color=4D9CFF&label=Forks&logo=github"></a>
|
||||||
|
<a href="https://www.npmjs.com/package/prozilla-os"><img alt="NPM Version" src="https://img.shields.io/npm/v/prozilla-os?logo=npm&style=flat-square&label=prozilla-os&color=FF4D5B"></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
`@prozilla-os/terminal` is a terminal/shell application for ProzillaOS.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`@prozilla-os/core` is required to run this application.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm install @prozilla-os/core @prozilla-os/terminal
|
||||||
|
$ yarn add @prozilla-os/core @prozilla-os/terminal
|
||||||
|
$ pnpm add @prozilla-os/core @prozilla-os/terminal
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Desktop, ModalsView, ProzillaOS, Taskbar, WindowsView, AppsConfig } from "@prozilla-os/core";
|
||||||
|
import { terminal } from "@prozilla-os/terminal";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<ProzillaOS
|
||||||
|
systemName="Example"
|
||||||
|
tagLine="Powered by ProzillaOS"
|
||||||
|
config={{
|
||||||
|
apps: new AppsConfig({
|
||||||
|
apps: [ terminal ]
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Taskbar/>
|
||||||
|
<WindowsView/>
|
||||||
|
<ModalsView/>
|
||||||
|
<Desktop/>
|
||||||
|
</ProzillaOS>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Website/demo][website]
|
||||||
|
- [GitHub][github]
|
||||||
|
- [npm][npm]
|
||||||
|
- [Ko-fi][ko-fi]
|
||||||
|
|
||||||
|
[website]: https://os.prozilla.dev/terminal
|
||||||
|
[github]: https://github.com/prozilla-os/ProzillaOS/tree/convert-to-monorepo/packages/apps/terminal
|
||||||
|
[npm]: https://www.npmjs.com/package/@prozilla-os/terminal
|
||||||
|
[ko-fi]: https://ko-fi.com/prozilla
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
export const USERNAME = "user";
|
|
||||||
export const HOSTNAME = "prozilla-os";
|
|
||||||
export const MAX_WIDTH = 50;
|
|
||||||
|
|
||||||
export const ANSI = {
|
|
||||||
fg: {
|
|
||||||
black: "\u001b[30m",
|
|
||||||
red: "\u001b[31m",
|
|
||||||
green: "\u001b[32m",
|
|
||||||
yellow: "\u001b[33m",
|
|
||||||
blue: "\u001b[34m",
|
|
||||||
magenta: "\u001b[35m",
|
|
||||||
cyan: "\u001b[36m",
|
|
||||||
white: "\u001b[37m",
|
|
||||||
},
|
|
||||||
bg: {
|
|
||||||
|
|
||||||
},
|
|
||||||
decoration: {
|
|
||||||
dim: "\u001b[2m",
|
|
||||||
},
|
|
||||||
reset: "\u001b[0m",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const WELCOME_MESSAGE = `${ANSI.fg.cyan + ANSI.decoration.dim}$APP_NAME - Made by Prozilla${ANSI.reset}`
|
|
||||||
+ `\n${ANSI.decoration.dim}Type 'help' for a list of commands.${ANSI.reset}\n`;
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import { TimeManager } from "../../../_utils/time.utils";
|
|
||||||
import { Command } from "../command";
|
|
||||||
|
|
||||||
export const uptime = new Command()
|
|
||||||
.setManual({
|
|
||||||
purpose: "Display the current uptime of the system"
|
|
||||||
})
|
|
||||||
.setExecute(function() {
|
|
||||||
return `Uptime: ${TimeManager.getUptime(2)}`;
|
|
||||||
});
|
|
||||||
38
packages/apps/terminal/package.json
Normal file
38
packages/apps/terminal/package.json
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"name": "@prozilla-os/terminal",
|
||||||
|
"description": "A terminal/shell application for ProzillaOS.",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"homepage": "https://os.prozilla.dev/terminal",
|
||||||
|
"author": {
|
||||||
|
"name": "Prozilla",
|
||||||
|
"email": "business@prozilla.dev",
|
||||||
|
"url": "https://prozilla.dev/"
|
||||||
|
},
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "tsc --watch"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/prozilla-os/ProzillaOS.git",
|
||||||
|
"directory": "packages/apps/terminal"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@prozilla-os/core": "workspace:*",
|
||||||
|
"anser": "^2.1.1",
|
||||||
|
"escape-carriage": "^1.3.1",
|
||||||
|
"react": "^18.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://registry.npmjs.org/",
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,20 +1,13 @@
|
||||||
import { MouseEventHandler, MutableRefObject, useEffect, useRef, useState } from "react";
|
import { MouseEventHandler, MutableRefObject, useEffect, useRef, useState } from "react";
|
||||||
import styles from "./Terminal.module.css";
|
import styles from "./Terminal.module.css";
|
||||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext";
|
|
||||||
import { OutputLine } from "./OutputLine";
|
import { OutputLine } from "./OutputLine";
|
||||||
import { InputLine } from "./InputLine";
|
import { InputLine } from "./InputLine";
|
||||||
import { ANSI, HOSTNAME, USERNAME, WELCOME_MESSAGE } from "../../../config/apps/terminal.config";
|
import { ANSI, App, clamp, removeFromArray, SettingsManager, useSettingsManager, useSystemManager, useVirtualRoot, VirtualFolder, WindowProps } from "@prozilla-os/core";
|
||||||
import { CommandsManager } from "../../../features/apps/terminal/commands";
|
import { HOSTNAME, USERNAME, WELCOME_MESSAGE } from "../constants/terminal.const";
|
||||||
import { removeFromArray } from "../../../features/_utils/array.utils";
|
import { Stream } from "../core/stream";
|
||||||
import { Stream } from "../../../features/apps/terminal/stream";
|
import { CommandResponse } from "../core/command";
|
||||||
import { formatError } from "../../../features/apps/terminal/_utils/terminal.utils";
|
import { formatError } from "../core/_utils/terminal.utils";
|
||||||
import { WindowProps } from "../../windows/WindowView";
|
import { CommandsManager } from "../core/commands";
|
||||||
import { VirtualFolder } from "../../../features/virtual-drive/folder/virtualFolder";
|
|
||||||
import { CommandResponse } from "../../../features/apps/terminal/command";
|
|
||||||
import { APP_NAMES } from "../../../config/apps.config";
|
|
||||||
import { useSettingsManager } from "../../../hooks/settings/settingsManagerContext";
|
|
||||||
import { SettingsManager } from "../../../features/settings/settingsManager";
|
|
||||||
import { clamp } from "../../../features/_utils/math.utils";
|
|
||||||
|
|
||||||
interface TerminalProps extends WindowProps {
|
interface TerminalProps extends WindowProps {
|
||||||
path: string;
|
path: string;
|
||||||
|
|
@ -28,11 +21,12 @@ interface HistoryEntry {
|
||||||
clear?: boolean;
|
clear?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Terminal({ path: startPath, input, setTitle, close: exit, active, focus }: TerminalProps) {
|
export function Terminal({ app, path: startPath, input, setTitle, close: exit, active, focus }: TerminalProps) {
|
||||||
|
const systemManager = useSystemManager();
|
||||||
const [inputKey, setInputKey] = useState(0);
|
const [inputKey, setInputKey] = useState(0);
|
||||||
const [inputValue, setInputValue] = useState(input ?? "");
|
const [inputValue, setInputValue] = useState(input ?? "");
|
||||||
const [history, setHistory] = useState<HistoryEntry[]>([{
|
const [history, setHistory] = useState<HistoryEntry[]>([{
|
||||||
text: WELCOME_MESSAGE.replace("$APP_NAME", APP_NAMES.TERMINAL),
|
text: app ? WELCOME_MESSAGE.replace("$APP_NAME", app.name) : WELCOME_MESSAGE,
|
||||||
isInput: false,
|
isInput: false,
|
||||||
}]);
|
}]);
|
||||||
const virtualRoot = useVirtualRoot();
|
const virtualRoot = useVirtualRoot();
|
||||||
|
|
@ -215,6 +209,8 @@ export function Terminal({ path: startPath, input, setTitle, close: exit, active
|
||||||
inputs,
|
inputs,
|
||||||
timestamp,
|
timestamp,
|
||||||
settingsManager: settingsManager as SettingsManager,
|
settingsManager: settingsManager as SettingsManager,
|
||||||
|
systemManager,
|
||||||
|
app: app as App,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response == null)
|
if (response == null)
|
||||||
43
packages/apps/terminal/src/constants/terminal.const.ts
Normal file
43
packages/apps/terminal/src/constants/terminal.const.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { ANSI } from "@prozilla-os/core";
|
||||||
|
|
||||||
|
export const USERNAME = "user";
|
||||||
|
export const HOSTNAME = "prozilla-os";
|
||||||
|
export const MAX_WIDTH = 50;
|
||||||
|
|
||||||
|
export const WELCOME_MESSAGE = `${ANSI.fg.cyan + ANSI.decoration.dim}$APP_NAME - Made by Prozilla${ANSI.reset}`
|
||||||
|
+ `\n${ANSI.decoration.dim}Type 'help' for a list of commands.${ANSI.reset}\n`;
|
||||||
|
|
||||||
|
export const ASCII_LOGO = `
|
||||||
|
:.
|
||||||
|
-==.
|
||||||
|
.=====:
|
||||||
|
---::..:=======-.
|
||||||
|
:===+=----------::..
|
||||||
|
=+=---------------:..
|
||||||
|
--------------------:.
|
||||||
|
.:-+=----*###*--*####=---.
|
||||||
|
:==+----#%+-+%#-##%*+----:.
|
||||||
|
.=----#%+-+%#-*+-%#+---:.
|
||||||
|
==----*###*--*###*----.
|
||||||
|
==+-------------------:.
|
||||||
|
...::---------------:.
|
||||||
|
.::---------::..
|
||||||
|
....::... `;
|
||||||
|
|
||||||
|
export const ANSI_LOGO_COLOR = ANSI.fg.cyan;
|
||||||
|
export const ANSI_ASCII_LOGO = `
|
||||||
|
:.
|
||||||
|
-==.
|
||||||
|
.=====:
|
||||||
|
---::..:=======-.
|
||||||
|
:===+=----------::..
|
||||||
|
=+=---------------:..
|
||||||
|
--------------------:.
|
||||||
|
.:-+=----${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}--${ANSI.fg.white}*####=${ANSI_LOGO_COLOR}---.
|
||||||
|
:==+----${ANSI.fg.white}#%+${ANSI_LOGO_COLOR}-${ANSI.fg.white}+%#${ANSI_LOGO_COLOR}-${ANSI.fg.white}##%*+${ANSI_LOGO_COLOR}----:.
|
||||||
|
.=----${ANSI.fg.white}#%+${ANSI_LOGO_COLOR}-${ANSI.fg.white}+%#${ANSI_LOGO_COLOR}-${ANSI.fg.white}*+${ANSI_LOGO_COLOR}-${ANSI.fg.white}%#+${ANSI_LOGO_COLOR}---:.
|
||||||
|
==----${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}--${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}----.
|
||||||
|
==+-------------------:.
|
||||||
|
...::---------------:.
|
||||||
|
.::---------::..
|
||||||
|
....::... `;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI } from "@prozilla-os/core";
|
||||||
|
|
||||||
export function formatError(commandName: string, error: string): string {
|
export function formatError(commandName: string, error: string): string {
|
||||||
return `${ANSI.fg.red}${commandName}: ${error}${ANSI.reset}`;
|
return `${ANSI.fg.red}${commandName}: ${error}${ANSI.reset}`;
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
import { SettingsManager } from "../../settings/settingsManager";
|
import { App, SettingsManager, SystemManager, VirtualFolder, VirtualRoot } from "@prozilla-os/core";
|
||||||
import { VirtualFolder } from "../../virtual-drive/folder/virtualFolder";
|
|
||||||
import { VirtualRoot } from "../../virtual-drive/root/virtualRoot";
|
|
||||||
import { Stream } from "./stream";
|
import { Stream } from "./stream";
|
||||||
|
|
||||||
type Option = {
|
type Option = {
|
||||||
|
|
@ -24,6 +22,8 @@ export type ExecuteParams = {
|
||||||
inputs?: Record<string, string>,
|
inputs?: Record<string, string>,
|
||||||
timestamp: number,
|
timestamp: number,
|
||||||
settingsManager: SettingsManager,
|
settingsManager: SettingsManager,
|
||||||
|
systemManager: SystemManager,
|
||||||
|
app: App,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Execute = (args?: string[], params?: ExecuteParams) => CommandResponse | Promise<CommandResponse>;
|
type Execute = (args?: string[], params?: ExecuteParams) => CommandResponse | Promise<CommandResponse>;
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file";
|
import { VirtualFile } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI, randomFromArray, randomRange, removeFromArray, Vector2 } from "@prozilla-os/core";
|
||||||
import { randomFromArray, removeFromArray } from "../../../_utils/array.utils";
|
|
||||||
import { randomRange } from "../../../_utils/math.utils";
|
|
||||||
import { Vector2 } from "../../../math/vector2";
|
|
||||||
import { Command } from "../command";
|
import { Command } from "../command";
|
||||||
import { Stream } from "../stream";
|
import { Stream } from "../stream";
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { MAX_WIDTH } from "../../../../config/apps/terminal.config";
|
import { MAX_WIDTH } from "../../constants/terminal.const";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
const COW = `
|
const COW = `
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { randomFromArray } from "../../../_utils/array.utils";
|
import { randomFromArray } from "@prozilla-os/core";
|
||||||
import { Command } from "../command";
|
import { Command } from "../command";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command } from "../command";
|
import { Command } from "../command";
|
||||||
import { CommandsManager } from "../commands";
|
import { CommandsManager } from "../commands";
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI } from "@prozilla-os/core";
|
||||||
import { removeAnsi } from "../_utils/terminal.utils";
|
import { removeAnsi } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI, VirtualFolder } from "@prozilla-os/core";
|
||||||
import { VirtualFolder } from "../../../virtual-drive/folder/virtualFolder";
|
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
import { CommandsManager } from "../commands";
|
import { CommandsManager } from "../commands";
|
||||||
|
|
@ -1,10 +1,5 @@
|
||||||
import { APPS } from "../../../../config/apps.config";
|
import { ANSI, SettingsManager, THEMES } from "@prozilla-os/core";
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI_ASCII_LOGO, ANSI_LOGO_COLOR } from "../../constants/terminal.const";
|
||||||
import { ANSI_ASCII_LOGO, ANSI_LOGO_COLOR, NAME } from "../../../../config/branding.config";
|
|
||||||
import { THEMES } from "../../../../config/themes.config";
|
|
||||||
import { TimeManager } from "../../../_utils/time.utils";
|
|
||||||
import { SettingsManager } from "../../../settings/settingsManager";
|
|
||||||
import { AppsManager } from "../../appsManager";
|
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
export const neofetch = new Command()
|
export const neofetch = new Command()
|
||||||
|
|
@ -12,7 +7,7 @@ export const neofetch = new Command()
|
||||||
purpose: "Fetch system information"
|
purpose: "Fetch system information"
|
||||||
})
|
})
|
||||||
.setExecute(async function(args, params) {
|
.setExecute(async function(args, params) {
|
||||||
const { username, hostname, settingsManager } = params as ExecuteParams;
|
const { username, hostname, app, systemManager, settingsManager } = params as ExecuteParams;
|
||||||
const leftColumn = ANSI_ASCII_LOGO.split("\n");
|
const leftColumn = ANSI_ASCII_LOGO.split("\n");
|
||||||
const rightColumnWidth = (username?.length ?? 0) + (hostname?.length ?? 0) + 1;
|
const rightColumnWidth = (username?.length ?? 0) + (hostname?.length ?? 0) + 1;
|
||||||
|
|
||||||
|
|
@ -43,12 +38,12 @@ export const neofetch = new Command()
|
||||||
const rightColumn = [
|
const rightColumn = [
|
||||||
`${ANSI.fg.cyan + username + ANSI.reset}@${ANSI.fg.cyan + hostname + ANSI.reset}`,
|
`${ANSI.fg.cyan + username + ANSI.reset}@${ANSI.fg.cyan + hostname + ANSI.reset}`,
|
||||||
"-".repeat(rightColumnWidth),
|
"-".repeat(rightColumnWidth),
|
||||||
formatLine("os", NAME),
|
formatLine("os", systemManager.systemName),
|
||||||
formatLine("uptime", TimeManager.getUptime(2)),
|
formatLine("uptime", systemManager.getUptime(2)),
|
||||||
formatLine("resolution", window.innerWidth + "x" + window.innerHeight),
|
formatLine("resolution", window.innerWidth + "x" + window.innerHeight),
|
||||||
formatLine("theme", theme),
|
formatLine("theme", theme),
|
||||||
formatLine("icons", "Font Awesome"),
|
formatLine("icons", "Font Awesome"),
|
||||||
formatLine("terminal", AppsManager.getAppById(APPS.TERMINAL)?.name ?? "Unknown"),
|
formatLine("terminal", app?.name ?? "Unknown"),
|
||||||
formatLine("browser", browserName),
|
formatLine("browser", browserName),
|
||||||
formatLine("platform", navigator.platform),
|
formatLine("platform", navigator.platform),
|
||||||
formatLine("language", navigator.language),
|
formatLine("language", navigator.language),
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { reloadViewport } from "../../../_utils/browser.utils";
|
import { reloadViewport } from "@prozilla-os/core";
|
||||||
import { Command } from "../command";
|
import { Command } from "../command";
|
||||||
|
|
||||||
export const reboot = new Command()
|
export const reboot = new Command()
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file";
|
import { VirtualFile } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { VirtualFile } from "../../../virtual-drive/file";
|
import { VirtualFile } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command, ExecuteParams } from "../command";
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
10
packages/apps/terminal/src/core/commands/uptime.ts
Normal file
10
packages/apps/terminal/src/core/commands/uptime.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { Command, ExecuteParams } from "../command";
|
||||||
|
|
||||||
|
export const uptime = new Command()
|
||||||
|
.setManual({
|
||||||
|
purpose: "Display the current uptime of the system"
|
||||||
|
})
|
||||||
|
.setExecute(function(args, params) {
|
||||||
|
const { systemManager } = params as ExecuteParams;
|
||||||
|
return `Uptime: ${systemManager.getUptime(2)}`;
|
||||||
|
});
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ANSI } from "../../../../config/apps/terminal.config";
|
import { ANSI } from "@prozilla-os/core";
|
||||||
import { formatError } from "../_utils/terminal.utils";
|
import { formatError } from "../_utils/terminal.utils";
|
||||||
import { Command } from "../command";
|
import { Command } from "../command";
|
||||||
import { CommandsManager } from "../commands";
|
import { CommandsManager } from "../commands";
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { EventEmitter } from "../../_utils/event.utils";
|
import { EventEmitter } from "@prozilla-os/core";
|
||||||
|
|
||||||
const StreamEvents = {
|
const StreamEvents = {
|
||||||
new: "new",
|
new: "new",
|
||||||
7
packages/apps/terminal/src/index.ts
Normal file
7
packages/apps/terminal/src/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { App } from "@prozilla-os/core";
|
||||||
|
import { Terminal } from "./components/Terminal";
|
||||||
|
|
||||||
|
const terminal = new App("Terminal", "terminal", Terminal)
|
||||||
|
.setIconUrl("https://os.prozilla.dev/assets/apps/icons/terminal.svg");
|
||||||
|
|
||||||
|
export { terminal };
|
||||||
5
packages/apps/terminal/tsconfig.json
Normal file
5
packages/apps/terminal/tsconfig.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
9
packages/apps/text-editor/CHANGELOG.md
Normal file
9
packages/apps/text-editor/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
# @prozilla-os/text-editor
|
||||||
|
|
||||||
|
## 1.0.1
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Added terminal and text editor app + adjusted links in app packages
|
||||||
|
- Updated dependencies
|
||||||
|
- @prozilla-os/core@1.0.11
|
||||||
64
packages/apps/text-editor/README.md
Normal file
64
packages/apps/text-editor/README.md
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
<div align="center">
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
<a href="https://os.prozilla.dev/"><img src="https://os.prozilla.dev/assets/logo.svg" height="200" alt="ProzillaOS" /></a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS/blob/main/LICENSE.md"><img alt="License" src="https://img.shields.io/github/license/Prozilla/ProzillaOS?style=flat-square&color=FF4D5B&label=License"></a>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS"><img alt="Stars" src="https://img.shields.io/github/stars/Prozilla/ProzillaOS?style=flat-square&color=FED24C&label=%E2%AD%90"></a>
|
||||||
|
<a href="https://github.com/prozilla-os/ProzillaOS"><img alt="Forks" src="https://img.shields.io/github/forks/Prozilla/ProzillaOS?style=flat-square&color=4D9CFF&label=Forks&logo=github"></a>
|
||||||
|
<a href="https://www.npmjs.com/package/prozilla-os"><img alt="NPM Version" src="https://img.shields.io/npm/v/prozilla-os?logo=npm&style=flat-square&label=prozilla-os&color=FF4D5B"></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
`@prozilla-os/text-editor` is a text editor application for ProzillaOS.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`@prozilla-os/core` is required to run this application.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ npm install @prozilla-os/core @prozilla-os/text-editor
|
||||||
|
$ yarn add @prozilla-os/core @prozilla-os/text-editor
|
||||||
|
$ pnpm add @prozilla-os/core @prozilla-os/text-editor
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Desktop, ModalsView, ProzillaOS, Taskbar, WindowsView, AppsConfig } from "@prozilla-os/core";
|
||||||
|
import { textEditor } from "@prozilla-os/text-editor";
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<ProzillaOS
|
||||||
|
systemName="Example"
|
||||||
|
tagLine="Powered by ProzillaOS"
|
||||||
|
config={{
|
||||||
|
apps: new AppsConfig({
|
||||||
|
apps: [ textEditor ]
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Taskbar/>
|
||||||
|
<WindowsView/>
|
||||||
|
<ModalsView/>
|
||||||
|
<Desktop/>
|
||||||
|
</ProzillaOS>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Website/demo][website]
|
||||||
|
- [GitHub][github]
|
||||||
|
- [npm][npm]
|
||||||
|
- [Ko-fi][ko-fi]
|
||||||
|
|
||||||
|
[website]: https://os.prozilla.dev/text-editor
|
||||||
|
[github]: https://github.com/prozilla-os/ProzillaOS/tree/convert-to-monorepo/packages/apps/text-editor
|
||||||
|
[npm]: https://www.npmjs.com/package/@prozilla-os/text-editor
|
||||||
|
[ko-fi]: https://ko-fi.com/prozilla
|
||||||
|
|
@ -1,226 +0,0 @@
|
||||||
import { ReactNode, Ref, useEffect, useRef, useState } from "react";
|
|
||||||
import styles from "./TextEditor.module.css";
|
|
||||||
import { HeaderMenu } from "../_utils/header-menu/HeaderMenu";
|
|
||||||
import Markdown from "markdown-to-jsx";
|
|
||||||
import { CODE_FORMATS, DEFAULT_ZOOM, EXTENSION_TO_LANGUAGE, ZOOM_FACTOR } from "../../../config/apps/textEditor.config";
|
|
||||||
import { AppsManager } from "../../../features/apps/appsManager";
|
|
||||||
import { TITLE_SEPARATOR } from "../../../config/windows.config";
|
|
||||||
import { MarkdownLink } from "./overrides/MarkdownLink";
|
|
||||||
import { MarkdownImage } from "./overrides/MarkdownImage";
|
|
||||||
import { useWindowsManager } from "../../../hooks/windows/windowsManagerContext";
|
|
||||||
import SyntaxHighlighter from "react-syntax-highlighter";
|
|
||||||
import { useWindowedModal } from "../../../hooks/modals/windowedModal";
|
|
||||||
import { DEFAULT_FILE_SELECTOR_SIZE } from "../../../config/modals.config";
|
|
||||||
import { FileSelector } from "../../modals/file-selector/FileSelector";
|
|
||||||
import { SELECTOR_MODE } from "../../../config/apps/fileExplorer.config";
|
|
||||||
import { VirtualFile } from "../../../features/virtual-drive/file";
|
|
||||||
import { WindowProps } from "../../windows/WindowView";
|
|
||||||
import { DropdownAction } from "../../actions/actions/DropdownAction";
|
|
||||||
import { ClickAction } from "../../actions/actions/ClickAction";
|
|
||||||
import { ModalsManager } from "../../../features/modals/modalsManager";
|
|
||||||
import { App } from "../../../features/apps/app";
|
|
||||||
import { WindowsManager } from "../../../features/windows/windowsManager";
|
|
||||||
import { MarkdownBlockquote } from "./overrides/MarkdownBlockquote";
|
|
||||||
import { useVirtualRoot } from "../../../hooks/virtual-drive/virtualRootContext";
|
|
||||||
import { APP_NAMES } from "../../../config/apps.config";
|
|
||||||
import { Divider } from "../../actions/actions/Divider";
|
|
||||||
|
|
||||||
const OVERRIDES = {
|
|
||||||
a: MarkdownLink,
|
|
||||||
img: MarkdownImage,
|
|
||||||
blockquote: MarkdownBlockquote,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface MarkdownProps {
|
|
||||||
modalsManager: ModalsManager;
|
|
||||||
setCurrentFile: Function;
|
|
||||||
currentFile: VirtualFile;
|
|
||||||
app: App;
|
|
||||||
windowsManager: WindowsManager;
|
|
||||||
children?: ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TextEditorProps extends WindowProps {
|
|
||||||
file?: VirtualFile;
|
|
||||||
mode?: "view" | "edit";
|
|
||||||
path?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TextEditor({ file, path, setTitle, setIconUrl, close, mode, app, modalsManager }: TextEditorProps) {
|
|
||||||
const ref = useRef<HTMLDivElement | HTMLTextAreaElement>();
|
|
||||||
const windowsManager = useWindowsManager();
|
|
||||||
const virtualRoot = useVirtualRoot();
|
|
||||||
const [currentFile, setCurrentFile] = useState<VirtualFile | null>(file as VirtualFile);
|
|
||||||
const [currentMode, setCurrentMode] = useState<TextEditorProps["mode"]>(mode);
|
|
||||||
const [content, setContent] = useState(file?.content ?? "");
|
|
||||||
const [unsavedChanges, setUnsavedChanges] = useState(file == null);
|
|
||||||
const [zoom, setZoom] = useState(DEFAULT_ZOOM);
|
|
||||||
const [initialised, setInitialised] = useState(false);
|
|
||||||
const { openWindowedModal } = useWindowedModal();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
void (async () => {
|
|
||||||
let newContent = "";
|
|
||||||
|
|
||||||
// Load file
|
|
||||||
if (currentFile) {
|
|
||||||
if (currentFile.content) {
|
|
||||||
newContent = currentFile.content;
|
|
||||||
} else if (currentFile.source) {
|
|
||||||
await fetch(currentFile.source).then((response) =>
|
|
||||||
response.text()
|
|
||||||
).then((response) => {
|
|
||||||
newContent = response;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconUrl = currentFile.getIconUrl();
|
|
||||||
if (iconUrl)
|
|
||||||
setIconUrl?.(iconUrl);
|
|
||||||
|
|
||||||
if (newContent?.trim() === "")
|
|
||||||
setCurrentMode("edit");
|
|
||||||
} else if (app != null) {
|
|
||||||
setIconUrl?.(AppsManager.getAppIconUrl(app.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
setContent(newContent);
|
|
||||||
|
|
||||||
if (ref.current) {
|
|
||||||
(ref.current as HTMLElement).scrollTo(0, 0);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}, [app?.id, currentFile, setIconUrl]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Update title
|
|
||||||
let label = currentFile?.id ?? "Untitled";
|
|
||||||
|
|
||||||
if (unsavedChanges)
|
|
||||||
label += "*";
|
|
||||||
|
|
||||||
if (currentMode === "view")
|
|
||||||
label += " (preview)";
|
|
||||||
|
|
||||||
setTitle?.(app != null ? `${label} ${TITLE_SEPARATOR} ${app.name}` : label);
|
|
||||||
}, [currentFile, setTitle, unsavedChanges, currentMode, app?.name]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!initialised && currentFile == null && path != null) {
|
|
||||||
const newFile = virtualRoot?.navigate(path);
|
|
||||||
|
|
||||||
if (newFile == null || !newFile.isFile())
|
|
||||||
return;
|
|
||||||
|
|
||||||
setCurrentFile(newFile as VirtualFile);
|
|
||||||
setInitialised(true);
|
|
||||||
}
|
|
||||||
}, [path, currentFile]);
|
|
||||||
|
|
||||||
const newText = () => {
|
|
||||||
setCurrentFile(null);
|
|
||||||
setCurrentMode("edit");
|
|
||||||
setUnsavedChanges(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveTextAs = () => {
|
|
||||||
onChange({ target: { value: content } });
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveText = () => {
|
|
||||||
if (currentFile == null)
|
|
||||||
return saveTextAs();
|
|
||||||
|
|
||||||
currentFile.setContent(content);
|
|
||||||
onChange({ target: { value: content } });
|
|
||||||
};
|
|
||||||
|
|
||||||
const onChange = (event: Event | { target: { value: string } }) => {
|
|
||||||
const value = (event.target as HTMLInputElement).value;
|
|
||||||
|
|
||||||
if (currentFile != null) {
|
|
||||||
setUnsavedChanges(currentFile.content !== value);
|
|
||||||
} else {
|
|
||||||
setUnsavedChanges(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return setContent(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const overrides: Record<string, object> = {};
|
|
||||||
for (const [key, value] of Object.entries(OVERRIDES)) {
|
|
||||||
overrides[key] = {
|
|
||||||
component: value,
|
|
||||||
props: {
|
|
||||||
modalsManager,
|
|
||||||
setCurrentFile,
|
|
||||||
currentFile,
|
|
||||||
app,
|
|
||||||
windowsManager
|
|
||||||
} as MarkdownProps
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={styles.TextEditor} style={{ fontSize: zoom }}>
|
|
||||||
<HeaderMenu>
|
|
||||||
<DropdownAction label="File" showOnHover={false}>
|
|
||||||
<ClickAction label="New" onTrigger={() => { newText(); }} shortcut={["Control", "e"]}/>
|
|
||||||
<ClickAction label="Open" onTrigger={() => {
|
|
||||||
openWindowedModal({
|
|
||||||
size: DEFAULT_FILE_SELECTOR_SIZE,
|
|
||||||
Modal: (props: object) => <FileSelector
|
|
||||||
type={SELECTOR_MODE.SINGLE}
|
|
||||||
onFinish={(file) => {
|
|
||||||
setCurrentFile(file as VirtualFile);
|
|
||||||
setUnsavedChanges(false);
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
});
|
|
||||||
}} shortcut={["Control", "o"]}/>
|
|
||||||
<Divider/>
|
|
||||||
<ClickAction label="Save" onTrigger={() => { saveText(); }} shortcut={["Control", "s"]}/>
|
|
||||||
<ClickAction label={`Reveal in ${APP_NAMES.FILE_EXPLORER}`} disabled={currentFile == null} onTrigger={() => {
|
|
||||||
if (windowsManager != null) currentFile?.parent?.open(windowsManager);
|
|
||||||
}}/>
|
|
||||||
<Divider/>
|
|
||||||
<ClickAction label="Quit" onTrigger={() => { close?.(); }} shortcut={["Control", "q"]}/>
|
|
||||||
</DropdownAction>
|
|
||||||
<DropdownAction label="View" showOnHover={false}>
|
|
||||||
<ClickAction label={currentMode === "view" ? "Edit mode" : "Preview mode"} onTrigger={() => {
|
|
||||||
setCurrentMode(currentMode === "view" ? "edit" : "view");
|
|
||||||
}} shortcut={["Control", "u"]}/>
|
|
||||||
<Divider/>
|
|
||||||
<ClickAction label="Zoom in" onTrigger={() => { setZoom(zoom + ZOOM_FACTOR); }} shortcut={["Control", "+"]}/>
|
|
||||||
<ClickAction label="Zoom out" onTrigger={() => { setZoom(zoom - ZOOM_FACTOR); }} shortcut={["Control", "-"]}/>
|
|
||||||
<ClickAction label="Reset Zoom" disabled={zoom == DEFAULT_ZOOM} onTrigger={() => { setZoom(DEFAULT_ZOOM); }} shortcut={["Control", "0"]}/>
|
|
||||||
</DropdownAction>
|
|
||||||
</HeaderMenu>
|
|
||||||
{currentMode === "view"
|
|
||||||
? currentFile?.extension != null && CODE_FORMATS.includes(currentFile?.extension)
|
|
||||||
? <SyntaxHighlighter
|
|
||||||
language={EXTENSION_TO_LANGUAGE[currentFile?.extension] ?? currentFile?.extension}
|
|
||||||
className={styles.Code}
|
|
||||||
useInlineStyles={false}
|
|
||||||
showLineNumbers={true}
|
|
||||||
>{content}</SyntaxHighlighter>
|
|
||||||
: <div ref={ref as Ref<HTMLDivElement>} className={styles.View}>
|
|
||||||
{currentFile?.extension === "md"
|
|
||||||
? <Markdown options={{ overrides } as object}>{content}</Markdown>
|
|
||||||
: <pre><p>{content}</p></pre>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
: <textarea
|
|
||||||
ref={ref as Ref<HTMLTextAreaElement>}
|
|
||||||
className={styles.View}
|
|
||||||
value={content}
|
|
||||||
onChange={onChange}
|
|
||||||
spellCheck={false}
|
|
||||||
autoComplete="off"
|
|
||||||
autoFocus
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
36
packages/apps/text-editor/package.json
Normal file
36
packages/apps/text-editor/package.json
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"name": "@prozilla-os/text-editor",
|
||||||
|
"description": "A text editor application for ProzillaOS.",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"homepage": "https://os.prozilla.dev/text-editor",
|
||||||
|
"author": {
|
||||||
|
"name": "Prozilla",
|
||||||
|
"email": "business@prozilla.dev",
|
||||||
|
"url": "https://prozilla.dev/"
|
||||||
|
},
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"test": "tsc --watch"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/prozilla-os/ProzillaOS.git",
|
||||||
|
"directory": "packages/apps/text-editor"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@prozilla-os/core": "workspace:*",
|
||||||
|
"react": "^18.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.4.5"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/**/*"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://registry.npmjs.org/",
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
208
packages/apps/text-editor/src/components/TextEditor.tsx
Normal file
208
packages/apps/text-editor/src/components/TextEditor.tsx
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
import { ReactNode, Ref, useEffect, useRef, useState } from "react";
|
||||||
|
import styles from "./TextEditor.module.css";
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
import { MarkdownLink } from "./overrides/MarkdownLink";
|
||||||
|
import { MarkdownImage } from "./overrides/MarkdownImage";
|
||||||
|
import SyntaxHighlighter from "react-syntax-highlighter";
|
||||||
|
import { MarkdownBlockquote } from "./overrides/MarkdownBlockquote";
|
||||||
|
import { App, ClickAction, CODE_EXTENSIONS, Divider, DropdownAction, FileSelector, FileSelectorMode, HeaderMenu, ModalsManager, useSystemManager, useVirtualRoot, useWindowedModal, useWindowsManager, VirtualFile, WindowProps, WindowsManager } from "@prozilla-os/core";
|
||||||
|
import { DEFAULT_ZOOM, EXTENSION_TO_LANGUAGE, ZOOM_FACTOR } from "../constants/textEditor.const";
|
||||||
|
|
||||||
|
const OVERRIDES = {
|
||||||
|
a: MarkdownLink,
|
||||||
|
img: MarkdownImage,
|
||||||
|
blockquote: MarkdownBlockquote,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface MarkdownProps {
|
||||||
|
modalsManager: ModalsManager;
|
||||||
|
setCurrentFile: Function;
|
||||||
|
currentFile: VirtualFile;
|
||||||
|
app: App;
|
||||||
|
windowsManager: WindowsManager;
|
||||||
|
children?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TextEditorProps extends WindowProps {
|
||||||
|
file?: VirtualFile;
|
||||||
|
mode?: "view" | "edit";
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TextEditor({ file, path, setTitle, setIconUrl, close, mode, app, modalsManager }: TextEditorProps) {
|
||||||
|
const { windowsConfig, modalsConfig } = useSystemManager();
|
||||||
|
const ref = useRef<HTMLDivElement | HTMLTextAreaElement>();
|
||||||
|
const windowsManager = useWindowsManager();
|
||||||
|
const virtualRoot = useVirtualRoot();
|
||||||
|
const [currentFile, setCurrentFile] = useState<VirtualFile | null>(file as VirtualFile);
|
||||||
|
const [currentMode, setCurrentMode] = useState<TextEditorProps["mode"]>(mode);
|
||||||
|
const [content, setContent] = useState(file?.content ?? "");
|
||||||
|
const [unsavedChanges, setUnsavedChanges] = useState(file == null);
|
||||||
|
const [zoom, setZoom] = useState(DEFAULT_ZOOM);
|
||||||
|
const [initialised, setInitialised] = useState(false);
|
||||||
|
const { openWindowedModal } = useWindowedModal();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void (async () => {
|
||||||
|
let newContent = "";
|
||||||
|
|
||||||
|
// Load file
|
||||||
|
if (currentFile) {
|
||||||
|
if (currentFile.content) {
|
||||||
|
newContent = currentFile.content;
|
||||||
|
} else if (currentFile.source) {
|
||||||
|
await fetch(currentFile.source).then((response) =>
|
||||||
|
response.text()
|
||||||
|
).then((response) => {
|
||||||
|
newContent = response;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconUrl = currentFile.getIconUrl();
|
||||||
|
if (iconUrl)
|
||||||
|
setIconUrl?.(iconUrl);
|
||||||
|
|
||||||
|
if (newContent?.trim() === "")
|
||||||
|
setCurrentMode("edit");
|
||||||
|
} else if (app != null && app.iconUrl != null) {
|
||||||
|
setIconUrl?.(app.iconUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
setContent(newContent);
|
||||||
|
|
||||||
|
if (ref.current) {
|
||||||
|
(ref.current as HTMLElement).scrollTo(0, 0);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, [app?.id, currentFile, setIconUrl]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Update title
|
||||||
|
let label = currentFile?.id ?? "Untitled";
|
||||||
|
|
||||||
|
if (unsavedChanges)
|
||||||
|
label += "*";
|
||||||
|
|
||||||
|
if (currentMode === "view")
|
||||||
|
label += " (preview)";
|
||||||
|
|
||||||
|
setTitle?.(app != null ? `${label} ${windowsConfig.titleSeparator} ${app.name}` : label);
|
||||||
|
}, [currentFile, setTitle, unsavedChanges, currentMode, app?.name]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!initialised && currentFile == null && path != null) {
|
||||||
|
const newFile = virtualRoot?.navigate(path);
|
||||||
|
|
||||||
|
if (newFile == null || !newFile.isFile())
|
||||||
|
return;
|
||||||
|
|
||||||
|
setCurrentFile(newFile as VirtualFile);
|
||||||
|
setInitialised(true);
|
||||||
|
}
|
||||||
|
}, [path, currentFile]);
|
||||||
|
|
||||||
|
const newText = () => {
|
||||||
|
setCurrentFile(null);
|
||||||
|
setCurrentMode("edit");
|
||||||
|
setUnsavedChanges(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveTextAs = () => {
|
||||||
|
onChange({ target: { value: content } });
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveText = () => {
|
||||||
|
if (currentFile == null)
|
||||||
|
return saveTextAs();
|
||||||
|
|
||||||
|
currentFile.setContent(content);
|
||||||
|
onChange({ target: { value: content } });
|
||||||
|
};
|
||||||
|
|
||||||
|
const onChange = (event: Event | { target: { value: string } }) => {
|
||||||
|
const value = (event.target as HTMLInputElement).value;
|
||||||
|
|
||||||
|
if (currentFile != null) {
|
||||||
|
setUnsavedChanges(currentFile.content !== value);
|
||||||
|
} else {
|
||||||
|
setUnsavedChanges(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setContent(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const overrides: Record<string, object> = {};
|
||||||
|
for (const [key, value] of Object.entries(OVERRIDES)) {
|
||||||
|
overrides[key] = {
|
||||||
|
component: value,
|
||||||
|
props: {
|
||||||
|
modalsManager,
|
||||||
|
setCurrentFile,
|
||||||
|
currentFile,
|
||||||
|
app,
|
||||||
|
windowsManager
|
||||||
|
} as MarkdownProps
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className={styles.TextEditor} style={{ fontSize: zoom }}>
|
||||||
|
<HeaderMenu>
|
||||||
|
<DropdownAction label="File" showOnHover={false}>
|
||||||
|
<ClickAction label="New" onTrigger={() => { newText(); }} shortcut={["Control", "e"]}/>
|
||||||
|
<ClickAction label="Open" onTrigger={() => {
|
||||||
|
openWindowedModal({
|
||||||
|
size: modalsConfig.defaultFileSelectorSize,
|
||||||
|
Modal: (props: object) => <FileSelector
|
||||||
|
type={FileSelectorMode.Single}
|
||||||
|
onFinish={(file) => {
|
||||||
|
setCurrentFile(file as VirtualFile);
|
||||||
|
setUnsavedChanges(false);
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
});
|
||||||
|
}} shortcut={["Control", "o"]}/>
|
||||||
|
<Divider/>
|
||||||
|
<ClickAction label="Save" onTrigger={() => { saveText(); }} shortcut={["Control", "s"]}/>
|
||||||
|
{/* <ClickAction label={`Reveal in ${APP_NAMES.FILE_EXPLORER}`} disabled={currentFile == null} onTrigger={() => {
|
||||||
|
if (windowsManager != null) currentFile?.parent?.open(windowsManager);
|
||||||
|
}}/> */}
|
||||||
|
<Divider/>
|
||||||
|
<ClickAction label="Quit" onTrigger={() => { close?.(); }} shortcut={["Control", "q"]}/>
|
||||||
|
</DropdownAction>
|
||||||
|
<DropdownAction label="View" showOnHover={false}>
|
||||||
|
<ClickAction label={currentMode === "view" ? "Edit mode" : "Preview mode"} onTrigger={() => {
|
||||||
|
setCurrentMode(currentMode === "view" ? "edit" : "view");
|
||||||
|
}} shortcut={["Control", "u"]}/>
|
||||||
|
<Divider/>
|
||||||
|
<ClickAction label="Zoom in" onTrigger={() => { setZoom(zoom + ZOOM_FACTOR); }} shortcut={["Control", "+"]}/>
|
||||||
|
<ClickAction label="Zoom out" onTrigger={() => { setZoom(zoom - ZOOM_FACTOR); }} shortcut={["Control", "-"]}/>
|
||||||
|
<ClickAction label="Reset Zoom" disabled={zoom == DEFAULT_ZOOM} onTrigger={() => { setZoom(DEFAULT_ZOOM); }} shortcut={["Control", "0"]}/>
|
||||||
|
</DropdownAction>
|
||||||
|
</HeaderMenu>
|
||||||
|
{currentMode === "view"
|
||||||
|
? currentFile?.extension != null && CODE_EXTENSIONS.includes(currentFile?.extension)
|
||||||
|
? <SyntaxHighlighter
|
||||||
|
language={EXTENSION_TO_LANGUAGE[currentFile?.extension] ?? currentFile?.extension}
|
||||||
|
className={styles.Code}
|
||||||
|
useInlineStyles={false}
|
||||||
|
showLineNumbers={true}
|
||||||
|
>{content}</SyntaxHighlighter>
|
||||||
|
: <div ref={ref as Ref<HTMLDivElement>} className={styles.View}>
|
||||||
|
{currentFile?.extension === "md"
|
||||||
|
? <Markdown options={{ overrides } as object}>{content}</Markdown>
|
||||||
|
: <pre><p>{content}</p></pre>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
: <textarea
|
||||||
|
ref={ref as Ref<HTMLTextAreaElement>}
|
||||||
|
className={styles.View}
|
||||||
|
value={content}
|
||||||
|
onChange={onChange}
|
||||||
|
spellCheck={false}
|
||||||
|
autoComplete="off"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { MarkdownProps } from "../TextEditor";
|
import { MarkdownProps } from "../TextEditor";
|
||||||
import { sanitizeProps } from "../../../../features/apps/text-editor/_utils/sanitizeProps";
|
|
||||||
import { Attributes, Children, cloneElement, DetailedHTMLProps, isValidElement, ReactNode } from "react";
|
import { Attributes, Children, cloneElement, DetailedHTMLProps, isValidElement, ReactNode } from "react";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faExclamationCircle, faExclamationTriangle, faInfoCircle, faLightbulb } from "@fortawesome/free-solid-svg-icons";
|
import { faExclamationCircle, faExclamationTriangle, faInfoCircle, faLightbulb } from "@fortawesome/free-solid-svg-icons";
|
||||||
import styles from "../TextEditor.module.css";
|
import styles from "../TextEditor.module.css";
|
||||||
|
import { sanitizeProps } from "../../core/_utils/sanitizeProps";
|
||||||
|
|
||||||
type Props = Partial<unknown> & Attributes & { children: ReactNode, className?: string };
|
type Props = Partial<unknown> & Attributes & { children: ReactNode, className?: string };
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { MarkdownProps } from "../TextEditor";
|
import { MarkdownProps } from "../TextEditor";
|
||||||
import { sanitizeProps } from "../../../../features/apps/text-editor/_utils/sanitizeProps";
|
|
||||||
import styles from "../TextEditor.module.css";
|
import styles from "../TextEditor.module.css";
|
||||||
|
import { sanitizeProps } from "../../core/_utils/sanitizeProps";
|
||||||
|
|
||||||
interface MarkdownImageProps extends MarkdownProps {
|
interface MarkdownImageProps extends MarkdownProps {
|
||||||
src: string;
|
src: string;
|
||||||
|
|
@ -1,20 +1,9 @@
|
||||||
import { MouseEventHandler, ReactNode, useMemo } from "react";
|
import { MouseEventHandler, ReactNode, useMemo } from "react";
|
||||||
import { faClipboard, faExternalLink } from "@fortawesome/free-solid-svg-icons";
|
import { faClipboard, faExternalLink } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { useContextMenu } from "../../../../hooks/modals/contextMenu";
|
|
||||||
import { Actions } from "../../../actions/Actions";
|
|
||||||
import { ClickAction } from "../../../actions/actions/ClickAction";
|
|
||||||
import { useWindowedModal } from "../../../../hooks/modals/windowedModal";
|
|
||||||
import { AppsManager } from "../../../../features/apps/appsManager";
|
|
||||||
import { DialogBox } from "../../../modals/dialog-box/DialogBox";
|
|
||||||
import { DIALOG_CONTENT_TYPES } from "../../../../config/modals.config";
|
|
||||||
import { Vector2 } from "../../../../features/math/vector2";
|
|
||||||
import { APPS } from "../../../../config/apps.config";
|
|
||||||
import { MarkdownProps } from "../TextEditor";
|
import { MarkdownProps } from "../TextEditor";
|
||||||
import { sanitizeProps } from "../../../../features/apps/text-editor/_utils/sanitizeProps";
|
|
||||||
import { copyToClipboard, removeUrlProtocol } from "../../../../features/_utils/browser.utils";
|
|
||||||
import { TextDisplay } from "../../../actions/actions/TextDisplay";
|
|
||||||
import styles from "../TextEditor.module.css";
|
import styles from "../TextEditor.module.css";
|
||||||
import { ModalProps } from "../../../modals/ModalView";
|
import { Actions, ClickAction, copyToClipboard, DIALOG_CONTENT_TYPES, DialogBox, ModalProps, removeUrlProtocol, TextDisplay, useContextMenu, useWindowedModal, Vector2 } from "@prozilla-os/core";
|
||||||
|
import { sanitizeProps } from "../../core/_utils/sanitizeProps";
|
||||||
|
|
||||||
interface MarkdownLinkProps extends MarkdownProps {
|
interface MarkdownLinkProps extends MarkdownProps {
|
||||||
href: string;
|
href: string;
|
||||||
|
|
@ -33,11 +22,11 @@ export function MarkdownLink({ href, children, windowsManager, currentFile, setC
|
||||||
if (target.isFile()) {
|
if (target.isFile()) {
|
||||||
setCurrentFile(target);
|
setCurrentFile(target);
|
||||||
} else {
|
} else {
|
||||||
windowsManager.open(APPS.FILE_EXPLORER, { path: target.path });
|
windowsManager.open("file-explorer", { path: target.path });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
openWindowedModal({
|
openWindowedModal({
|
||||||
iconUrl: AppsManager.getAppIconUrl(app.id),
|
iconUrl: app?.iconUrl as string | undefined,
|
||||||
title: "Failed to open link",
|
title: "Failed to open link",
|
||||||
size: new Vector2(450, 150),
|
size: new Vector2(450, 150),
|
||||||
Modal: (props: ModalProps) =>
|
Modal: (props: ModalProps) =>
|
||||||
|
|
@ -1,16 +1,5 @@
|
||||||
export const DEFAULT_ZOOM = 16;
|
export const DEFAULT_ZOOM = 16;
|
||||||
export const ZOOM_FACTOR = 4;
|
export const ZOOM_FACTOR = 4;
|
||||||
export const CODE_FORMATS = [
|
|
||||||
"js",
|
|
||||||
"jsx",
|
|
||||||
"ts",
|
|
||||||
"tsx",
|
|
||||||
"json",
|
|
||||||
"css",
|
|
||||||
"html",
|
|
||||||
"xml",
|
|
||||||
"yml"
|
|
||||||
];
|
|
||||||
|
|
||||||
export const EXTENSION_TO_LANGUAGE: Record<string, string> = {
|
export const EXTENSION_TO_LANGUAGE: Record<string, string> = {
|
||||||
"js": "javascript",
|
"js": "javascript",
|
||||||
7
packages/apps/text-editor/src/index.ts
Normal file
7
packages/apps/text-editor/src/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { App } from "@prozilla-os/core";
|
||||||
|
import { TextEditor } from "./components/TextEditor";
|
||||||
|
|
||||||
|
const textEditor = new App("Text Editor", "text-editor", TextEditor)
|
||||||
|
.setIconUrl("https://os.prozilla.dev/assets/apps/icons/text-editor.svg");
|
||||||
|
|
||||||
|
export { textEditor };
|
||||||
5
packages/apps/text-editor/tsconfig.json
Normal file
5
packages/apps/text-editor/tsconfig.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": "../../../tsconfig.json",
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
# @prozilla-os/core
|
# @prozilla-os/core
|
||||||
|
|
||||||
|
## 1.0.11
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Added terminal and text editor app + adjusted links in app packages
|
||||||
|
- Updated dependencies
|
||||||
|
- @prozilla-os/file-explorer@1.0.8
|
||||||
|
|
||||||
## 1.0.10
|
## 1.0.10
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "@prozilla-os/core",
|
"name": "@prozilla-os/core",
|
||||||
"description": "A React component library written in TypeScript for building web-based operating systems, made by Prozilla.",
|
"description": "A React component library written in TypeScript for building web-based operating systems, made by Prozilla.",
|
||||||
"version": "1.0.10",
|
"version": "1.0.11",
|
||||||
|
"homepage": "https://os.prozilla.dev/",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Prozilla",
|
"name": "Prozilla",
|
||||||
"email": "business@prozilla.dev",
|
"email": "business@prozilla.dev",
|
||||||
|
|
@ -14,7 +15,7 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/Prozilla/ProzillaOS.git",
|
"url": "git+https://github.com/prozilla-os/ProzillaOS.git",
|
||||||
"directory": "packages/core"
|
"directory": "packages/core"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ export { FileSelector } from "./file-selector/FileSelector";
|
||||||
export { Share } from "./share/Share";
|
export { Share } from "./share/Share";
|
||||||
export { ModalsView } from "./ModalsView";
|
export { ModalsView } from "./ModalsView";
|
||||||
|
|
||||||
export type { ModalProps } from "./ModalView";
|
export type { ModalProps } from "./ModalView";
|
||||||
|
export { FileSelectorMode } from "@prozilla-os/file-explorer";
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
export { DIALOG_CONTENT_TYPES } from "./modals.const";
|
export { DIALOG_CONTENT_TYPES } from "./modals.const";
|
||||||
export { CODE_EXTENSIONS } from "./virtualDrive.const";
|
export { CODE_EXTENSIONS } from "./virtualDrive.const";
|
||||||
export { ANSI } from "./utils.const";
|
export { ANSI } from "./utils.const";
|
||||||
|
export { THEMES } from "./themes.const";
|
||||||
|
|
@ -8,5 +8,6 @@ export { StorageManager } from "./storage/storageManager";
|
||||||
export { TrackingManager } from "./tracking/trackingManager";
|
export { TrackingManager } from "./tracking/trackingManager";
|
||||||
export { WindowsManager } from "./windows/windowsManager";
|
export { WindowsManager } from "./windows/windowsManager";
|
||||||
export { ZIndexManager } from "./z-index/zIndexManager";
|
export { ZIndexManager } from "./z-index/zIndexManager";
|
||||||
|
export { SystemManager } from "./system/systemManager";
|
||||||
|
|
||||||
export { Vector2 } from "./math/vector2";
|
export { Vector2 } from "./math/vector2";
|
||||||
|
|
@ -1,5 +1,16 @@
|
||||||
# prozilla-os
|
# prozilla-os
|
||||||
|
|
||||||
|
## 1.0.11
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Added terminal and text editor app + adjusted links in app packages
|
||||||
|
- Updated dependencies
|
||||||
|
- @prozilla-os/file-explorer@1.0.8
|
||||||
|
- @prozilla-os/core@1.0.11
|
||||||
|
- @prozilla-os/terminal@1.0.1
|
||||||
|
- @prozilla-os/text-editor@1.0.1
|
||||||
|
|
||||||
## 1.0.10
|
## 1.0.10
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "prozilla-os",
|
"name": "prozilla-os",
|
||||||
"description": "a React component library written in TypeScript for building web-based operating systems, made by Prozilla.",
|
"description": "a React component library written in TypeScript for building web-based operating systems, made by Prozilla.",
|
||||||
"version": "1.0.10",
|
"version": "1.0.11",
|
||||||
"homepage": "https://os.prozilla.dev/",
|
"homepage": "https://os.prozilla.dev/",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Prozilla",
|
"name": "Prozilla",
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/Prozilla/ProzillaOS.git",
|
"url": "git+https://github.com/prozilla-os/ProzillaOS.git",
|
||||||
"directory": "packages/prozilla-os"
|
"directory": "packages/prozilla-os"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -29,7 +29,9 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prozilla-os/core": "workspace:*",
|
"@prozilla-os/core": "workspace:*",
|
||||||
"@prozilla-os/file-explorer": "workspace:*"
|
"@prozilla-os/file-explorer": "workspace:*",
|
||||||
|
"@prozilla-os/terminal": "workspace:*",
|
||||||
|
"@prozilla-os/text-editor": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
export * from "@prozilla-os/core";
|
export * from "@prozilla-os/core";
|
||||||
export * from "@prozilla-os/file-explorer";
|
export * from "@prozilla-os/file-explorer";
|
||||||
|
export * from "@prozilla-os/terminal";
|
||||||
|
export * from "@prozilla-os/text-editor";
|
||||||
|
|
@ -131,6 +131,38 @@ importers:
|
||||||
specifier: ^5.4.5
|
specifier: ^5.4.5
|
||||||
version: 5.4.5
|
version: 5.4.5
|
||||||
|
|
||||||
|
packages/apps/terminal:
|
||||||
|
dependencies:
|
||||||
|
'@prozilla-os/core':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../core
|
||||||
|
anser:
|
||||||
|
specifier: ^2.1.1
|
||||||
|
version: 2.1.1
|
||||||
|
escape-carriage:
|
||||||
|
specifier: ^1.3.1
|
||||||
|
version: 1.3.1
|
||||||
|
react:
|
||||||
|
specifier: ^18.3.1
|
||||||
|
version: 18.3.1
|
||||||
|
devDependencies:
|
||||||
|
typescript:
|
||||||
|
specifier: ^5.4.5
|
||||||
|
version: 5.4.5
|
||||||
|
|
||||||
|
packages/apps/text-editor:
|
||||||
|
dependencies:
|
||||||
|
'@prozilla-os/core':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../../core
|
||||||
|
react:
|
||||||
|
specifier: ^18.3.1
|
||||||
|
version: 18.3.1
|
||||||
|
devDependencies:
|
||||||
|
typescript:
|
||||||
|
specifier: ^5.4.5
|
||||||
|
version: 5.4.5
|
||||||
|
|
||||||
packages/core:
|
packages/core:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fortawesome/fontawesome-svg-core':
|
'@fortawesome/fontawesome-svg-core':
|
||||||
|
|
@ -179,6 +211,12 @@ importers:
|
||||||
'@prozilla-os/file-explorer':
|
'@prozilla-os/file-explorer':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../apps/file-explorer
|
version: link:../apps/file-explorer
|
||||||
|
'@prozilla-os/terminal':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../apps/terminal
|
||||||
|
'@prozilla-os/text-editor':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../apps/text-editor
|
||||||
devDependencies:
|
devDependencies:
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.4.5
|
specifier: ^5.4.5
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
import { AppsConfig, fileExplorer } from "prozilla-os";
|
import { AppsConfig, fileExplorer, terminal, textEditor } from "prozilla-os";
|
||||||
|
|
||||||
export const appsConfig = new AppsConfig({
|
export const appsConfig = new AppsConfig({
|
||||||
apps: [
|
apps: [
|
||||||
fileExplorer.setName("Files"),
|
fileExplorer.setName("Files")
|
||||||
|
.setDescription("Browse and manage your virtual files on ProzillaOS.")
|
||||||
|
.setIconUrl("/assets/apps/icons/file-explorer.svg"),
|
||||||
|
terminal.setName("Commands")
|
||||||
|
.setDescription("A command line tool inspired by the Unix shell that runs entirely in your browser using ProzillaOS. Allows you to interact and manipulate the virtual drive and run silly commands.")
|
||||||
|
.setIconUrl("/assets/apps/icons/terminal.svg"),
|
||||||
|
textEditor.setName("Notes")
|
||||||
|
.setDescription("Text editor for reading and writing text documents in a virtual file system using ProzillaOS.")
|
||||||
|
.setIconUrl("/assets/apps/icons/text-editor.svg"),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import { ANSI } from "prozilla-os";
|
|
||||||
|
|
||||||
export const NAME = "ProzillaOS";
|
export const NAME = "ProzillaOS";
|
||||||
export const TAG_LINE = "Web-based Operating System";
|
export const TAG_LINE = "Web-based Operating System";
|
||||||
|
|
||||||
|
|
@ -16,24 +14,6 @@ export const ASCII_LOGO = `
|
||||||
.=----#%+-+%#-*+-%#+---:.
|
.=----#%+-+%#-*+-%#+---:.
|
||||||
==----*###*--*###*----.
|
==----*###*--*###*----.
|
||||||
==+-------------------:.
|
==+-------------------:.
|
||||||
...::---------------:.
|
|
||||||
.::---------::..
|
|
||||||
....::... `;
|
|
||||||
|
|
||||||
export const ANSI_LOGO_COLOR = ANSI.fg.cyan;
|
|
||||||
export const ANSI_ASCII_LOGO = `
|
|
||||||
:.
|
|
||||||
-==.
|
|
||||||
.=====:
|
|
||||||
---::..:=======-.
|
|
||||||
:===+=----------::..
|
|
||||||
=+=---------------:..
|
|
||||||
--------------------:.
|
|
||||||
.:-+=----${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}--${ANSI.fg.white}*####=${ANSI_LOGO_COLOR}---.
|
|
||||||
:==+----${ANSI.fg.white}#%+${ANSI_LOGO_COLOR}-${ANSI.fg.white}+%#${ANSI_LOGO_COLOR}-${ANSI.fg.white}##%*+${ANSI_LOGO_COLOR}----:.
|
|
||||||
.=----${ANSI.fg.white}#%+${ANSI_LOGO_COLOR}-${ANSI.fg.white}+%#${ANSI_LOGO_COLOR}-${ANSI.fg.white}*+${ANSI_LOGO_COLOR}-${ANSI.fg.white}%#+${ANSI_LOGO_COLOR}---:.
|
|
||||||
==----${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}--${ANSI.fg.white}*###*${ANSI_LOGO_COLOR}----.
|
|
||||||
==+-------------------:.
|
|
||||||
...::---------------:.
|
...::---------------:.
|
||||||
.::---------::..
|
.::---------::..
|
||||||
....::... `;
|
....::... `;
|
||||||
Loading…
Reference in a new issue