This commit was merged in pull request #77.
This commit is contained in:
@@ -7,6 +7,7 @@ import React, {
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { AppState, Platform } from "react-native";
|
||||
|
||||
export type TimmyMood = "idle" | "thinking" | "working" | "speaking";
|
||||
|
||||
@@ -21,7 +22,7 @@ export type WsEvent = {
|
||||
count?: number;
|
||||
};
|
||||
|
||||
export type ConnectionStatus = "connecting" | "connected" | "disconnected" | "error";
|
||||
export type ConnectionStatus = "connecting" | "connected" | "disconnected" | "reconnecting" | "error";
|
||||
|
||||
type TimmyContextValue = {
|
||||
timmyMood: TimmyMood;
|
||||
@@ -215,6 +216,54 @@ export function TimmyProvider({ children }: { children: React.ReactNode }) {
|
||||
};
|
||||
}, [connectWs]);
|
||||
|
||||
// AppState-aware WebSocket reconnect on foreground
|
||||
useEffect(() => {
|
||||
if (Platform.OS === "web") return;
|
||||
|
||||
const appStateRef = { current: AppState.currentState };
|
||||
|
||||
const subscription = AppState.addEventListener("change", (nextAppState) => {
|
||||
const wasBackground =
|
||||
appStateRef.current === "background" ||
|
||||
appStateRef.current === "inactive";
|
||||
const isNowActive = nextAppState === "active";
|
||||
|
||||
if (wasBackground && isNowActive) {
|
||||
// App returned to foreground — check if WS is still alive
|
||||
const ws = wsRef.current;
|
||||
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
||||
// Cancel any pending retry so we don't create duplicates
|
||||
if (retryTimerRef.current) {
|
||||
clearTimeout(retryTimerRef.current);
|
||||
retryTimerRef.current = null;
|
||||
}
|
||||
retryCountRef.current = 0;
|
||||
setConnectionStatus("reconnecting");
|
||||
connectWs();
|
||||
}
|
||||
} else if (nextAppState === "background") {
|
||||
// Proactively close the WS to avoid OS killing it mid-frame
|
||||
if (retryTimerRef.current) {
|
||||
clearTimeout(retryTimerRef.current);
|
||||
retryTimerRef.current = null;
|
||||
}
|
||||
if (wsRef.current) {
|
||||
wsRef.current.onclose = null;
|
||||
wsRef.current.onerror = null;
|
||||
wsRef.current.close();
|
||||
wsRef.current = null;
|
||||
}
|
||||
setConnectionStatus("disconnected");
|
||||
}
|
||||
|
||||
appStateRef.current = nextAppState;
|
||||
});
|
||||
|
||||
return () => {
|
||||
subscription.remove();
|
||||
};
|
||||
}, [connectWs]);
|
||||
|
||||
const send = useCallback((msg: object) => {
|
||||
if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
|
||||
wsRef.current.send(JSON.stringify(msg));
|
||||
|
||||
Reference in New Issue
Block a user