Add refresh prompt after WS loss

This commit is contained in:
Jack Kingsman
2026-02-24 20:45:47 -08:00
parent 81c166bb8d
commit b4a0b1c515
5 changed files with 15 additions and 4 deletions
+6
View File
@@ -220,6 +220,12 @@ export function App() {
description: success.details,
});
},
onReconnect: () => {
toast.warning('Unstable connection', {
description: 'Please refresh the page to ensure all messages are correctly loaded.',
duration: 10000,
});
},
onMessage: (msg: Message) => {
const activeConv = activeConversationRef.current;
-1
View File
@@ -433,5 +433,4 @@ describe('messageCache', () => {
expect(messageCache.reconcile(current, fetched)).toBeNull();
});
});
});
+6 -1
View File
@@ -24,12 +24,14 @@ interface UseWebSocketOptions {
onMessageAcked?: (messageId: number, ackCount: number, paths?: MessagePath[]) => void;
onError?: (error: ErrorEvent) => void;
onSuccess?: (success: SuccessEvent) => void;
onReconnect?: () => void;
}
export function useWebSocket(options: UseWebSocketOptions) {
const wsRef = useRef<WebSocket | null>(null);
const reconnectTimeoutRef = useRef<number | null>(null);
const shouldReconnectRef = useRef(true);
const hasConnectedRef = useRef(false);
// Store options in ref to avoid stale closures in WebSocket handlers.
// The onmessage callback captures this ref, and we keep the ref updated
@@ -61,6 +63,10 @@ export function useWebSocket(options: UseWebSocketOptions) {
clearTimeout(reconnectTimeoutRef.current);
reconnectTimeoutRef.current = null;
}
if (hasConnectedRef.current) {
optionsRef.current.onReconnect?.();
}
hasConnectedRef.current = true;
};
ws.onclose = () => {
@@ -156,5 +162,4 @@ export function useWebSocket(options: UseWebSocketOptions) {
}
};
}, [connect]);
}
-1
View File
@@ -24,4 +24,3 @@ export const RADIO_PRESETS: RadioPreset[] = [
{ name: 'Portugal 868MHz', freq: 869.618, bw: 62.5, sf: 7, cr: 6 },
{ name: 'Vietnam', freq: 920.25, bw: 250, sf: 11, cr: 5 },
];
+3 -1
View File
@@ -174,7 +174,9 @@ export function getPacketLabel(payloadType: number): PacketLabel {
}
export function generatePacketKey(parsed: ParsedPacket, rawPacket: RawPacket): string {
const contentHash = (parsed.messageHash || hashString(rawPacket.data).toString(16).padStart(8, '0')).slice(0, 8);
const contentHash = (
parsed.messageHash || hashString(rawPacket.data).toString(16).padStart(8, '0')
).slice(0, 8);
if (parsed.payloadType === PayloadType.Advert && parsed.advertPubkey) {
return `ad:${parsed.advertPubkey.slice(0, 12)}`;