import { useDatabase } from "@/app/providers/DatabaseProvider/useDatabase"; import { OnlineState, PacketOnlineState, PublicKeyOnlineState } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinestate"; import { createContext, useEffect, useState } from "react"; import { usePacket } from "../ProtocolProvider/usePacket"; import { useConsoleLogger } from "@/app/hooks/useConsoleLogger"; import { useSystemAccounts } from "../SystemAccountsProvider/useSystemAccounts"; import { usePublicKey } from "../AccountProvider/usePublicKey"; export const InformationContext = createContext({}); interface InformationProviderProps { children: React.ReactNode; } export interface UserInformation { publicKey: string; verified: number; title: string; username: string; online: OnlineState; } export interface GroupInformation { groupId: string; title: string; description: string; } export function InformationProvider(props: InformationProviderProps) { const [cachedUsers, setCachedUsers] = useState([]); const [cachedGroups, setCachedGroups] = useState([]); const {allQuery, getQuery, runQuery} = useDatabase(); const {info} = useConsoleLogger("InformationProvider"); const systemAccounts = useSystemAccounts(); const publicKey = usePublicKey(); useEffect(() => { loadCachedUsers(); loadCachedGroups(); }, [publicKey]); usePacket(0x5, (state: PacketOnlineState) => { const keys = state.getPublicKeysState(); keys.map((value : PublicKeyOnlineState) => { const cachedUser = cachedUsers.find((userInfo) => userInfo.publicKey == value.publicKey); if(!cachedUser) { info(`No cached user found for public key: ${value.publicKey}, info not updated`); return; } updateUserInformation({ ...cachedUser, online: value.state }); }) }); const loadCachedGroups = () => { if(publicKey == ''){ return; } const result = allQuery("SELECT * FROM groups WHERE account = ?", [publicKey]); result.then((rows) => { const infos : GroupInformation[] = []; for(let i = 0; i < rows.length; i++) { infos.push({ groupId: rows[i].group_id, title: rows[i].title, description: rows[i].description, }); } setCachedGroups(infos); }); } const loadCachedUsers = () => { const result = allQuery("SELECT * FROM cached_users", []); result.then((rows) => { const infos : UserInformation[] = []; for(let i = 0; i < rows.length; i++) { infos.push({ publicKey: rows[i].public_key, verified: rows[i].verified, title: rows[i].title, username: rows[i].username, online: publicKey == rows[i].public_key ? OnlineState.ONLINE : OnlineState.OFFLINE }); } infos.push(...systemAccounts); setCachedUsers(infos); }); } const updateGroupInformation = async (groupInfo : GroupInformation) => { const result = await getQuery("SELECT COUNT(*) as count FROM groups WHERE account = ? AND group_id = ?", [publicKey, groupInfo.groupId]); if(result.count > 0){ /** * Обрабатываем только событие если строка в базе уже есть, * потому что добавление строки мы отрабатываем в другом месте */ await runQuery(`UPDATE groups SET title = ?, description = ? WHERE account = ? AND group_id = ?`, [groupInfo.title, groupInfo.description, publicKey, groupInfo.groupId]); } if(cachedGroups.find((v) => v.groupId == groupInfo.groupId)){ setCachedGroups((prev) => prev.map((group) => { if (group.groupId == groupInfo.groupId) { return { ...group, title: groupInfo.title, description: groupInfo.description } } return group; })); }else{ setCachedGroups((prev) => ([ ...prev, { groupId: groupInfo.groupId, title: groupInfo.title, description: groupInfo.description } ])); } } const updateUserInformation = async (userInfo : UserInformation) => { if(systemAccounts.find((acc) => acc.publicKey == userInfo.publicKey)){ /** * Данные системных аккаунтов не нужно кэшифровать, они уже * прописаны в коде */ return; } const result = await getQuery("SELECT COUNT(*) as count FROM cached_users WHERE public_key = ?", [userInfo.publicKey]); if (result.count > 0) { await runQuery(`UPDATE cached_users SET title = ?, username = ?, verified = ? WHERE public_key = ?`, [userInfo.title, userInfo.username, userInfo.verified, userInfo.publicKey]); setCachedUsers((prev) => prev.map((user) => { if (user.publicKey == userInfo.publicKey) { return { ...user, verified: userInfo.verified, title: userInfo.title, username: userInfo.username, online: userInfo.online, } } return user; })); } else { await runQuery(`INSERT INTO cached_users (public_key, title, username, verified) VALUES (?, ?, ?, ?)`, [userInfo.publicKey, userInfo.title, userInfo.username, userInfo.verified]); setCachedUsers((prev) => ([ ...prev, { publicKey: userInfo.publicKey, title: userInfo.title, username: userInfo.username, online: OnlineState.OFFLINE, verified: userInfo.verified } ])); } } return ( {props.children} ) }