75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
// hooks/useLiveTelemetry.ts
|
|
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
|
|
interface TelemetryCar {
|
|
carID: number;
|
|
driver_guid: string;
|
|
driver_name: string;
|
|
car_model: string;
|
|
position: number;
|
|
current_lap: number;
|
|
normalizedSplinePos: number;
|
|
speed: number;
|
|
gear: number;
|
|
rpm: number;
|
|
last_lap_time: number | null;
|
|
best_lap_time: number | null;
|
|
}
|
|
|
|
interface TelemetryData {
|
|
type: string;
|
|
timestamp: number;
|
|
cars: TelemetryCar[];
|
|
}
|
|
|
|
export function useLiveTelemetry(serverId?: number) {
|
|
const [telemetry, setTelemetry] = useState<TelemetryCar[]>([]);
|
|
const [connected, setConnected] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const url = serverId
|
|
? `/api/live/telemetry?serverId=${serverId}`
|
|
: '/api/live/telemetry';
|
|
|
|
const eventSource = new EventSource(url);
|
|
|
|
eventSource.onopen = () => {
|
|
console.log('[Telemetry] Connected');
|
|
setConnected(true);
|
|
setError(null);
|
|
};
|
|
|
|
eventSource.onmessage = (event) => {
|
|
try {
|
|
const data: TelemetryData = JSON.parse(event.data);
|
|
|
|
if (data.type === 'connected') {
|
|
console.log('[Telemetry] Stream established');
|
|
} else if (data.type === 'update') {
|
|
setTelemetry(data.cars);
|
|
}
|
|
} catch (err) {
|
|
console.error('[Telemetry] Parse error:', err);
|
|
}
|
|
};
|
|
|
|
eventSource.onerror = (err) => {
|
|
console.error('[Telemetry] Connection error:', err);
|
|
setConnected(false);
|
|
setError('Connection lost');
|
|
eventSource.close();
|
|
};
|
|
|
|
// Cleanup on unmount
|
|
return () => {
|
|
console.log('[Telemetry] Disconnecting');
|
|
eventSource.close();
|
|
};
|
|
}, [serverId]);
|
|
|
|
return { telemetry, connected, error };
|
|
}
|