Added neofetch command
This commit is contained in:
parent
24eb482da7
commit
922d01e583
6 changed files with 156 additions and 3 deletions
|
|
@ -53,6 +53,7 @@
|
|||
"error",
|
||||
"double"
|
||||
],
|
||||
"default-case": "off",
|
||||
"jsdoc/no-undefined-types": "warn",
|
||||
"jsdoc/require-param": "warn",
|
||||
"jsdoc/check-tag-names": "warn",
|
||||
|
|
|
|||
|
|
@ -11,9 +11,13 @@ const HOSTNAME = "prozilla-os";
|
|||
* @param {string} props.text
|
||||
*/
|
||||
function OutputLine({ text }) {
|
||||
return (
|
||||
<p className={styles.Output}>{text}</p>
|
||||
);
|
||||
const lines = text?.split("\n");
|
||||
|
||||
return (<>
|
||||
{lines.map((line, index) =>
|
||||
<p key={index} className={styles.Output}>{line}</p>
|
||||
)}
|
||||
</>);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
line-height: 1.25rem;
|
||||
font-size: 1rem;
|
||||
text-align: start;
|
||||
white-space: break-spaces;
|
||||
}
|
||||
|
||||
.Input {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}),
|
||||
];
|
||||
}
|
||||
94
src/features/utils/date.js
Normal file
94
src/features/utils/date.js
Normal file
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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(
|
|||
</React.StrictMode>
|
||||
);
|
||||
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue