From 922d01e583d2bb6de8d1c37f5aea660de2f22d21 Mon Sep 17 00:00:00 2001 From: Prozilla Date: Sat, 12 Aug 2023 11:16:35 +0200 Subject: [PATCH] Added neofetch command --- package.json | 1 + .../applications/terminal/Terminal.jsx | 10 +- .../applications/terminal/Terminal.module.css | 1 + .../applications/terminal/commands.js | 48 ++++++++++ src/features/utils/date.js | 94 +++++++++++++++++++ src/index.js | 5 + 6 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 src/features/utils/date.js diff --git a/package.json b/package.json index c1249a3..0cb9d9a 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "error", "double" ], + "default-case": "off", "jsdoc/no-undefined-types": "warn", "jsdoc/require-param": "warn", "jsdoc/check-tag-names": "warn", diff --git a/src/components/applications/terminal/Terminal.jsx b/src/components/applications/terminal/Terminal.jsx index 0eb715e..96171fa 100644 --- a/src/components/applications/terminal/Terminal.jsx +++ b/src/components/applications/terminal/Terminal.jsx @@ -11,9 +11,13 @@ const HOSTNAME = "prozilla-os"; * @param {string} props.text */ function OutputLine({ text }) { - return ( -

{text}

- ); + const lines = text?.split("\n"); + + return (<> + {lines.map((line, index) => +

{line}

+ )} + ); } /** diff --git a/src/components/applications/terminal/Terminal.module.css b/src/components/applications/terminal/Terminal.module.css index acc0867..923fb1d 100644 --- a/src/components/applications/terminal/Terminal.module.css +++ b/src/components/applications/terminal/Terminal.module.css @@ -27,6 +27,7 @@ line-height: 1.25rem; font-size: 1rem; text-align: start; + white-space: break-spaces; } .Input { diff --git a/src/features/applications/terminal/commands.js b/src/features/applications/terminal/commands.js index 7d67b2a..c71a97d 100644 --- a/src/features/applications/terminal/commands.js +++ b/src/features/applications/terminal/commands.js @@ -1,3 +1,25 @@ +import { START_DATE } from "../../../index.js"; +import { formatRelativeTime } from "../../utils/date.js"; +import ApplicationsManager from "../applications.js"; + +export const ASCII_LOGO = ` + :. + -==. + .=====: + ---::..:=======-. + :===+=----------::.. + =+=---------------:.. + --------------=-----:. + .:-+=---=*#*#*==*#*##=---. + :==+---=#%+=+%#+##**+=---:. + .=---=#%+=+%*+*++*%+---:. + ==---=*###*==*###*=---. + ==+-------------------:. + ...::---------------:. + .::---------::.. + ....::... +`; + export class Command { /** * @param {string} name @@ -125,5 +147,31 @@ export class Command { new Command("hostname", (args, { hostname }) => { return hostname; }), + new Command("neofetch", (args, { username, hostname }) => { + const leftColumn = ASCII_LOGO.split("\n"); + const rightColumn = [ + `${username}@${hostname}`, + "-".repeat(username.length + hostname.length + 1), + "OS: ProzillaOS", + `UPTIME: ${formatRelativeTime(START_DATE, 2, false)}`, + `RESOLUTION: ${window.innerWidth}x${window.innerHeight}`, + "THEME: default", + "ICONS: Font Awesome", + `TERMINAL: ${ApplicationsManager.getApplication("terminal")?.name ?? "Unknown"}`, + ]; + + const combined = []; + for (let i = 1; i < leftColumn.length - 1; i++) { + let line = `${leftColumn[i]} `; + + if (i <= rightColumn.length) { + line += rightColumn[i - 1]; + } + + combined.push(line); + } + + return combined.join("\n"); + }), ]; } \ No newline at end of file diff --git a/src/features/utils/date.js b/src/features/utils/date.js new file mode 100644 index 0000000..35d8f48 --- /dev/null +++ b/src/features/utils/date.js @@ -0,0 +1,94 @@ +const TIME_INDICATORS = { + "s": 1000, + "m": 1000 * 60, + "h": 1000 * 60 * 60, + "d": 1000 * 60 * 60 * 24, + "w": 1000 * 60 * 60 * 24 * 7, + "n": 1000 * 60 * 60 * 24 * 31, + "y": 1000 * 60 * 60 * 24 * 365, + "c": 1000 * 60 * 60 * 24 * 365 * 100 +}; + +/** + * Format a time + * @param {number} time - Time in milliseconds + * @param {number} maxLength - The maximum amount of units, e.g.: 3 => years, months, days + * @param {boolean} allowAffixes + * @returns {string} + */ +export const formatTime = (time, maxLength = 3, allowAffixes) => { + const result = []; + + const formatResult = (result, inPast) => { + if (!allowAffixes) + return result.join(", "); + + let prefix = ""; + let suffix = ""; + + if (inPast) { + suffix = "ago"; + } else { + prefix = "in"; + } + + return [prefix, result.join(", "), suffix].join(" ").trim(); + }; + + let inPast = false; + + if (time < 0) { + time = -time; + inPast = true; + } + + if (Math.abs(time) < TIME_INDICATORS.s) { + return formatResult(["less than a second"], inPast); + } + + const units = []; + const unitLabels = { + "s": "seconds", + "m": "minutes", + "h": "hours", + "d": "days", + "n": "months", + "y": "years", + }; + + for (const [key, value] of Object.entries(TIME_INDICATORS).reverse()) { + if (key === "w" || key === "c") + continue; + + const amount = Math.floor(time / value); + time -= amount * value; + + if (amount > 0) + units.push({ amount, label: unitLabels[key] }); + } + + for (let i = 0; i < maxLength; i++) { + const unit = units[i]; + + if (unit) + result.push(`${unit.amount} ${unit.label}`); + } + + if (result.length === 0) { + return formatResult(["less than a second"], inPast); + } else { + return formatResult(result, inPast); + } +}; + +/** + * Format a time relative to now + * @param {Date} date - The date + * @param {number} maxLength - The maximum amount of units, e.g.: 3 => years, months, days + * @param {boolean} allowAffixes + * @returns {string} + */ +export const formatRelativeTime = (date, maxLength = 3, allowAffixes) => { + const difference = date - new Date(); + return formatTime(difference, maxLength, allowAffixes); +}; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 0e3cc9d..80f46eb 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,9 @@ import ReactDOM from "react-dom/client"; import "./styles/global.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; +import { ASCII_LOGO } from "./features/applications/terminal/commands.js"; + +export const START_DATE = new Date(); const root = ReactDOM.createRoot(document.getElementById("root")); root.render( @@ -11,6 +14,8 @@ root.render( ); +console.log(ASCII_LOGO); + // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals