Files
desktop/app/providers/DialogProvider/useSynchronize.ts

70 lines
2.7 KiB
TypeScript

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(() => {
const handshake_complete = () => {
trySync();
}
protocol.on('handshake_complete', handshake_complete);
return () => {
protocol.off('handshake_complete', handshake_complete);
}
}, [protocol]);
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 = ?",
[publicKey, packet.getTimestamp(), packet.getTimestamp()]
);
console.info("Batch complete", publicKey, packet.getTimestamp());
trySync();
}
if(status == SyncStatus.NOT_NEEDED){
/**
* Синхронизация не нужна, все данные актуальны
*/
setProtocolState(ProtocolState.CONNECTED);
}
}, [publicKey]);
}