import { useEffect } from "react"; import { useProtocolState } from "../ProtocolProvider/useProtocolState"; import { ProtocolState } from "../ProtocolProvider/ProtocolProvider"; import { useDatabase } from "../DatabaseProvider/useDatabase"; import { usePublicKey } from "../AccountProvider/usePublicKey"; import { PacketSync, SyncStatus } from "../ProtocolProvider/protocol/packets/packet.sync"; import { useSender } from "../ProtocolProvider/useSender"; import { usePacket } from "../ProtocolProvider/usePacket"; import { whenFinish } from "./dialogQueue"; import { useProtocol } from "../ProtocolProvider/useProtocol"; /** * Хук отвечает за синхронизацию сообщений, запрос синхронизации * при подключении */ export function useSynchronize() { const [_, setProtocolState] = useProtocolState(); const {getQuery, runQuery} = useDatabase(); const publicKey = usePublicKey(); const send = useSender(); const {protocol} = useProtocol(); useEffect(() => { if(protocol.handshakeExchangeComplete){ trySync(); } }, [protocol.handshakeExchangeComplete]); const trySync = async () => { const lastSyncTime = await getQuery(`SELECT last_sync FROM accounts_sync_times WHERE account = ?`, [publicKey]); sendSynchronize(lastSyncTime?.last_sync ?? 0); } const sendSynchronize = (timestamp: number) => { const packet = new PacketSync(); packet.setStatus(0); packet.setTimestamp(timestamp); send(packet); } usePacket(25, async (packet: PacketSync) => { const status = packet.getStatus(); if(status == SyncStatus.BATCH_START){ setProtocolState(ProtocolState.SYNCHRONIZATION); } if(status == SyncStatus.BATCH_END){ console.info("Batch start"); await whenFinish(); console.info("Batch finished"); await runQuery( "INSERT INTO accounts_sync_times (account, last_sync) VALUES (?, ?) " + "ON CONFLICT(account) DO UPDATE SET last_sync = ? WHERE account = ?", [publicKey, packet.getTimestamp(), packet.getTimestamp(), publicKey] ); console.info("Batch complete", publicKey, packet.getTimestamp()); trySync(); } if(status == SyncStatus.NOT_NEEDED){ /** * Синхронизация не нужна, все данные актуальны */ setProtocolState(ProtocolState.CONNECTED); } }, [publicKey]); }