Skip to content

Commit 4d226ef

Browse files
committed
port leds
1 parent 0c4db53 commit 4d226ef

1 file changed

Lines changed: 84 additions & 1 deletion

File tree

  • src/components/module-faces/network
Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,89 @@
1+
import { useEffect, useState } from 'react';
12

23
export const Port = ({ className = "w-4 h-4" }: { className?: string }) => {
4+
// 3 states: 'off', 'online' (linked), 'active' (transmitting)
5+
// Initialize random state to avoid unison effect
6+
const [status, setStatus] = useState<'off' | 'online' | 'active'>(() => {
7+
const rand = Math.random();
8+
if (rand > 0.95) return 'off'; // 5% chance starts unplugged
9+
if (rand > 0.6) return 'active';
10+
return 'online';
11+
});
12+
13+
const [isAmberOn, setIsAmberOn] = useState(false);
14+
15+
// State simulation loop
16+
useEffect(() => {
17+
if (status === 'off') {
18+
// Small chance to plug in
19+
if (Math.random() > 0.995) {
20+
// checking very rarely? No, need a timeout.
21+
}
22+
// For now, if off, stay off (simulation of unplugged).
23+
// Or maybe randomly plug in? Let's keep it simple: if off, stay off for now.
24+
// Actually, user might want everything lit up.
25+
// Let's make it so 'off' can transition to 'online' rarely.
26+
const timeout = setTimeout(() => {
27+
if (Math.random() > 0.9) setStatus('online'); // 10% chance to wake up every 5s logic below?
28+
// actually we shouldn't act if we return inside useEffect.
29+
}, 5000);
30+
return () => clearTimeout(timeout);
31+
}
32+
33+
// Toggle between online and active (traffic bursts)
34+
const duration = status === 'online'
35+
? Math.random() * 5000 + 1000 // Stay idle 1-6s
36+
: Math.random() * 3000 + 500; // Burst 0.5-3.5s
37+
38+
const timeoutId = setTimeout(() => {
39+
if (status === 'online') {
40+
setStatus('active');
41+
} else {
42+
setStatus('online');
43+
}
44+
}, duration);
45+
46+
return () => clearTimeout(timeoutId);
47+
}, [status]);
48+
49+
// Blinking logic for Amber LED (Active mode)
50+
useEffect(() => {
51+
if (status !== 'active') {
52+
setIsAmberOn(false);
53+
return;
54+
}
55+
56+
let timeoutId: ReturnType<typeof setTimeout>;
57+
const toggleBlink = () => {
58+
const shouldBeOn = Math.random() > 0.3; // More activity than idle
59+
setIsAmberOn(shouldBeOn);
60+
// Very fast blinking for network activity
61+
timeoutId = setTimeout(toggleBlink, Math.random() * 100 + 20);
62+
};
63+
64+
toggleBlink();
65+
return () => clearTimeout(timeoutId);
66+
}, [status]);
67+
368
return (
4-
<div className={`bg-black/80 rounded-[1px] border border-gray-600 shadow-inner ${className}`}></div>
69+
<div className="flex flex-col items-center gap-[0px]">
70+
71+
{/* Port */}
72+
<div className={`bg-black/80 rounded-[1px] border border-gray-600 shadow-inner ${className}`}>
73+
{/* LEDs */}
74+
<div className="flex justify-between w-full px-[1px]">
75+
{/* Green LED: On when online or active */}
76+
<div className={`w-0.75 h-0.75 rounded-[0.5px] transition-colors duration-200 ${status !== 'off'
77+
? 'bg-green-500/50 shadow-[0_0_2px_rgba(34,197,94,0.6)]'
78+
: 'bg-green-900/60'
79+
}`}></div>
80+
81+
{/* Amber LED: Blinking when active, Off otherwise */}
82+
<div className={`w-0.75 h-0.75 rounded-[0.5px] transition-colors duration-50 ${isAmberOn
83+
? 'bg-amber-500/40 shadow-[0_0_2px_rgba(245,158,11,0.6)]'
84+
: 'bg-amber-900/60'
85+
}`}></div>
86+
</div></div>
87+
</div>
588
);
689
};

0 commit comments

Comments
 (0)