From 261eaf84c59ab454e606bbd6201255e473ffbabc Mon Sep 17 00:00:00 2001
From: sirpiglr <49359077-sirpiglr@users.noreply.replit.com>
Date: Wed, 17 Dec 2025 01:29:30 +0000
Subject: [PATCH] Add loading skeletons and new terminal commands for better
user experience
Introduce a reusable Skeleton component for loading states, enhance the TerminalApp with commands like 'dice', 'cowsay', and 'joke', and update existing UI elements to use the new skeleton components.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 279f1558-c0e3-40e4-8217-be7e9f4c6eca
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: d9c26768-4739-47d1-ac7b-bb6d188535ad
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/b984cb14-1d19-4944-922b-bc79e821ed35/279f1558-c0e3-40e4-8217-be7e9f4c6eca/aiPwIfX
Replit-Helium-Checkpoint-Created: true
---
client/src/pages/os.tsx | 203 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 196 insertions(+), 7 deletions(-)
diff --git a/client/src/pages/os.tsx b/client/src/pages/os.tsx
index cc1ccf8..8ebae67 100644
--- a/client/src/pages/os.tsx
+++ b/client/src/pages/os.tsx
@@ -850,6 +850,35 @@ interface TaskbarProps {
onDesktopChange: (d: number) => void;
}
+function Skeleton({ className = "", animate = true }: { className?: string; animate?: boolean }) {
+ return (
+
+ );
+}
+
+function LoadingSkeleton() {
+ return (
+
+ );
+}
+
function ParticleField() {
const particles = Array.from({ length: 30 }, (_, i) => ({
id: i,
@@ -1223,6 +1252,14 @@ function TerminalApp() {
"║ matrix - Enter the matrix ║",
"║ clear - Clear terminal ║",
"║ tour - AeThex guided tour ║",
+ "╠═══════════════════════════════════════════╣",
+ "║ dice - Roll two dice ║",
+ "║ cowsay - Make a cow say something ║",
+ "║ joke - Tell a programmer joke ║",
+ "║ weather - Metaverse weather report ║",
+ "║ uptime - System uptime ║",
+ "║ banner - Show AeThex banner ║",
+ "║ coffee - Brew some coffee ║",
"╚═══════════════════════════════════════════╝",
""
], setHistory);
@@ -1489,6 +1526,113 @@ function TerminalApp() {
], setHistory);
break;
+ case 'dice':
+ const d1 = Math.floor(Math.random() * 6) + 1;
+ const d2 = Math.floor(Math.random() * 6) + 1;
+ const diceArt: Record = {
+ 1: ["┌───────┐", "│ │", "│ ● │", "│ │", "└───────┘"],
+ 2: ["┌───────┐", "│ ● │", "│ │", "│ ● │", "└───────┘"],
+ 3: ["┌───────┐", "│ ● │", "│ ● │", "│ ● │", "└───────┘"],
+ 4: ["┌───────┐", "│ ● ● │", "│ │", "│ ● ● │", "└───────┘"],
+ 5: ["┌───────┐", "│ ● ● │", "│ ● │", "│ ● ● │", "└───────┘"],
+ 6: ["┌───────┐", "│ ● ● │", "│ ● ● │", "│ ● ● │", "└───────┘"],
+ };
+ await typeEffect(["", "🎲 Rolling dice..."], setHistory);
+ await delay(500);
+ for (let i = 0; i < 5; i++) {
+ await typeEffect([` ${diceArt[d1][i]} ${diceArt[d2][i]}`], setHistory);
+ }
+ await typeEffect([``, `Result: ${d1} + ${d2} = ${d1 + d2}`, ""], setHistory);
+ break;
+
+ case 'cowsay':
+ const cowMsg = args.slice(1).join(' ') || 'Hello, Architect!';
+ const border = '─'.repeat(cowMsg.length + 2);
+ await typeEffect([
+ "",
+ `┌${border}┐`,
+ `│ ${cowMsg} │`,
+ `└${border}┘`,
+ " \\ ^__^",
+ " \\ (oo)\\_______",
+ " (__)\\ )\\/\\",
+ " ||----w |",
+ " || ||",
+ ""
+ ], setHistory);
+ break;
+
+ case 'joke':
+ const jokes = [
+ { q: "Why do programmers prefer dark mode?", a: "Because light attracts bugs." },
+ { q: "Why did the developer go broke?", a: "Because he used up all his cache." },
+ { q: "What's a programmer's favorite hangout place?", a: "Foo Bar." },
+ { q: "Why do Java developers wear glasses?", a: "Because they can't C#." },
+ ];
+ const joke = jokes[Math.floor(Math.random() * jokes.length)];
+ await typeEffect(["", `Q: ${joke.q}`], setHistory);
+ await delay(1500);
+ await typeEffect([`A: ${joke.a}`, ""], setHistory);
+ break;
+
+ case 'weather':
+ const conditions = ['☀️ Sunny', '🌤️ Partly Cloudy', '☁️ Cloudy', '🌧️ Rainy', '⚡ Thunderstorms', '🌈 Rainbow'];
+ const temp = Math.floor(Math.random() * 30) + 15;
+ await typeEffect([
+ "",
+ "┌────────────────────────────┐",
+ "│ METAVERSE WEATHER │",
+ "├────────────────────────────┤",
+ `│ ${conditions[Math.floor(Math.random() * conditions.length)].padEnd(24)}│`,
+ `│ Temperature: ${temp}°C │`,
+ "│ Humidity: Always optimal │",
+ "│ Wind: Digital breeze │",
+ "└────────────────────────────┘",
+ ""
+ ], setHistory);
+ break;
+
+ case 'uptime':
+ const days = Math.floor(Math.random() * 365) + 100;
+ const hours = Math.floor(Math.random() * 24);
+ await typeEffect([
+ "",
+ `System uptime: ${days} days, ${hours} hours`,
+ "The Metaverse never sleeps.",
+ ""
+ ], setHistory);
+ break;
+
+ case 'banner':
+ await typeEffect([
+ "",
+ "█████╗ ███████╗████████╗██╗ ██╗███████╗██╗ ██╗",
+ "██╔══██╗██╔════╝╚══██╔══╝██║ ██║██╔════╝╚██╗██╔╝",
+ "███████║█████╗ ██║ ███████║█████╗ ╚███╔╝ ",
+ "██╔══██║██╔══╝ ██║ ██╔══██║██╔══╝ ██╔██╗ ",
+ "██║ ██║███████╗ ██║ ██║ ██║███████╗██╔╝ ██╗",
+ "╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝",
+ "",
+ " Operating System for the Metaverse",
+ ""
+ ], setHistory);
+ break;
+
+ case 'coffee':
+ await typeEffect([
+ "",
+ " ( (",
+ " ) )",
+ " ........",
+ " | |]",
+ " \\ /",
+ " `----'",
+ "",
+ "☕ Coffee brewed! Stay caffeinated, Architect.",
+ ""
+ ], setHistory);
+ break;
+
default:
setHistory(prev => [...prev, `Command not found: ${cmd}`, "Type 'help' for available commands.", ""]);
}
@@ -1514,7 +1658,7 @@ function TerminalApp() {
}
} else if (e.key === 'Tab') {
e.preventDefault();
- const cmds = ['help', 'status', 'architects', 'projects', 'scan', 'analyze', 'decrypt', 'hack', 'fortune', 'whoami', 'neofetch', 'matrix', 'clear', 'tour'];
+ const cmds = ['help', 'status', 'architects', 'projects', 'scan', 'analyze', 'decrypt', 'hack', 'fortune', 'whoami', 'neofetch', 'matrix', 'clear', 'tour', 'dice', 'cowsay', 'joke', 'weather', 'uptime', 'banner', 'coffee', 'sudo', 'secret'];
const match = cmds.find(c => c.startsWith(input.toLowerCase()));
if (match) setInput(match);
}
@@ -2065,8 +2209,17 @@ function MetricsDashboardApp() {
if (isLoading) {
return (
-
-
+
);
}
@@ -2341,8 +2494,28 @@ function ProfilesApp() {
if (isLoading) {
return (
-
-
+
+
+
+
+
+
+ {[1,2,3,4].map(i => (
+
+ ))}
+
);
}
@@ -2393,8 +2566,24 @@ function LeaderboardApp() {
if (isLoading) {
return (
-
-
+
+
+
+
+
+
+ {[1,2,3,4,5].map(i => (
+
+ ))}
+
);
}