272 lines
7.5 KiB
TypeScript
272 lines
7.5 KiB
TypeScript
import {
|
|
AcceptFriendMessageComposer,
|
|
DeclineFriendMessageComposer,
|
|
FindFriendsProcessResultEvent,
|
|
FollowFriendMessageComposer,
|
|
FriendListFragmentEvent,
|
|
FriendListUpdateComposer,
|
|
FriendListUpdateEvent,
|
|
FriendParser,
|
|
FriendRequestsEvent,
|
|
GetFriendRequestsComposer,
|
|
MessengerInitComposer,
|
|
MessengerInitEvent,
|
|
NewFriendRequestEvent,
|
|
RequestFriendComposer,
|
|
SetRelationshipStatusComposer,
|
|
} from "@nitro/renderer";
|
|
import {useEffect, useMemo, useState} from "react";
|
|
import {useBetween} from "use-between";
|
|
|
|
import {CloneObject, GetSessionDataManager, LocalizeText, MessengerFriend, MessengerRequest, MessengerSettings, SendMessageComposer} from "../../api";
|
|
import {useMessageEvent} from "../events";
|
|
import {useNotification} from "../notification";
|
|
|
|
const useFriendsState = () => {
|
|
const [friends, setFriends] = useState<MessengerFriend[]>([]);
|
|
const [requests, setRequests] = useState<MessengerRequest[]>([]);
|
|
const [sentRequests, setSentRequests] = useState<number[]>([]);
|
|
const [dismissedRequestIds, setDismissedRequestIds] = useState<number[]>([]);
|
|
const [settings, setSettings] = useState<MessengerSettings>(null);
|
|
const {simpleAlert} = useNotification();
|
|
|
|
const onlineFriends = useMemo(() => {
|
|
const onlineFriends = friends.filter(friend => friend.online);
|
|
|
|
onlineFriends.sort((a, b) => {
|
|
if (a.name < b.name) return -1;
|
|
|
|
if (a.name > b.name) return 1;
|
|
|
|
return 0;
|
|
});
|
|
|
|
return onlineFriends;
|
|
}, [friends]);
|
|
|
|
const offlineFriends = useMemo(() => {
|
|
const offlineFriends = friends.filter(friend => !friend.online);
|
|
|
|
offlineFriends.sort((a, b) => {
|
|
if (a.name < b.name) return -1;
|
|
|
|
if (a.name > b.name) return 1;
|
|
|
|
return 0;
|
|
});
|
|
|
|
return offlineFriends;
|
|
}, [friends]);
|
|
|
|
const followFriend = (friend: MessengerFriend) => SendMessageComposer(new FollowFriendMessageComposer(friend.id));
|
|
|
|
const updateRelationship = (friend: MessengerFriend, type: number) =>
|
|
type !== friend.relationshipStatus && SendMessageComposer(new SetRelationshipStatusComposer(friend.id, type));
|
|
|
|
const getFriend = (userId: number) => {
|
|
for (const friend of friends) {
|
|
if (friend.id === userId) return friend;
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
const canRequestFriend = (userId: number) => {
|
|
if (userId === GetSessionDataManager().userId) return false;
|
|
|
|
if (getFriend(userId)) return false;
|
|
|
|
if (requests.find(request => request.requesterUserId === userId)) return false;
|
|
|
|
if (sentRequests.indexOf(userId) >= 0) return false;
|
|
|
|
return true;
|
|
};
|
|
|
|
const requestFriend = (userId: number, userName: string) => {
|
|
if (!canRequestFriend(userId)) return false;
|
|
|
|
setSentRequests(prevValue => {
|
|
const newSentRequests = [...prevValue];
|
|
|
|
newSentRequests.push(userId);
|
|
|
|
return newSentRequests;
|
|
});
|
|
|
|
SendMessageComposer(new RequestFriendComposer(userName));
|
|
};
|
|
|
|
const requestResponse = (requestId: number, flag: boolean) => {
|
|
if (requestId === -1 && !flag) {
|
|
SendMessageComposer(new DeclineFriendMessageComposer(true));
|
|
|
|
setRequests([]);
|
|
} else {
|
|
setRequests(prevValue => {
|
|
const newRequests = [...prevValue];
|
|
const index = newRequests.findIndex(request => request.id === requestId);
|
|
|
|
if (index === -1) return prevValue;
|
|
|
|
if (flag) {
|
|
SendMessageComposer(new AcceptFriendMessageComposer(newRequests[index].id));
|
|
} else {
|
|
SendMessageComposer(new DeclineFriendMessageComposer(false, newRequests[index].id));
|
|
}
|
|
|
|
newRequests.splice(index, 1);
|
|
|
|
return newRequests;
|
|
});
|
|
}
|
|
};
|
|
|
|
useMessageEvent<MessengerInitEvent>(MessengerInitEvent, event => {
|
|
const parser = event.getParser();
|
|
|
|
setSettings(new MessengerSettings(parser.userFriendLimit, parser.normalFriendLimit, parser.extendedFriendLimit, parser.categories));
|
|
|
|
SendMessageComposer(new GetFriendRequestsComposer());
|
|
});
|
|
|
|
useMessageEvent<FriendListFragmentEvent>(FriendListFragmentEvent, event => {
|
|
const parser = event.getParser();
|
|
|
|
setFriends(prevValue => {
|
|
const newValue = [...prevValue];
|
|
|
|
for (const friend of parser.fragment) {
|
|
const index = newValue.findIndex(existingFriend => existingFriend.id === friend.id);
|
|
const newFriend = new MessengerFriend();
|
|
newFriend.populate(friend);
|
|
|
|
if (index > -1) newValue[index] = newFriend;
|
|
else newValue.push(newFriend);
|
|
}
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useMessageEvent<FriendListUpdateEvent>(FriendListUpdateEvent, event => {
|
|
const parser = event.getParser();
|
|
|
|
setFriends(prevValue => {
|
|
const newValue = [...prevValue];
|
|
|
|
const processUpdate = (friend: FriendParser) => {
|
|
const index = newValue.findIndex(existingFriend => existingFriend.id === friend.id);
|
|
|
|
if (index === -1) {
|
|
const newFriend = new MessengerFriend();
|
|
newFriend.populate(friend);
|
|
|
|
newValue.unshift(newFriend);
|
|
} else {
|
|
newValue[index].populate(friend);
|
|
}
|
|
};
|
|
|
|
for (const friend of parser.addedFriends) processUpdate(friend);
|
|
|
|
for (const friend of parser.updatedFriends) processUpdate(friend);
|
|
|
|
for (const removedFriendId of parser.removedFriendIds) {
|
|
const index = newValue.findIndex(existingFriend => existingFriend.id === removedFriendId);
|
|
|
|
if (index > -1) newValue.splice(index, 1);
|
|
}
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useMessageEvent<FriendRequestsEvent>(FriendRequestsEvent, event => {
|
|
const parser = event.getParser();
|
|
|
|
setRequests(prevValue => {
|
|
const newValue = [...prevValue];
|
|
|
|
for (const request of parser.requests) {
|
|
const index = newValue.findIndex(existing => existing.requesterUserId === request.requesterUserId);
|
|
|
|
if (index > 0) {
|
|
newValue[index] = CloneObject(newValue[index]);
|
|
newValue[index].populate(request);
|
|
} else {
|
|
const newRequest = new MessengerRequest();
|
|
newRequest.populate(request);
|
|
|
|
newValue.push(newRequest);
|
|
}
|
|
}
|
|
|
|
return newValue;
|
|
});
|
|
});
|
|
|
|
useMessageEvent<NewFriendRequestEvent>(NewFriendRequestEvent, event => {
|
|
const parser = event.getParser();
|
|
const request = parser.request;
|
|
|
|
setRequests(prevValue => {
|
|
const newRequests = [...prevValue];
|
|
|
|
const index = newRequests.findIndex(existing => existing.requesterUserId === request.requesterUserId);
|
|
|
|
if (index === -1) {
|
|
const newRequest = new MessengerRequest();
|
|
newRequest.populate(request);
|
|
|
|
newRequests.push(newRequest);
|
|
}
|
|
|
|
return newRequests;
|
|
});
|
|
});
|
|
|
|
useMessageEvent<FindFriendsProcessResultEvent>(FindFriendsProcessResultEvent, event => {
|
|
const parser = event.getParser();
|
|
|
|
if (!parser) return;
|
|
|
|
simpleAlert(
|
|
LocalizeText(!parser.success ? "friendbar.find.error.text" : "friendbar.find.success.text"),
|
|
"",
|
|
"",
|
|
"",
|
|
LocalizeText(!parser.success ? "friendbar.find.error.title" : "friendbar.find.success.title")
|
|
);
|
|
});
|
|
|
|
useEffect(() => {
|
|
SendMessageComposer(new MessengerInitComposer());
|
|
|
|
const interval = setInterval(() => SendMessageComposer(new FriendListUpdateComposer()), 120000);
|
|
|
|
return () => {
|
|
clearInterval(interval);
|
|
};
|
|
}, []);
|
|
|
|
return {
|
|
friends,
|
|
requests,
|
|
sentRequests,
|
|
dismissedRequestIds,
|
|
setDismissedRequestIds,
|
|
settings,
|
|
onlineFriends,
|
|
offlineFriends,
|
|
getFriend,
|
|
canRequestFriend,
|
|
requestFriend,
|
|
requestResponse,
|
|
followFriend,
|
|
updateRelationship,
|
|
};
|
|
};
|
|
|
|
export const useFriends = () => useBetween(useFriendsState);
|