nitro-react/src/hooks/friends/useFriends.ts

266 lines
8.2 KiB
TypeScript
Raw Normal View History

2022-03-31 12:16:58 -04:00
import { AcceptFriendMessageComposer, DeclineFriendMessageComposer, FollowFriendMessageComposer, FriendListFragmentEvent, FriendListUpdateEvent, FriendParser, FriendRequestsEvent, GetFriendRequestsComposer, MessengerInitComposer, MessengerInitEvent, NewFriendRequestEvent, RequestFriendComposer, SetRelationshipStatusComposer } from '@nitrots/nitro-renderer';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useBetween } from 'use-between';
import { CloneObject, MessengerFriend, MessengerRequest, MessengerSettings, SendMessageComposer } from '../../api';
import { UseMessageEventHook } from '../messages';
const useFriendsState = () =>
{
const [ friends, setFriends ] = useState<MessengerFriend[]>([]);
const [ requests, setRequests ] = useState<MessengerRequest[]>([]);
const [ sentRequests, setSentRequests ] = useState<number[]>([]);
const [ settings, setSettings ] = useState<MessengerSettings>(null);
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 = useCallback((friend: MessengerFriend) => SendMessageComposer(new FollowFriendMessageComposer(friend.id)), []);
const updateRelationship = useCallback((friend: MessengerFriend, type: number) => ((type !== friend.relationshipStatus) && SendMessageComposer(new SetRelationshipStatusComposer(friend.id, type))), []);
const getFriend = useCallback((userId: number) =>
{
for(const friend of friends)
{
if(friend.id === userId) return friend;
}
return null;
}, [ friends ]);
const canRequestFriend = useCallback((userId: number) =>
{
if(getFriend(userId)) return false;
if(requests.find(request => (request.requesterUserId === userId))) return false;
if(sentRequests.indexOf(userId) >= 0) return false;
return true;
}, [ requests, sentRequests, getFriend ]);
const requestFriend = useCallback((userId: number, userName: string) =>
{
if(!canRequestFriend(userId)) return false;
setSentRequests(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newSentRequests = [ ...prevValue ];
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
newSentRequests.push(userId);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
return newSentRequests;
});
2022-03-31 12:16:58 -04:00
SendMessageComposer(new RequestFriendComposer(userName));
}, [ canRequestFriend ]);
const requestResponse = useCallback((requestId: number, flag: boolean) =>
{
if(requestId === -1 && !flag)
{
SendMessageComposer(new DeclineFriendMessageComposer(true));
setRequests([]);
}
else
{
setRequests(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newRequests = [ ...prevValue ];
const index = newRequests.findIndex(request => (request.id === requestId));
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(index === -1) return prevValue;
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(flag)
{
SendMessageComposer(new AcceptFriendMessageComposer(newRequests[index].id));
}
else
{
SendMessageComposer(new DeclineFriendMessageComposer(false, newRequests[index].id));
}
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
newRequests.splice(index, 1);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
return newRequests;
});
2022-03-31 12:16:58 -04:00
}
}, []);
const onMessengerInitEvent = useCallback((event: MessengerInitEvent) =>
{
const parser = event.getParser();
setSettings(new MessengerSettings(
parser.userFriendLimit,
parser.normalFriendLimit,
parser.extendedFriendLimit,
parser.categories));
SendMessageComposer(new GetFriendRequestsComposer());
}, []);
UseMessageEventHook(MessengerInitEvent, onMessengerInitEvent);
const onFriendsFragmentEvent = useCallback((event: FriendListFragmentEvent) =>
{
const parser = event.getParser();
setFriends(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newValue = [ ...prevValue ];
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
for(const friend of parser.fragment)
{
const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id));
const newFriend = new MessengerFriend();
newFriend.populate(friend);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(index > -1) newValue[index] = newFriend;
else newValue.push(newFriend);
}
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
return newValue;
});
2022-03-31 12:16:58 -04:00
}, []);
UseMessageEventHook(FriendListFragmentEvent, onFriendsFragmentEvent);
const onFriendsUpdateEvent = useCallback((event: FriendListUpdateEvent) =>
{
const parser = event.getParser();
setFriends(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newValue = [ ...prevValue ];
const processUpdate = (friend: FriendParser) =>
2022-03-31 12:16:58 -04:00
{
2022-04-02 21:12:58 -04:00
const index = newValue.findIndex(existingFriend => (existingFriend.id === friend.id));
if(index === -1)
{
const newFriend = new MessengerFriend();
newFriend.populate(friend);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
newValue.unshift(newFriend);
}
else
2022-03-31 12:16:58 -04:00
{
2022-04-02 21:12:58 -04:00
newValue[index].populate(friend);
2022-03-31 12:16:58 -04:00
}
2022-04-02 21:12:58 -04:00
}
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
for(const friend of parser.addedFriends) processUpdate(friend);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
for(const friend of parser.updatedFriends) processUpdate(friend);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
for(const removedFriendId of parser.removedFriendIds)
{
const index = newValue.findIndex(existingFriend => (existingFriend.id === removedFriendId));
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(index > -1) newValue.splice(index, 1);
}
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
return newValue;
});
2022-03-31 12:16:58 -04:00
}, []);
UseMessageEventHook(FriendListUpdateEvent, onFriendsUpdateEvent);
const onFriendRequestsEvent = useCallback((event: FriendRequestsEvent) =>
{
const parser = event.getParser();
setRequests(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newValue = [ ...prevValue ];
for(const request of parser.requests)
2022-03-31 12:16:58 -04:00
{
2022-04-02 21:12:58 -04:00
const index = newValue.findIndex(existing => (existing.requesterUserId === request.requesterUserId));
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(index > 0)
2022-03-31 12:16:58 -04:00
{
2022-04-02 21:12:58 -04:00
newValue[index] = CloneObject(newValue[index]);
newValue[index].populate(request);
2022-03-31 12:16:58 -04:00
}
2022-04-02 21:12:58 -04:00
else
{
const newRequest = new MessengerRequest();
newRequest.populate(request);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
newValue.push(newRequest);
}
}
return newValue;
});
2022-03-31 12:16:58 -04:00
}, []);
UseMessageEventHook(FriendRequestsEvent, onFriendRequestsEvent);
const onNewFriendRequestEvent = useCallback((event: NewFriendRequestEvent) =>
{
const parser = event.getParser();
const request = parser.request;
setRequests(prevValue =>
2022-04-02 21:12:58 -04:00
{
const newRequests = [ ...prevValue ];
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
const index = newRequests.findIndex(existing => (existing.requesterUserId === request.requesterUserId));
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
if(index === -1)
{
const newRequest = new MessengerRequest();
newRequest.populate(request);
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
newRequests.push(newRequest);
}
2022-03-31 12:16:58 -04:00
2022-04-02 21:12:58 -04:00
return newRequests;
});
2022-03-31 12:16:58 -04:00
}, []);
UseMessageEventHook(NewFriendRequestEvent, onNewFriendRequestEvent);
useEffect(() =>
{
SendMessageComposer(new MessengerInitComposer());
}, []);
return { friends, requests, sentRequests, settings, onlineFriends, offlineFriends, getFriend, canRequestFriend, requestFriend, requestResponse, followFriend, updateRelationship };
}
export const useFriends = () => useBetween(useFriendsState);