Introduces Unicode-safe base64 encoding/decoding for call details between incidents and call screens. Refactors PageHeader to accept left, center, and right header props for more flexible layouts. Updates call.jsx and register.jsx to use the new header structure, and improves department/unit rendering and modal dropdowns for department selection. Generalizes and modernizes UI code for better maintainability and cross-platform compatibility.
78 lines
2.2 KiB
JavaScript
78 lines
2.2 KiB
JavaScript
import React, { createContext, useEffect, useRef, useState } from 'react';
|
|
|
|
export const WebSocketContext = createContext(null);
|
|
|
|
export const WebSocketProvider = ({ children }) => {
|
|
const ws = useRef(null);
|
|
const reconnectInterval = useRef(null);
|
|
const reconnectAttempts = useRef(0);
|
|
const maxReconnectAttempts = 5;
|
|
|
|
const [isConnected, setIsConnected] = useState(false);
|
|
const [lastMessage, setLastMessage] = useState(null);
|
|
|
|
const connect = () => {
|
|
if (reconnectAttempts.current >= maxReconnectAttempts) {
|
|
console.warn('❌ Max reconnect attempts reached. Giving up.');
|
|
clearInterval(reconnectInterval.current);
|
|
ws.current?.close();
|
|
return;
|
|
}
|
|
|
|
console.log(`🔁 Connecting (Attempt ${reconnectAttempts.current + 1}/${maxReconnectAttempts})`);
|
|
ws.current = new WebSocket(`${process.env.EXPO_PUBLIC_WS_URL}/callfeed`);
|
|
|
|
ws.current.onopen = () => {
|
|
console.log('✅ WebSocket connected');
|
|
setIsConnected(true);
|
|
reconnectAttempts.current = 0;
|
|
if (reconnectInterval.current) {
|
|
clearInterval(reconnectInterval.current);
|
|
reconnectInterval.current = null;
|
|
}
|
|
};
|
|
|
|
ws.current.onmessage = (e) => {
|
|
console.log('📩 Message received:', e.data);
|
|
setLastMessage(e.data);
|
|
};
|
|
|
|
ws.current.onerror = (e) => {
|
|
console.error('❌ WebSocket error:', e.message);
|
|
};
|
|
|
|
ws.current.onclose = (e) => {
|
|
console.log('🔌 WebSocket closed:', e.code, e.reason);
|
|
setIsConnected(false);
|
|
if (!reconnectInterval.current && reconnectAttempts.current < maxReconnectAttempts) {
|
|
reconnectInterval.current = setInterval(() => {
|
|
reconnectAttempts.current += 1;
|
|
connect();
|
|
}, 3000);
|
|
}
|
|
};
|
|
};
|
|
|
|
useEffect(() => {
|
|
connect();
|
|
|
|
return () => {
|
|
clearInterval(reconnectInterval.current);
|
|
ws.current?.close();
|
|
};
|
|
}, []);
|
|
|
|
const sendMessage = (msg) => {
|
|
if (ws.current?.readyState === WebSocket.OPEN) {
|
|
ws.current.send(JSON.stringify(msg));
|
|
} else {
|
|
console.warn('⚠️ WebSocket is not open. Message not sent.');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<WebSocketContext.Provider value={{ sendMessage, lastMessage, isConnected }}>
|
|
{children}
|
|
</WebSocketContext.Provider>
|
|
);
|
|
};
|