From ed80c17dfa49efa09d4398515f1ac671547f3541 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Tue, 19 Dec 2023 11:42:51 +0100 Subject: [PATCH] Updated terminal app --- .../applications/browser/Browser.jsx | 1 - .../applications/terminal/Terminal.jsx | 2 +- .../applications/terminal/commands.js | 10 +- .../applications/terminal/commands/blow.js | 6 -- .../applications/terminal/commands/cat.js | 2 +- .../applications/terminal/commands/cd.js | 2 +- .../applications/terminal/commands/dir.js | 20 ++-- .../applications/terminal/commands/echo.js | 10 +- .../applications/terminal/commands/exit.js | 12 ++- .../applications/terminal/commands/fortune.js | 10 +- .../applications/terminal/commands/help.js | 26 ++++++ .../terminal/commands/hostname.js | 10 +- .../applications/terminal/commands/ls.js | 5 +- .../applications/terminal/commands/make.js | 1 + .../applications/terminal/commands/man.js | 4 +- .../applications/terminal/commands/mkdir.js | 21 +++-- .../terminal/commands/neofetch.js | 92 ++++++++++--------- .../applications/terminal/commands/nice.js | 7 -- .../applications/terminal/commands/pwd.js | 18 ++-- .../applications/terminal/commands/reboot.js | 12 ++- .../applications/terminal/commands/rm.js | 23 +++-- .../applications/terminal/commands/rmdir.js | 23 +++-- .../applications/terminal/commands/uptime.js | 12 +++ .../applications/terminal/commands/whatis.js | 3 + .../applications/terminal/commands/whoami.js | 10 +- .../applications/terminal/commands/world.js | 6 -- 26 files changed, 209 insertions(+), 139 deletions(-) delete mode 100644 src/features/applications/terminal/commands/blow.js create mode 100644 src/features/applications/terminal/commands/help.js delete mode 100644 src/features/applications/terminal/commands/nice.js create mode 100644 src/features/applications/terminal/commands/uptime.js delete mode 100644 src/features/applications/terminal/commands/world.js diff --git a/src/components/applications/browser/Browser.jsx b/src/components/applications/browser/Browser.jsx index c133e54..22c514d 100644 --- a/src/components/applications/browser/Browser.jsx +++ b/src/components/applications/browser/Browser.jsx @@ -6,7 +6,6 @@ import { faCaretLeft, faCaretRight, faHome, faRotateRight } from "@fortawesome/f import { HOME_URL, SEARCH_URL } from "../../../constants/applications/browser.js"; import { isValidUrl } from "../../../features/utils/browser.js"; import { useHistory } from "../../../hooks/utils/history.js"; -import { TITLE_SEPARATOR } from "../../../constants/windows.js"; /** @type {import("../../windows/WindowView.jsx").windowProps} */ export function Browser({ startUrl, focus }) { diff --git a/src/components/applications/terminal/Terminal.jsx b/src/components/applications/terminal/Terminal.jsx index bfe4d1e..9329067 100644 --- a/src/components/applications/terminal/Terminal.jsx +++ b/src/components/applications/terminal/Terminal.jsx @@ -134,7 +134,7 @@ export function Terminal({ setTitle, close: exit }) { }); if (output) - promptOutput(output); + promptOutput(`${output}\n`); }; const updateHistoryIndex = (delta) => { diff --git a/src/features/applications/terminal/commands.js b/src/features/applications/terminal/commands.js index af80c53..c6fe52c 100644 --- a/src/features/applications/terminal/commands.js +++ b/src/features/applications/terminal/commands.js @@ -1,5 +1,4 @@ import Command from "./command.js"; -import { blow } from "./commands/blow.js"; import { cat } from "./commands/cat.js"; import { cd } from "./commands/cd.js"; import { clear } from "./commands/clear.js"; @@ -9,21 +8,21 @@ import { dir } from "./commands/dir.js"; import { echo } from "./commands/echo.js"; import { exit } from "./commands/exit.js"; import { fortune } from "./commands/fortune.js"; +import { help } from "./commands/help.js"; import { hostname } from "./commands/hostname.js"; import { ls } from "./commands/ls.js"; import { make } from "./commands/make.js"; import { man } from "./commands/man.js"; import { mkdir } from "./commands/mkdir.js"; import { neofetch } from "./commands/neofetch.js"; -import { nice } from "./commands/nice.js"; import { pwd } from "./commands/pwd.js"; import { reboot } from "./commands/reboot.js"; import { rm } from "./commands/rm.js"; import { rmdir } from "./commands/rmdir.js"; import { touch } from "./commands/touch.js"; +import { uptime } from "./commands/uptime.js"; import { whatis } from "./commands/whatis.js"; import { whoami } from "./commands/whoami.js"; -import { world } from "./commands/world.js"; export default class CommandsManager { /** @@ -67,9 +66,6 @@ export default class CommandsManager { neofetch, fortune, cowsay, - world, - nice, - blow, make, cat, man, @@ -78,5 +74,7 @@ export default class CommandsManager { whoami, whatis, exit, + help, + uptime, ]; } \ No newline at end of file diff --git a/src/features/applications/terminal/commands/blow.js b/src/features/applications/terminal/commands/blow.js deleted file mode 100644 index aaa631d..0000000 --- a/src/features/applications/terminal/commands/blow.js +++ /dev/null @@ -1,6 +0,0 @@ -import Command from "../command.js"; - -export const blow = new Command("%blow") - .setExecute(function() { - return `fg: ${this.name}: No such job`; - }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/cat.js b/src/features/applications/terminal/commands/cat.js index 4b0f736..699d39c 100644 --- a/src/features/applications/terminal/commands/cat.js +++ b/src/features/applications/terminal/commands/cat.js @@ -3,7 +3,7 @@ import Command from "../command.js"; export const cat = new Command("cat") .setRequireArgs(true) .setManual({ - purpose: "Concetenate files and print on the standard output", + purpose: "Concetenate files and display on the terminal screen", usage: "cat [OPTION]... [FILE]...", description: "Concetenate FILE(s) to standard output." }) diff --git a/src/features/applications/terminal/commands/cd.js b/src/features/applications/terminal/commands/cd.js index 86b2387..f14713d 100644 --- a/src/features/applications/terminal/commands/cd.js +++ b/src/features/applications/terminal/commands/cd.js @@ -3,7 +3,7 @@ import Command from "../command.js"; export const cd = new Command("cd") .setRequireArgs(true) .setManual({ - purpose: "Change directory", + purpose: "Change the current directory", usage: "cd path", description: "Change working directory to given path (the home directory by default)." }) diff --git a/src/features/applications/terminal/commands/dir.js b/src/features/applications/terminal/commands/dir.js index e2db95c..0f86d32 100644 --- a/src/features/applications/terminal/commands/dir.js +++ b/src/features/applications/terminal/commands/dir.js @@ -1,10 +1,14 @@ import Command from "../command.js"; -export const dir = new Command("dir", (args, { currentDirectory }) => { - const folderNames = currentDirectory.subFolders.map((folder) => folder.id); - - if (folderNames.length === 0) - return { blank: true }; - - return folderNames.sort((nameA, nameB) => nameA.localeCompare(nameB)).join(" "); -}); \ No newline at end of file +export const dir = new Command("dir") + .setManual({ + purpose: "List all directories in the current directory" + }) + .setExecute((args, { currentDirectory }) => { + const folderNames = currentDirectory.subFolders.map((folder) => folder.id); + + if (folderNames.length === 0) + return { blank: true }; + + return folderNames.sort((nameA, nameB) => nameA.localeCompare(nameB)).join(" "); + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/echo.js b/src/features/applications/terminal/commands/echo.js index b8b8bce..49ab477 100644 --- a/src/features/applications/terminal/commands/echo.js +++ b/src/features/applications/terminal/commands/echo.js @@ -1,5 +1,9 @@ import Command from "../command.js"; -export const echo = new Command("echo", (args, { rawInputValue }) => { - return rawInputValue; -}); \ No newline at end of file +export const echo = new Command("echo") + .setManual({ + purpose: "Display text on the terminal screen" + }) + .setExecute((args, { rawInputValue }) => { + return rawInputValue; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/exit.js b/src/features/applications/terminal/commands/exit.js index 4317c03..bb95e92 100644 --- a/src/features/applications/terminal/commands/exit.js +++ b/src/features/applications/terminal/commands/exit.js @@ -1,6 +1,10 @@ import Command from "../command.js"; -export const exit = new Command("exit", (args, { exit }) => { - exit(); - return { blank: true }; -}); \ No newline at end of file +export const exit = new Command("exit") + .setManual({ + purpose: "Quit terminal interface" + }) + .setExecute((args, { exit }) => { + exit(); + return { blank: true }; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/fortune.js b/src/features/applications/terminal/commands/fortune.js index 723a482..3aed4ff 100644 --- a/src/features/applications/terminal/commands/fortune.js +++ b/src/features/applications/terminal/commands/fortune.js @@ -94,6 +94,10 @@ const FORTUNES = [ "Your true value depends entirely on what you are compared with.", ]; -export const fortune = new Command("fortune", () => { - return randomFromArray(FORTUNES); -}); \ No newline at end of file +export const fortune = new Command("fortune") + .setManual({ + purpose: "Tell fortune" + }) + .setExecute(() => { + return randomFromArray(FORTUNES); + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/help.js b/src/features/applications/terminal/commands/help.js new file mode 100644 index 0000000..5954737 --- /dev/null +++ b/src/features/applications/terminal/commands/help.js @@ -0,0 +1,26 @@ +import Command from "../command.js"; +import CommandsManager from "../commands.js"; + +export const help = new Command("help") + .setExecute((args) => { + if (args.length === 0) { + return CommandsManager.COMMANDS.map((command) => { + if (command.manual?.purpose) { + return `${command.name} - ${command.manual.purpose}`; + } else { + return command.name; + } + }).sort().join("\n"); + } + + const commandName = args[0].toLowerCase(); + const command = CommandsManager.find(commandName); + + if (!command) + return `${this.name}: ${commandName}: Command not found`; + + if (!command.manual?.purpose) + return `${this.name}: ${commandName}: No manual found`; + + return command.manual.purpose; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/hostname.js b/src/features/applications/terminal/commands/hostname.js index d0d516a..e54fe5e 100644 --- a/src/features/applications/terminal/commands/hostname.js +++ b/src/features/applications/terminal/commands/hostname.js @@ -1,5 +1,9 @@ import Command from "../command.js"; -export const hostname = new Command("hostname", (args, { hostname }) => { - return hostname; -}); \ No newline at end of file +export const hostname = new Command("hostname") + .setManual({ + purpose: "Display the hostname" + }) + .setExecute((args, { hostname }) => { + return hostname; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/ls.js b/src/features/applications/terminal/commands/ls.js index adb65fa..d7d9cf8 100644 --- a/src/features/applications/terminal/commands/ls.js +++ b/src/features/applications/terminal/commands/ls.js @@ -2,10 +2,9 @@ import Command from "../command.js"; export const ls = new Command("ls") .setManual({ - purpose: "list directory contents", + purpose: "List directory contents", usage: "ls [OPTION]... [FILE]...", - description: "List information about the FILEs (the current directory by default).\n" - + "Sort entries alphabetically if none of -cftuvSUX nor --sort is specified." + description: "List information about the FILEs (the current directory by default)." }) .setExecute(function(args, { currentDirectory }) { let directory = currentDirectory; diff --git a/src/features/applications/terminal/commands/make.js b/src/features/applications/terminal/commands/make.js index d9c3afd..ed72339 100644 --- a/src/features/applications/terminal/commands/make.js +++ b/src/features/applications/terminal/commands/make.js @@ -1,6 +1,7 @@ import Command from "../command.js"; export const make = new Command("make") + .setRequireArgs(true) .setExecute(function(args) { if (args[0] === "love") return `${this.name}: *** No rule to make target 'love'. Stop.`; diff --git a/src/features/applications/terminal/commands/man.js b/src/features/applications/terminal/commands/man.js index e0ed37c..2be9059 100644 --- a/src/features/applications/terminal/commands/man.js +++ b/src/features/applications/terminal/commands/man.js @@ -18,14 +18,14 @@ export const man = new Command("man") .setExecute(function(args, { options }) { // Search function if (options.includes("k")) { - const commands = CommandsManager.search(args[0]); + const commands = CommandsManager.search(args[0].toLowerCase()); return commands.map((command) => { if (command.manual?.purpose) { return `${command.name} - ${command.manual.purpose}`; } else { return command.name; } - }).join("\n"); + }).sort().join("\n"); } const commandName = args[0].toLowerCase(); diff --git a/src/features/applications/terminal/commands/mkdir.js b/src/features/applications/terminal/commands/mkdir.js index 4df7881..2b9b1a2 100644 --- a/src/features/applications/terminal/commands/mkdir.js +++ b/src/features/applications/terminal/commands/mkdir.js @@ -1,11 +1,16 @@ import Command from "../command.js"; -export const mkdir = new Command("mkdir", (args, { currentDirectory }) => { - const name = args[0]; - - if (currentDirectory.findSubFolder(name)) +export const mkdir = new Command("mkdir") + .setManual({ + purpose: "Create directory" + }) + .setRequireArgs(true) + .setExecute((args, { currentDirectory }) => { + const name = args[0]; + + if (currentDirectory.findSubFolder(name)) + return { blank: true }; + + currentDirectory.createFolder(name); return { blank: true }; - - currentDirectory.createFolder(name); - return { blank: true }; -}).setRequireArgs(true); \ No newline at end of file + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/neofetch.js b/src/features/applications/terminal/commands/neofetch.js index 208270c..e09c060 100644 --- a/src/features/applications/terminal/commands/neofetch.js +++ b/src/features/applications/terminal/commands/neofetch.js @@ -5,53 +5,57 @@ import { formatRelativeTime } from "../../../utils/date.js"; import AppsManager from "../../applications.js"; import Command from "../command.js"; -export const neofetch = new Command("neofetch", (args, { username, hostname }) => { - const leftColumn = ASCII_LOGO.split("\n"); - const rightColumnWidth = username.length + hostname.length + 1; +export const neofetch = new Command("neofetch") + .setManual({ + purpose: "Fetch system information" + }) + .setExecute((args, { username, hostname }) => { + const leftColumn = ASCII_LOGO.split("\n"); + const rightColumnWidth = username.length + hostname.length + 1; - const userAgent = navigator.userAgent; + const userAgent = navigator.userAgent; - // Check for the browser name using regular expressions - let browserName; - if (userAgent.match(/Firefox\//)) { - browserName = "Mozilla Firefox"; - } else if (userAgent.match(/Edg\//)) { - browserName = "Microsoft Edge"; - } else if (userAgent.match(/Chrome\//)) { - browserName = "Google Chrome"; - } else if (userAgent.match(/Safari\//)) { - browserName = "Apple Safari"; - } else { - browserName = "Unknown"; - } - - const rightColumn = [ - `${username}@${hostname}`, - "-".repeat(rightColumnWidth), - `OS: ${NAME}`, - `UPTIME: ${formatRelativeTime(START_DATE, 2, false)}`, - `RESOLUTION: ${window.innerWidth}x${window.innerHeight}`, - "THEME: default", - "ICONS: Font Awesome", - `TERMINAL: ${AppsManager.getApp(APPS.TERMINAL)?.name ?? "Unknown"}`, - `BROWSER: ${browserName}`, - `PLATFORM: ${navigator.platform}`, - `LANGUAGE: ${navigator.language}`, - ]; - - const combined = []; - for (let i = 1; i < leftColumn.length; i++) { - let line = `${leftColumn[i]} `; - - if (i <= rightColumn.length) { - line += rightColumn[i - 1]; + // Check for the browser name using regular expressions + let browserName; + if (userAgent.match(/Firefox\//)) { + browserName = "Mozilla Firefox"; + } else if (userAgent.match(/Edg\//)) { + browserName = "Microsoft Edge"; + } else if (userAgent.match(/Chrome\//)) { + browserName = "Google Chrome"; + } else if (userAgent.match(/Safari\//)) { + browserName = "Apple Safari"; } else { - // This fixes a weird display bug on Safari mobile - line += " ".repeat(rightColumnWidth); + browserName = "Unknown"; } - combined.push(line); - } + const rightColumn = [ + `${username}@${hostname}`, + "-".repeat(rightColumnWidth), + `OS: ${NAME}`, + `UPTIME: ${formatRelativeTime(START_DATE, 2, false)}`, + `RESOLUTION: ${window.innerWidth}x${window.innerHeight}`, + "THEME: default", + "ICONS: Font Awesome", + `TERMINAL: ${AppsManager.getApp(APPS.TERMINAL)?.name ?? "Unknown"}`, + `BROWSER: ${browserName}`, + `PLATFORM: ${navigator.platform}`, + `LANGUAGE: ${navigator.language}`, + ]; - return combined.join("\n"); -}); \ No newline at end of file + const combined = []; + for (let i = 1; i < leftColumn.length; i++) { + let line = `${leftColumn[i]} `; + + if (i <= rightColumn.length) { + line += rightColumn[i - 1]; + } else { + // This fixes a weird display bug on Safari mobile + line += " ".repeat(rightColumnWidth); + } + + combined.push(line); + } + + return combined.join("\n"); + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/nice.js b/src/features/applications/terminal/commands/nice.js deleted file mode 100644 index 325608d..0000000 --- a/src/features/applications/terminal/commands/nice.js +++ /dev/null @@ -1,7 +0,0 @@ -import Command from "../command.js"; - -export const nice = new Command("nice") - .setExecute(function(args) { - if (args[0] === "man" && args[1] === "woman") - return `${this.name}: No manual entry for woman`; - }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/pwd.js b/src/features/applications/terminal/commands/pwd.js index 094aceb..5f1d55f 100644 --- a/src/features/applications/terminal/commands/pwd.js +++ b/src/features/applications/terminal/commands/pwd.js @@ -1,9 +1,13 @@ import Command from "../command.js"; -export const pwd = new Command("pwd", (args, { currentDirectory }) => { - if (currentDirectory.root) { - return "/"; - } else { - return currentDirectory.absolutePath; - } -}); \ No newline at end of file +export const pwd = new Command("pwd") + .setManual({ + purpose: "Display path of the current directory" + }) + .setExecute((args, { currentDirectory }) => { + if (currentDirectory.root) { + return "/"; + } else { + return currentDirectory.absolutePath; + } + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/reboot.js b/src/features/applications/terminal/commands/reboot.js index 865312e..8f05d7e 100644 --- a/src/features/applications/terminal/commands/reboot.js +++ b/src/features/applications/terminal/commands/reboot.js @@ -1,7 +1,11 @@ import { reloadViewport } from "../../../utils/browser.js"; import Command from "../command.js"; -export const reboot = new Command("reboot", () => { - reloadViewport(); - return { blank: true }; -}); \ No newline at end of file +export const reboot = new Command("reboot") + .setManual({ + purpose: "Reboot the system" + }) + .setExecute(() => { + reloadViewport(); + return { blank: true }; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/rm.js b/src/features/applications/terminal/commands/rm.js index 36b13c7..5ce4edd 100644 --- a/src/features/applications/terminal/commands/rm.js +++ b/src/features/applications/terminal/commands/rm.js @@ -1,12 +1,17 @@ import Command from "../command.js"; -export const rm = new Command("rm", (args, { currentDirectory }) => { - const [name, extension] = args[0].split("."); - const file = currentDirectory.findFile(name, extension); - - if (!file) - return `${this.name}: ${args[0]}: No such file`; +export const rm = new Command("rm") + .setRequireArgs(true) + .setManual({ + purpose: "Remove a file" + }) + .setExecute((args, { currentDirectory }) => { + const [name, extension] = args[0].split("."); + const file = currentDirectory.findFile(name, extension); - file.delete(); - return { blank: true }; -}).setRequireArgs(true); \ No newline at end of file + if (!file) + return `${this.name}: ${args[0]}: No such file`; + + file.delete(); + return { blank: true }; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/rmdir.js b/src/features/applications/terminal/commands/rmdir.js index 00517a3..9528d53 100644 --- a/src/features/applications/terminal/commands/rmdir.js +++ b/src/features/applications/terminal/commands/rmdir.js @@ -1,12 +1,17 @@ import Command from "../command.js"; -export const rmdir = new Command("rmdir", (args, { currentDirectory }) => { - const name = args[0]; - const folder = currentDirectory.findSubFolder(name); - - if (!folder) - return `${this.name}: ${args[0]}: No such directory`; +export const rmdir = new Command("rmdir") + .setRequireArgs(true) + .setManual({ + purpose: "Remove a directory" + }) + .setExecute((args, { currentDirectory }) => { + const name = args[0]; + const folder = currentDirectory.findSubFolder(name); - folder.delete(); - return { blank: true }; -}).setRequireArgs(true); \ No newline at end of file + if (!folder) + return `${this.name}: ${args[0]}: No such directory`; + + folder.delete(); + return { blank: true }; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/uptime.js b/src/features/applications/terminal/commands/uptime.js new file mode 100644 index 0000000..8edcdf5 --- /dev/null +++ b/src/features/applications/terminal/commands/uptime.js @@ -0,0 +1,12 @@ +import { START_DATE } from "../../../../index.js"; +import { formatRelativeTime } from "../../../utils/date.js"; +import Command from "../command.js"; + + +export const uptime = new Command("uptime") + .setManual({ + purpose: "Displays the current uptime of the system" + }) + .setExecute(() => { + return `Uptime: ${formatRelativeTime(START_DATE, 2, false)}`; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/whatis.js b/src/features/applications/terminal/commands/whatis.js index ff36cb9..edfe2d2 100644 --- a/src/features/applications/terminal/commands/whatis.js +++ b/src/features/applications/terminal/commands/whatis.js @@ -3,6 +3,9 @@ import CommandsManager from "../commands.js"; export const whatis = new Command("whatis") .setRequireArgs(true) + .setManual({ + purpose: "Show information about a command" + }) .setExecute(function(args) { const commandName = args[0].toLowerCase(); const command = CommandsManager.find(commandName); diff --git a/src/features/applications/terminal/commands/whoami.js b/src/features/applications/terminal/commands/whoami.js index c8a93c5..9810883 100644 --- a/src/features/applications/terminal/commands/whoami.js +++ b/src/features/applications/terminal/commands/whoami.js @@ -1,5 +1,9 @@ import Command from "../command.js"; -export const whoami = new Command("whoami", (args, { username }) => { - return username; -}); \ No newline at end of file +export const whoami = new Command("whoami") + .setManual({ + purpose: "Display the username" + }) + .setExecute((args, { username }) => { + return username; + }); \ No newline at end of file diff --git a/src/features/applications/terminal/commands/world.js b/src/features/applications/terminal/commands/world.js deleted file mode 100644 index 0adaa9f..0000000 --- a/src/features/applications/terminal/commands/world.js +++ /dev/null @@ -1,6 +0,0 @@ -import Command from "../command.js"; - -export const world = new Command("world") - .setExecute(function() { - return `${this.name}: Not found`; - }); \ No newline at end of file