178 lines
6.7 KiB
TypeScript
178 lines
6.7 KiB
TypeScript
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<any>({});
|
|
|
|
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<UserInformation[]>([]);
|
|
const [cachedGroups, setCachedGroups] = useState<GroupInformation[]>([]);
|
|
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 (
|
|
<InformationContext.Provider value={{
|
|
cachedUsers,
|
|
cachedGroups,
|
|
setCachedUsers,
|
|
updateUserInformation,
|
|
updateGroupInformation
|
|
}}>
|
|
{props.children}
|
|
</InformationContext.Provider>
|
|
)
|
|
} |