Files
ruvnet--RuView/ui/mobile/src/screens/LiveScreen/useGaussianBridge.ts
T
ruv fdc7142dfa feat: Implement RSSI service for iOS and Web platforms
- Added IosRssiService to handle synthetic RSSI data for iOS.
- Created WebRssiService to simulate RSSI scanning on the web.
- Defined shared types for WifiNetwork and RssiService in rssi.service.ts.
- Introduced simulation service to generate synthetic sensing data.
- Implemented WebSocket service for real-time data handling with reconnection logic.
- Established Zustand stores for managing application state related to MAT and pose data.
- Developed theme context and utility functions for consistent styling and formatting.
- Added type definitions for various application entities including API responses and sensing data.
- Created utility functions for color mapping and URL validation.
- Configured TypeScript settings for the mobile application.
2026-03-02 10:30:33 -05:00

98 lines
2.3 KiB
TypeScript

import { useCallback, useState } from 'react';
import type { RefObject } from 'react';
import type { WebViewMessageEvent } from 'react-native-webview';
import { WebView } from 'react-native-webview';
import type { SensingFrame } from '@/types/sensing';
export type GaussianBridgeMessageType = 'READY' | 'FPS_TICK' | 'ERROR';
type BridgeMessage = {
type: GaussianBridgeMessageType;
payload?: {
fps?: number;
message?: string;
};
};
const toJsonScript = (message: unknown): string => {
const serialized = JSON.stringify(message);
return `window.dispatchEvent(new MessageEvent('message', { data: ${JSON.stringify(serialized)} })); true;`;
};
export const useGaussianBridge = (webViewRef: RefObject<WebView | null>) => {
const [isReady, setIsReady] = useState(false);
const [fps, setFps] = useState(0);
const [error, setError] = useState<string | null>(null);
const send = useCallback((message: unknown) => {
const webView = webViewRef.current;
if (!webView) {
return;
}
webView.injectJavaScript(toJsonScript(message));
}, [webViewRef]);
const sendFrame = useCallback(
(frame: SensingFrame) => {
send({
type: 'FRAME_UPDATE',
payload: frame,
});
},
[send],
);
const onMessage = useCallback((event: WebViewMessageEvent) => {
let parsed: BridgeMessage | null = null;
const raw = event.nativeEvent.data;
if (typeof raw === 'string') {
try {
parsed = JSON.parse(raw) as BridgeMessage;
} catch {
setError('Invalid bridge message format');
return;
}
} else if (typeof raw === 'object' && raw !== null) {
parsed = raw as BridgeMessage;
}
if (!parsed) {
return;
}
if (parsed.type === 'READY') {
setIsReady(true);
setError(null);
return;
}
if (parsed.type === 'FPS_TICK') {
const fpsValue = parsed.payload?.fps;
if (typeof fpsValue === 'number' && Number.isFinite(fpsValue)) {
setFps(Math.max(0, Math.floor(fpsValue)));
}
return;
}
if (parsed.type === 'ERROR') {
setError(parsed.payload?.message ?? 'Unknown bridge error');
setIsReady(false);
}
}, []);
return {
sendFrame,
onMessage,
isReady,
fps,
error,
reset: () => {
setIsReady(false);
setFps(0);
setError(null);
},
};
};