import Protocol from "@/app/providers/ProtocolProvider/protocol/protocol"; import { createContext, useEffect, useMemo, useState } from "react"; import { usePublicKey } from "../AccountProvider/usePublicKey"; import { usePrivateKeyHash } from "../AccountProvider/usePrivateKeyHash"; import { useLogger } from "@/app/hooks/useLogger"; import { useMemory } from "../MemoryProvider/useMemory"; import { useNavigate } from "react-router-dom"; import { useSystemInformation } from "../SystemProvider/useSystemInformation"; export enum ProtocolState { CONNECTED, HANDSHAKE_EXCHANGE, DISCONNECTED, RECONNECTING, DEVICE_VERIFICATION_REQUIRED } export const ProtocolContext = createContext<[Protocol|null, ProtocolState]>([null, ProtocolState.DISCONNECTED]); interface ProtocolProviderProps { children: React.ReactNode; serverAddress : string; } export function ProtocolProvider(props : ProtocolProviderProps) { const publicKey = usePublicKey(); const privateKey = usePrivateKeyHash(); const protocol = useMemo(() => { return new Protocol(props.serverAddress) }, [props.serverAddress]); const log = useLogger('ProtocolProvider'); const [connect, setConnect] = useState(ProtocolState.DISCONNECTED); const [_, setOnlineSubscribes] = useMemory("online_subscribes", [], true); const systemInfo = useSystemInformation(); const navigate = useNavigate(); useEffect(() => { if(publicKey.trim() == "" || privateKey.trim() == "" || systemInfo.id == "") { return; } const device = { deviceId: systemInfo.id, deviceName: systemInfo.name, deviceOs: systemInfo.os } protocol.connect(); protocol.startHandshakeExchange(publicKey, privateKey, device); protocol.on('connect', () => { protocol.startHandshakeExchange(publicKey, privateKey, device); /** * Сбрасываем подписки на онлайн статусы пользователей * так как при переподключении они слетают */ setOnlineSubscribes([]); }); protocol.on('reconnect', () => { log("Connection lost, reconnecting and starting handshake exchange"); setConnect(ProtocolState.RECONNECTING); }); protocol.on('handshake_start', () => { log("Handshake exchange started"); setConnect(ProtocolState.HANDSHAKE_EXCHANGE); }); protocol.on('handshake_complete', () => { log("Handshake exchange complete"); setConnect(ProtocolState.CONNECTED); }); protocol.on('handshake_need_device_verification', () => { log("Handshake exchange needs device verification"); setConnect(ProtocolState.DEVICE_VERIFICATION_REQUIRED); navigate('/deviceconfirm'); }); }, [publicKey, privateKey, systemInfo.id]); return ( {props.children} ); }