From fcfcf28eabfb1febc386bd9e62738307a32b1c7a Mon Sep 17 00:00:00 2001 From: Marc Robin Richter Date: Mon, 16 Mar 2026 11:56:40 +0100 Subject: [PATCH] good work --- src/components/BootSequence.ts | 428 +++++++++++++++++++++++++------ src/components/CommandPrompt.tsx | 46 ++-- 2 files changed, 374 insertions(+), 100 deletions(-) diff --git a/src/components/BootSequence.ts b/src/components/BootSequence.ts index 2ed9cfa..658f558 100644 --- a/src/components/BootSequence.ts +++ b/src/components/BootSequence.ts @@ -1,4 +1,4 @@ -export type LineColor = 'green' | 'amber' | 'red' | 'dim'; +export type LineColor = "green" | "amber" | "red" | "dim"; export interface BootLine { text: string; @@ -9,96 +9,358 @@ export interface BootLine { export const BOOT_SEQUENCE: BootLine[] = [ // Phase 1 - BIOS POST - { text: 'AWARD BIOS v6.9.420 (c) 2024 Stift15 Systems Ltd.', color: 'dim', delay: 300 }, - { text: 'Performing Power-On Self Test...', color: 'dim', delay: 200 }, - { text: '', color: 'dim', delay: 100 }, - { text: 'CPU: AMD Ryzen 9 9950X "GamerFuel Edition" @ 5.7 GHz .......... OK', color: 'green', delay: 150 }, - { text: 'RAM: 65536 MB DDR5-6000 ....................................... OK', color: 'green', delay: 120 }, - { text: 'GPU: NVIDIA RTX 5090 "Mortgage Edition" ........................ OK', color: 'green', delay: 120 }, - { text: 'RGB Subsystem .................................................. SYNCED (mood: aggressive)', color: 'green', delay: 100 }, - { text: 'Gamer Chair Lumbar Support ..................................... RECLINED', color: 'green', delay: 100 }, - { text: '', color: 'dim', delay: 80 }, - { text: 'Detecting boot devices...', color: 'dim', delay: 400 }, - { text: 'Boot device: /dev/sda1 (labeled "DO_NOT_DELETE_MOM")', color: 'dim', delay: 300 }, - { text: '', color: 'dim', delay: 200 }, + { + text: "AWARD BIOS v6.9.420 (c) 2024 Stift15 Systems Ltd.", + color: "dim", + delay: 300, + }, + { text: "Performing Power-On Self Test...", color: "dim", delay: 200 }, + { text: "", color: "dim", delay: 100 }, + { + text: 'CPU: AMD Ryzen 9 9950X "GamerFuel Edition" @ 5.7 GHz .......... OK', + color: "green", + delay: 150, + }, + { + text: "RAM: 65536 MB DDR5-6000 ....................................... OK", + color: "green", + delay: 120, + }, + { + text: 'GPU: NVIDIA RTX 5090 "Mortgage Edition" ........................ OK', + color: "green", + delay: 120, + }, + { + text: "RGB Subsystem .................................................. SYNCED (mood: aggressive)", + color: "green", + delay: 100, + }, + { + text: "Gamer Chair Lumbar Support ..................................... RECLINED", + color: "green", + delay: 100, + }, + { text: "", color: "dim", delay: 80 }, + { text: "Detecting boot devices...", color: "dim", delay: 400 }, + { + text: 'Boot device: /dev/sda1 (labeled "DO_NOT_DELETE_MOM")', + color: "dim", + delay: 300, + }, + { text: "", color: "dim", delay: 200 }, // Phase 2 - Kernel Boot - { text: 'Loading GRUB 2.12 ...', color: 'green', delay: 300 }, - { text: 'kernel: Linux 6.9.0-gamer-generic loading...', color: 'green', delay: 200 }, - { text: '[ 0.000000] Command line: root=/dev/sda1 ro quiet splash=off fps_unlock=true', color: 'dim', delay: 80 }, - { text: '[ 0.004200] Initializing gaming subsystems...', color: 'dim', delay: 80 }, - { text: '[ 0.013370] RGB controller mapped to /dev/rgb0', color: 'dim', delay: 60 }, - { text: '[ 0.024601] Registering thermal zone: "CPU Package" (target: yes)', color: 'dim', delay: 60 }, - { text: '[ 0.031337] Loading module: gamer_posture.ko', color: 'dim', delay: 60 }, - { text: '[ 0.042069] Mounting /dev/fridge (read-only, sadness mode)', color: 'dim', delay: 60 }, - { text: '', color: 'dim', delay: 200 }, + { text: "Loading GRUB 2.12 ...", color: "green", delay: 300 }, + { + text: "kernel: Linux 6.9.0-gamer-generic loading...", + color: "green", + delay: 200, + }, + { + text: "[ 0.000000] Command line: root=/dev/sda1 ro quiet splash=off fps_unlock=true", + color: "dim", + delay: 80, + }, + { + text: "[ 0.004200] Initializing gaming subsystems...", + color: "dim", + delay: 80, + }, + { + text: "[ 0.013370] RGB controller mapped to /dev/rgb0", + color: "dim", + delay: 60, + }, + { + text: '[ 0.024601] Registering thermal zone: "CPU Package" (target: yes)', + color: "dim", + delay: 60, + }, + { + text: "[ 0.031337] Loading module: gamer_posture.ko", + color: "dim", + delay: 60, + }, + { + text: "[ 0.042069] Mounting /dev/fridge (read-only, sadness mode)", + color: "dim", + delay: 60, + }, + { text: "", color: "dim", delay: 200 }, // Phase 3 - Services Starting - { text: '[ OK ] Started Gamer Posture Reminder Service', color: 'green', delay: 150 }, - { text: '[ OK ] Started Mountain Dew Level Monitor', color: 'green', delay: 120 }, - { text: '[ OK ] Started Discord Rich Presence Daemon', color: 'green', delay: 120 }, - { text: '[ OK ] Started Mechanical Keyboard Click Amplifier', color: 'green', delay: 100 }, - { text: '[ OK ] Started Rage Quit Prevention System (v0.1-beta)', color: 'green', delay: 100 }, - { text: '[WARN] Hot Pocket Proximity Sensor returned NaN', color: 'amber', delay: 300 }, - { text: '[ OK ] Started Frank\'s "Temporary" Minecraft Server (uptime: 847 days)', color: 'green', delay: 150 }, - { text: '[ OK ] Started nginx web server on port 80', color: 'green', delay: 100 }, - { text: '[ OK ] Started Node.js application server on port 3000', color: 'green', delay: 100 }, - { text: '[WARN] server.js has mass of 2.1 GB (node_modules singularity detected)', color: 'amber', delay: 400 }, - { text: '[WARN] Gravitational pull from node_modules is affecting nearby files', color: 'amber', delay: 200 }, - { text: '', color: 'dim', delay: 300 }, + { + text: "[ OK ] Started Gamer Posture Reminder Service", + color: "green", + delay: 150, + }, + { + text: "[ OK ] Started Mountain Dew Level Monitor", + color: "green", + delay: 120, + }, + { + text: "[ OK ] Started Teamspeak Rich Presence Daemon", + color: "green", + delay: 120, + }, + { + text: "[ OK ] Started Mechanical Keyboard Click Amplifier", + color: "green", + delay: 100, + }, + { + text: "[ OK ] Started Rage Quit Prevention System (v0.1-beta)", + color: "green", + delay: 100, + }, + { + text: "[WARN] Hot Pocket Proximity Sensor returned NaN", + color: "amber", + delay: 300, + }, + { + text: '[ OK ] Started Frank\'s "Temporary" Minecraft Server (uptime: 847 days)', + color: "green", + delay: 150, + }, + { + text: "[ OK ] Started nginx web server on port 80", + color: "green", + delay: 100, + }, + { + text: "[ OK ] Started Node.js application server on port 3000", + color: "green", + delay: 100, + }, + { + text: "[WARN] server.js has mass of 2.1 GB (node_modules singularity detected)", + color: "amber", + delay: 400, + }, + { + text: "[WARN] Gravitational pull from node_modules is affecting nearby files", + color: "amber", + delay: 200, + }, + { text: "", color: "dim", delay: 300 }, // Phase 4 - The Crash - { text: '[FAIL] HTTP Health Check: GET /api/status returned... nothing', color: 'red', delay: 600 }, - { text: '[FAIL] The backend is not responding.', color: 'red', delay: 400 }, - { text: '[FAIL] The backend has never responded. To anything. Ever.', color: 'red', delay: 500 }, - { text: '', color: 'dim', delay: 200 }, - { text: '[WARN] Attempting emergency restart...', color: 'amber', delay: 800 }, - { text: '[ 4.040404] Process \'server.js\' invoked OOM killer', color: 'red', delay: 300 }, - { text: '[ 4.040405] OOM killer selected process \'stift15-game-server\' (adj 1000)', color: 'red', delay: 150 }, - { text: '[ 4.040406] Out of memory: Killed process 1337 (stift15-game-server)', color: 'red', delay: 150 }, - { text: '[ 4.040407] Reason: Frank downloaded the entire Steam Workshop into /tmp', color: 'red', delay: 300 }, - { text: '', color: 'dim', delay: 200 }, - { text: '[FAIL] Emergency restart failed. Exit code: 418 (I\'m a teapot)', color: 'red', delay: 600 }, - { text: '', color: 'dim', delay: 800 }, + { + text: "[FAIL] HTTP Health Check: GET /api/status returned... nothing", + color: "red", + delay: 600, + }, + { text: "[FAIL] The backend is not responding.", color: "red", delay: 400 }, + { + text: "[FAIL] The backend has never responded. To anything. Ever.", + color: "red", + delay: 500, + }, + { text: "", color: "dim", delay: 200 }, + { + text: "[WARN] Attempting emergency restart...", + color: "amber", + delay: 800, + }, + { + text: "[ 4.040404] Process 'server.js' invoked OOM killer", + color: "red", + delay: 300, + }, + { + text: "[ 4.040405] OOM killer selected process 'stift15-game-server' (adj 1000)", + color: "red", + delay: 150, + }, + { + text: "[ 4.040406] Out of memory: Killed process 1337 (stift15-game-server)", + color: "red", + delay: 150, + }, + { + text: "[ 4.040407] Reason: Frank downloaded the entire Steam Workshop into /tmp", + color: "red", + delay: 300, + }, + { text: "", color: "dim", delay: 200 }, + { + text: "[FAIL] Emergency restart failed. Exit code: 418 (I'm a teapot)", + color: "red", + delay: 600, + }, + { text: "", color: "dim", delay: 800 }, // Phase 5 - The 503 Error (typewriter lines) - { text: '============================================================', color: 'red', delay: 400, typewriter: true }, - { text: ' ERROR 503 - SERVICE UNAVAILABLE', color: 'red', delay: 100, typewriter: true }, - { text: '============================================================', color: 'red', delay: 100, typewriter: true }, - { text: '', color: 'dim', delay: 200 }, - { text: ' The server hosting the Stift15 gaming group has encountered', color: 'green', delay: 60, typewriter: true }, - { text: ' a fatal error and is currently taking a rage-quit break.', color: 'green', delay: 60, typewriter: true }, - { text: '', color: 'dim', delay: 300 }, - { text: ' DIAGNOSTIC SUMMARY:', color: 'amber', delay: 200, typewriter: true }, - { text: ' - Last stable connection: "lol"', color: 'green', delay: 80, typewriter: true }, - { text: ' - Uptime before crash: 4h 20m 69s', color: 'green', delay: 80, typewriter: true }, - { text: ' - Packets lost: all of them', color: 'green', delay: 80, typewriter: true }, - { text: ' - Root cause: someone git pushed node_modules to prod', color: 'green', delay: 80, typewriter: true }, - { text: ' - Secondary cause: Frank', color: 'green', delay: 80, typewriter: true }, - { text: ' - Tertiary cause: also Frank', color: 'green', delay: 80, typewriter: true }, - { text: ' - Frank\'s response: "works on my machine"', color: 'green', delay: 80, typewriter: true }, - { text: '', color: 'dim', delay: 300 }, - { text: ' RECOMMENDED ACTIONS:', color: 'amber', delay: 200, typewriter: true }, - { text: ' 1. Touch grass (estimated ETA: never)', color: 'green', delay: 80, typewriter: true }, - { text: ' 2. Check if Frank pushed to main again', color: 'green', delay: 80, typewriter: true }, - { text: ' 3. Blame the lag', color: 'green', delay: 80, typewriter: true }, - { text: ' 4. Alt+F4 your expectations', color: 'green', delay: 80, typewriter: true }, - { text: ' 5. Have you tried turning Frank off and on again?', color: 'green', delay: 80, typewriter: true }, - { text: '', color: 'dim', delay: 300 }, - { text: ' If this error persists, please scream into the void or', color: 'green', delay: 60, typewriter: true }, - { text: ' message the server admin, who is also screaming into the void.', color: 'green', delay: 60, typewriter: true }, - { text: '', color: 'dim', delay: 400 }, - { text: '============================================================', color: 'red', delay: 100, typewriter: true }, - { text: ' SERVER ADMIN NOTE:', color: 'amber', delay: 200, typewriter: true }, - { text: ' No, I will not fix this at 3 AM. I have work tomorrow.', color: 'green', delay: 60, typewriter: true }, - { text: ' The server can stay dead. It builds character.', color: 'green', delay: 60, typewriter: true }, - { text: ' Also Frank still owes me for last month\'s hosting.', color: 'green', delay: 60, typewriter: true }, - { text: '============================================================', color: 'red', delay: 100, typewriter: true }, - { text: '', color: 'dim', delay: 1500 }, + { + text: "============================================================", + color: "red", + delay: 400, + typewriter: true, + }, + { + text: " ERROR 503 - SERVICE UNAVAILABLE", + color: "red", + delay: 100, + typewriter: true, + }, + { + text: "============================================================", + color: "red", + delay: 100, + typewriter: true, + }, + { text: "", color: "dim", delay: 200 }, + { + text: " The server hosting Stift15.de has encountered", + color: "green", + delay: 60, + typewriter: true, + }, + { + text: " a fatal error and is currently taking a rage-quit break.", + color: "green", + delay: 60, + typewriter: true, + }, + { text: "", color: "dim", delay: 300 }, + { + text: " DIAGNOSTIC SUMMARY:", + color: "amber", + delay: 200, + typewriter: true, + }, + { + text: ' - Last stable connection: "lol"', + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " - Uptime before crash: 4h 20m 69s", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " - Packets lost: all of them", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " - Root cause: someone git pushed node_modules to prod", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " - Secondary cause: Frank", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " - Tertiary cause: also Frank", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: ' - Frank\'s response: "works on my machine"', + color: "green", + delay: 80, + typewriter: true, + }, + { text: "", color: "dim", delay: 300 }, + { + text: " RECOMMENDED ACTIONS:", + color: "amber", + delay: 200, + typewriter: true, + }, + { + text: " 1. Touch grass (estimated ETA: never)", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " 2. Check if Frank pushed to main again", + color: "green", + delay: 80, + typewriter: true, + }, + { text: " 3. Blame the lag", color: "green", delay: 80, typewriter: true }, + { + text: " 4. Alt+F4 your expectations", + color: "green", + delay: 80, + typewriter: true, + }, + { + text: " 5. Have you tried turning Frank off and on again?", + color: "green", + delay: 80, + typewriter: true, + }, + { text: "", color: "dim", delay: 300 }, + { + text: " If this error persists, please scream into the void or", + color: "green", + delay: 60, + typewriter: true, + }, + { + text: " message the server admin, who is also screaming into the void.", + color: "green", + delay: 60, + typewriter: true, + }, + { text: "", color: "dim", delay: 400 }, + { + text: "============================================================", + color: "red", + delay: 100, + typewriter: true, + }, + { + text: " SERVER ADMIN NOTE:", + color: "amber", + delay: 200, + typewriter: true, + }, + { + text: " No, I will not fix this at 3 AM. I have work tomorrow.", + color: "green", + delay: 60, + typewriter: true, + }, + { + text: " The server can stay dead. It builds character.", + color: "green", + delay: 60, + typewriter: true, + }, + { + text: " Also Frank still owes me for last month's hosting.", + color: "green", + delay: 60, + typewriter: true, + }, + { + text: "============================================================", + color: "red", + delay: 100, + typewriter: true, + }, + { text: "", color: "dim", delay: 1500 }, // Phase 6 - Reconnect - { text: '> Reconnecting in 3 seconds...', color: 'dim', delay: 0 }, - { text: '> ...', color: 'dim', delay: 1000 }, - { text: '> ...', color: 'dim', delay: 1000 }, - { text: '> CONNECTION ESTABLISHED', color: 'green', delay: 1000 }, + { text: "> Reconnecting in 3 seconds...", color: "dim", delay: 0 }, + { text: "> ...", color: "dim", delay: 1000 }, + { text: "> ...", color: "dim", delay: 1000 }, + { text: "> CONNECTION ESTABLISHED", color: "green", delay: 1000 }, ]; diff --git a/src/components/CommandPrompt.tsx b/src/components/CommandPrompt.tsx index bc85a0a..8fc47c7 100644 --- a/src/components/CommandPrompt.tsx +++ b/src/components/CommandPrompt.tsx @@ -20,7 +20,7 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) { const [input, setInput] = useState(''); const [history, setHistory] = useState([]); const [historyIndex, setHistoryIndex] = useState(-1); - const containerRef = useRef(null); + const inputRef = useRef(null); const bottomRef = useRef(null); const scrollToBottom = useCallback(() => { @@ -29,9 +29,13 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) { useEffect(scrollToBottom, [outputLines.length, scrollToBottom]); - // Focus container on mount + // Keep input focused useEffect(() => { - containerRef.current?.focus(); + inputRef.current?.focus(); + }, []); + + const focusInput = useCallback(() => { + inputRef.current?.focus(); }, []); const executeCommand = useCallback( @@ -82,12 +86,11 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) { ); const handleKeyDown = useCallback( - (e: React.KeyboardEvent) => { + (e: React.KeyboardEvent) => { if (e.key === 'Enter') { executeCommand(input); setInput(''); - } else if (e.key === 'Backspace') { - setInput((prev) => prev.slice(0, -1)); + setHistoryIndex(-1); } else if (e.key === 'ArrowUp') { e.preventDefault(); if (history.length === 0) return; @@ -105,8 +108,6 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) { setHistoryIndex(newIndex); setInput(history[newIndex]); } - } else if (e.key.length === 1 && !e.ctrlKey && !e.metaKey) { - setInput((prev) => prev + e.key); } }, [input, executeCommand, history, historyIndex] @@ -121,11 +122,8 @@ export function CommandPrompt({ onReboot, onBrick }: CommandPromptProps) { return (
containerRef.current?.focus()} + className="absolute inset-0 z-0 overflow-y-auto p-4 font-mono text-sm outline-none cursor-text" + onClick={focusInput} > {outputLines.map((line, i) => (
- {PROMPT} - {input} +
+ {PROMPT} + {input} + {/* Hidden native input for reliable focus and mobile keyboard support */} + setInput(e.target.value)} + onKeyDown={handleKeyDown} + onBlur={focusInput} + className="absolute opacity-0 w-0 h-0" + autoCapitalize="off" + autoCorrect="off" + autoComplete="off" + spellCheck={false} + />