Files
desktop/app/providers/InformationProvider/InformationProvider.tsx
rosetta 83f38dc63f 'init'
2026-01-30 05:01:05 +02:00

171 lines
6.4 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) => {
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>
)
}