154 lines
5.9 KiB
TypeScript
154 lines
5.9 KiB
TypeScript
import { useContext, useEffect, useState } from "react";
|
||
import { InformationContext, UserInformation } from "./InformationProvider";
|
||
import { PacketOnlineSubscribe } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinesubscribe";
|
||
import { useMemory } from "../MemoryProvider/useMemory";
|
||
import { OnlineState } from "@/app/providers/ProtocolProvider/protocol/packets/packet.onlinestate";
|
||
import { PacketSearch } from "@/app/providers/ProtocolProvider/protocol/packets/packet.search";
|
||
import { usePrivateKeyHash } from "../AccountProvider/usePrivateKeyHash";
|
||
import { useSender } from "../ProtocolProvider/useSender";
|
||
import { usePacket } from "../ProtocolProvider/usePacket";
|
||
import { usePublicKey } from "../AccountProvider/usePublicKey";
|
||
import { useBlacklist } from "../BlacklistProvider/useBlacklist";
|
||
import { useConsoleLogger } from "@/app/hooks/useConsoleLogger";
|
||
import { useSystemAccounts } from "../SystemAccountsProvider/useSystemAccounts";
|
||
|
||
export function useUserInformation(publicKey: string) : [
|
||
UserInformation,
|
||
(userInfo: UserInformation) => Promise<void>,
|
||
() => void,
|
||
boolean
|
||
] {
|
||
const context = useContext(InformationContext);
|
||
const send = useSender();
|
||
const privateKey = usePrivateKeyHash();
|
||
const [onlineSubscribes, setOnlineSubscribes] = useMemory<string[]>("online_subscribes", [], true);
|
||
const {cachedUsers, updateUserInformation} = context;
|
||
const user : UserInformation = cachedUsers.find((user: UserInformation) => user.publicKey == publicKey);
|
||
const [loading, setLoading] = useState(false);
|
||
const ownPublicKey = usePublicKey();
|
||
const [blocked] = useBlacklist(publicKey);
|
||
const {info, warn} = useConsoleLogger('useUserInformation');
|
||
const systemAccounts = useSystemAccounts();
|
||
|
||
if(!context || !context.cachedUsers) {
|
||
throw new Error("useUserInformation must be used within a InformationProvider");
|
||
}
|
||
|
||
const forceUpdateUserInformation = () => {
|
||
if(publicKey.indexOf("#group:") !== -1){
|
||
/**
|
||
* This is group, only users can be force updated
|
||
*/
|
||
info("Force update skipped for group " + publicKey);
|
||
return;
|
||
}
|
||
if(systemAccounts.find((acc) => acc.publicKey == publicKey)){
|
||
/**
|
||
* System account has no updates, its hardcoded display
|
||
* name and user name
|
||
*/
|
||
info("System account not need force update");
|
||
return;
|
||
}
|
||
if(blocked){
|
||
warn("User is blocked, no force update " + publicKey);
|
||
return;
|
||
}
|
||
warn("Force update " + publicKey);
|
||
let packetSearch = new PacketSearch();
|
||
packetSearch.setSearch(publicKey);
|
||
packetSearch.setPrivateKey(privateKey);
|
||
send(packetSearch);
|
||
}
|
||
|
||
useEffect(() => {
|
||
/**
|
||
* Подписываемся на статус пользователя онлайн или не онлайн
|
||
* если еще не подписаны
|
||
*/
|
||
if(systemAccounts.find((acc) => acc.publicKey == publicKey)){
|
||
/**
|
||
* У системных аккаунтов не нужно подписыаться на онлайн статус
|
||
*/
|
||
return;
|
||
}
|
||
if(onlineSubscribes.indexOf(publicKey) !== -1
|
||
|| publicKey.indexOf("#group:") !== -1
|
||
|| publicKey == ownPublicKey
|
||
|| publicKey.trim() == ''
|
||
|| blocked){
|
||
/**
|
||
* Уже подписаны на онлайн статус этого пользователя или это группа
|
||
*/
|
||
return;
|
||
}
|
||
let subscribePacket = new PacketOnlineSubscribe();
|
||
subscribePacket.setPrivateKey(privateKey);
|
||
subscribePacket.addPublicKey(publicKey);
|
||
send(subscribePacket);
|
||
setOnlineSubscribes((prev) => [...prev, publicKey]);
|
||
}, [blocked, publicKey]);
|
||
|
||
useEffect(() => {
|
||
if(user || publicKey.trim() == ''){
|
||
return;
|
||
}
|
||
if(systemAccounts.find((acc) => acc.publicKey == publicKey)){
|
||
/**
|
||
* System account has no updates, its hardcoded display
|
||
* name and user name
|
||
*/
|
||
return;
|
||
}
|
||
setLoading(true);
|
||
let packetSearch = new PacketSearch();
|
||
packetSearch.setSearch(publicKey);
|
||
packetSearch.setPrivateKey(privateKey);
|
||
send(packetSearch);
|
||
}, [publicKey, privateKey, user]);
|
||
|
||
usePacket(0x03, (packet : PacketSearch) => {
|
||
const users = packet.getUsers();
|
||
if (users.length > 0 && users[0].publicKey == publicKey) {
|
||
if( user &&
|
||
user.username == users[0].username &&
|
||
user.verified == users[0].verified &&
|
||
user.title == users[0].title
|
||
){
|
||
/**
|
||
* No update readed from server, stop rerender
|
||
*/
|
||
return;
|
||
}
|
||
setLoading(false);
|
||
updateUserInformation({
|
||
publicKey: users[0].publicKey,
|
||
avatar: "", // No avatar in search packet
|
||
username: users[0].username,
|
||
title: users[0].title,
|
||
online: users[0].online,
|
||
verified: users[0].verified
|
||
});
|
||
}
|
||
}, [publicKey, privateKey]);
|
||
|
||
let userInfo = user ? user : {
|
||
title: "DELETED",
|
||
username: "",
|
||
publicKey: "",
|
||
online: OnlineState.OFFLINE,
|
||
verified: 0
|
||
};
|
||
|
||
if(systemAccounts.find((acc) => acc.publicKey == publicKey)){
|
||
/**
|
||
* Это системный аккаунт, возвращаем его информацию
|
||
*/
|
||
userInfo = systemAccounts.find((acc) => acc.publicKey == publicKey)!;
|
||
}
|
||
|
||
return [
|
||
userInfo, updateUserInformation, forceUpdateUserInformation, loading
|
||
]
|
||
|
||
} |