React Hook
useSkySpySocket hook for React applications.
useSkySpySocket Hook
import { useEffect, useState, useCallback, useRef } from 'react';
import { io, Socket } from 'socket.io-client';
interface Aircraft {
hex: string;
flight?: string;
lat: number;
lon: number;
alt: number;
gs: number;
track: number;
vr: number;
}
interface UseSkySpySocketOptions {
url?: string;
topics?: string;
}
export function useSkySpySocket(options: UseSkySpySocketOptions = {}) {
const { url = 'http://localhost:5000', topics = 'aircraft' } = options;
const [connected, setConnected] = useState(false);
const [aircraft, setAircraft] = useState<Map<string, Aircraft>>(new Map());
const socketRef = useRef<Socket | null>(null);
useEffect(() => {
const socket = io(url, {
path: '/socket.io/socket.io',
query: { topics },
transports: ['websocket', 'polling']
});
socketRef.current = socket;
socket.on('connect', () => setConnected(true));
socket.on('disconnect', () => setConnected(false));
socket.on('aircraft:snapshot', (data) => {
setAircraft(new Map(data.aircraft.map((a: Aircraft) => [a.hex, a])));
});
socket.on('aircraft:update', (data) => {
setAircraft((prev) => {
const next = new Map(prev);
for (const a of data.aircraft) {
const existing = next.get(a.hex);
next.set(a.hex, { ...existing, ...a });
}
return next;
});
});
socket.on('aircraft:remove', (data) => {
setAircraft((prev) => {
const next = new Map(prev);
for (const icao of data.icaos) {
next.delete(icao);
}
return next;
});
});
return () => {
socket.disconnect();
};
}, [url, topics]);
return {
connected,
aircraft: Array.from(aircraft.values()),
socket: socketRef.current
};
}Usage Example
function AircraftList() {
const { connected, aircraft } = useSkySpySocket({
topics: 'aircraft,safety'
});
if (!connected) {
return <div>🔄 Connecting...</div>;
}
return (
<div>
<h2>✈️ {aircraft.length} Aircraft</h2>
<ul>
{aircraft.map((a) => (
<li key={a.hex}>
{a.flight || a.hex} - {a.alt}ft @ {a.gs}kts
</li>
))}
</ul>
</div>
);
}With Safety Events
function SafetyMonitor() {
const { socket, connected } = useSkySpySocket({
topics: 'safety'
});
const [alerts, setAlerts] = useState<any[]>([]);
useEffect(() => {
if (!socket) return;
socket.on('safety:event', (event) => {
setAlerts((prev) => [event, ...prev].slice(0, 50));
});
}, [socket]);
return (
<div>
<h2>🛡️ Safety Alerts</h2>
{alerts.map((alert, i) => (
<div key={i} className={alert.severity}>
{alert.message}
</div>
))}
</div>
);
}Updated 7 days ago