mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-27 08:00:51 +01:00
Add friend request bubble
This commit is contained in:
parent
128919af62
commit
b51ef0bbcc
@ -3,7 +3,7 @@ import { DeclineFriendMessageComposer } from '@nitrots/nitro-renderer/src';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { GetRoomSession } from '../../api';
|
||||
import { FriendEnteredRoomEvent, FriendListContentEvent, FriendsEvent, FriendsRequestCountEvent } from '../../events';
|
||||
import { FriendEnteredRoomEvent, FriendListContentEvent, FriendRequestEvent, FriendsAcceptFriendRequestEvent, FriendsDeclineFriendRequestEvent, FriendsEvent, FriendsRequestCountEvent } from '../../events';
|
||||
import { FriendsSendFriendRequestEvent } from '../../events/friends/FriendsSendFriendRequestEvent';
|
||||
import { CreateMessageHook, useRoomEngineEvent } from '../../hooks';
|
||||
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
@ -71,18 +71,17 @@ export const FriendsView: FC<{}> = props =>
|
||||
{
|
||||
setRequests(prevValue =>
|
||||
{
|
||||
const newRequests: MessengerRequest[] = [];
|
||||
const newRequests: MessengerRequest[] = [ ...prevValue ];
|
||||
|
||||
for(const request of prevValue)
|
||||
const index = newRequests.findIndex(request => (request.requesterUserId === userId));
|
||||
|
||||
if(index >= 0)
|
||||
{
|
||||
if(request.requesterUserId !== userId)
|
||||
{
|
||||
newRequests.push(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageHook(new AcceptFriendMessageComposer(request.id));
|
||||
}
|
||||
SendMessageHook(new AcceptFriendMessageComposer(newRequests[index].id));
|
||||
|
||||
dispatchUiEvent(new FriendRequestEvent(FriendRequestEvent.ACCEPTED, userId));
|
||||
|
||||
newRequests.splice(index, 1);
|
||||
}
|
||||
|
||||
return newRequests;
|
||||
@ -97,22 +96,23 @@ export const FriendsView: FC<{}> = props =>
|
||||
{
|
||||
SendMessageHook(new DeclineFriendMessageComposer(true));
|
||||
|
||||
for(const request of prevValue) dispatchUiEvent(new FriendRequestEvent(FriendRequestEvent.DECLINED, request.requesterUserId));
|
||||
|
||||
return [];
|
||||
}
|
||||
else
|
||||
{
|
||||
const newRequests: MessengerRequest[] = [];
|
||||
const newRequests: MessengerRequest[] = [ ...prevValue ];
|
||||
|
||||
for(const request of prevValue)
|
||||
const index = newRequests.findIndex(request => (request.requesterUserId === userId));
|
||||
|
||||
if(index >= 0)
|
||||
{
|
||||
if(request.requesterUserId !== userId)
|
||||
{
|
||||
newRequests.push(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageHook(new DeclineFriendMessageComposer(false, request.id));
|
||||
}
|
||||
SendMessageHook(new DeclineFriendMessageComposer(false, newRequests[index].id));
|
||||
|
||||
dispatchUiEvent(new FriendRequestEvent(FriendRequestEvent.DECLINED, userId));
|
||||
|
||||
newRequests.splice(index, 1);
|
||||
}
|
||||
|
||||
return newRequests;
|
||||
@ -237,10 +237,15 @@ export const FriendsView: FC<{}> = props =>
|
||||
{
|
||||
const newRequests = [ ...prevValue ];
|
||||
|
||||
const newRequest = new MessengerRequest();
|
||||
newRequest.populate(request);
|
||||
const index = newRequests.findIndex(existing => (existing.requesterUserId === request.requesterUserId));
|
||||
|
||||
newRequests.push(newRequest);
|
||||
if(index === -1)
|
||||
{
|
||||
const newRequest = new MessengerRequest();
|
||||
newRequest.populate(request);
|
||||
|
||||
newRequests.push(newRequest);
|
||||
}
|
||||
|
||||
return newRequests;
|
||||
});
|
||||
@ -273,6 +278,20 @@ export const FriendsView: FC<{}> = props =>
|
||||
useUiEvent(FriendsSendFriendRequestEvent.SEND_FRIEND_REQUEST, onFriendsEvent);
|
||||
useUiEvent(FriendsEvent.REQUEST_FRIEND_LIST, onFriendsEvent);
|
||||
|
||||
const onFriendsAcceptFriendRequestEvent = useCallback((event: FriendsAcceptFriendRequestEvent) =>
|
||||
{
|
||||
acceptFriend(event.requestId);
|
||||
}, [ acceptFriend ]);
|
||||
|
||||
useUiEvent(FriendsAcceptFriendRequestEvent.ACCEPT_FRIEND_REQUEST, onFriendsAcceptFriendRequestEvent);
|
||||
|
||||
const onFriendsDeclineFriendRequestEvent = useCallback((event: FriendsDeclineFriendRequestEvent) =>
|
||||
{
|
||||
declineFriend(event.requestId);
|
||||
}, [ declineFriend ]);
|
||||
|
||||
useUiEvent(FriendsDeclineFriendRequestEvent.DECLINE_FRIEND_REQUEST, onFriendsDeclineFriendRequestEvent);
|
||||
|
||||
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||
{
|
||||
const roomSession = GetRoomSession();
|
||||
|
@ -14,9 +14,9 @@ export const FriendsRequestView: FC<FriendsRequestViewProps> = props =>
|
||||
|
||||
return (
|
||||
<NitroCardAccordionSetView headerText={ LocalizeText('friendlist.tab.friendrequests') + ` (${ requests.length })` } isExpanded={ true }>
|
||||
{ requests.map(request =>
|
||||
{ requests.map((request, index) =>
|
||||
{
|
||||
return <FriendsRequestItemView key={ request.requesterUserId } request={ request } />
|
||||
return <FriendsRequestItemView key={ index } request={ request } />
|
||||
}) }
|
||||
<NitroLayoutFlex className="justify-content-center p-1">
|
||||
<NitroLayoutButton size="sm" onClick={ event => declineFriend(-1, true) }>
|
||||
|
@ -1,11 +1,12 @@
|
||||
@import './avatar-info/AvatarInfoWidgetView';
|
||||
@import './chat/ChatWidgetView';
|
||||
@import './chat-input/ChatInputView';
|
||||
@import './choosers/ChooserWidgetView';
|
||||
@import './context-menu/ContextMenu';
|
||||
@import './doorbell/DoorbellWidgetView';
|
||||
@import './friend-request/FriendRequestDialogView';
|
||||
@import './furniture/FurnitureWidgets';
|
||||
@import './infostand/InfoStandWidgetView';
|
||||
@import './object-location/ObjectLocationView';
|
||||
@import './room-tools/RoomToolsWidgetView';
|
||||
@import './choosers/ChooserWidgetView';
|
||||
@import './word-quiz/WordQuizWidgetView';
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPollEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomSessionWordQuizEvent, RoomZoomEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../api';
|
||||
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
|
||||
import { FriendRequestEvent } from '../../../events';
|
||||
import { useRoomEngineEvent, useRoomSessionManagerEvent, useUiEvent } from '../../../hooks';
|
||||
import { NotificationAlertType } from '../../notification-center/common/NotificationAlertType';
|
||||
import { NotificationUtilities } from '../../notification-center/common/NotificationUtilities';
|
||||
import { useRoomContext } from '../context/RoomContext';
|
||||
@ -11,6 +12,7 @@ import { ChatWidgetView } from './chat/ChatWidgetView';
|
||||
import { FurniChooserWidgetView } from './choosers/FurniChooserWidgetView';
|
||||
import { UserChooserWidgetView } from './choosers/UserChooserWidgetView';
|
||||
import { DoorbellWidgetView } from './doorbell/DoorbellWidgetView';
|
||||
import { FriendRequestWidgetView } from './friend-request/FriendRequestWidgetView';
|
||||
import { FurnitureWidgetsView } from './furniture/FurnitureWidgetsView';
|
||||
import { InfoStandWidgetView } from './infostand/InfoStandWidgetView';
|
||||
import { RoomThumbnailWidgetView } from './room-thumbnail/RoomThumbnailWidgetView';
|
||||
@ -275,6 +277,8 @@ export const RoomWidgetsView: FC<{}> = props =>
|
||||
useRoomSessionManagerEvent(RoomSessionPollEvent.OFFER, onRoomSessionEvent);
|
||||
useRoomSessionManagerEvent(RoomSessionPollEvent.ERROR, onRoomSessionEvent);
|
||||
useRoomSessionManagerEvent(RoomSessionPollEvent.CONTENT, onRoomSessionEvent);
|
||||
useUiEvent(FriendRequestEvent.ACCEPTED, onRoomSessionEvent);
|
||||
useUiEvent(FriendRequestEvent.DECLINED, onRoomSessionEvent);
|
||||
|
||||
const onRoomSessionErrorMessageEvent = useCallback((event: RoomSessionErrorMessageEvent) =>
|
||||
{
|
||||
@ -357,6 +361,7 @@ export const RoomWidgetsView: FC<{}> = props =>
|
||||
<FurniChooserWidgetView />
|
||||
<UserChooserWidgetView />
|
||||
<WordQuizWidgetView />
|
||||
<FriendRequestWidgetView />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,4 @@
|
||||
.nitro-friend-request-dialog {
|
||||
width: unset;
|
||||
max-width: 200px;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText, RoomWidgetFriendRequestMessage } from '../../../../api';
|
||||
import { NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn } from '../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../layout/base';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { UserLocationView } from '../user-location/UserLocationView';
|
||||
import { FriendRequestDialogViewProps } from './FriendRequestDialogView.types';
|
||||
|
||||
export const FriendRequestDialogView: FC<FriendRequestDialogViewProps> = props =>
|
||||
{
|
||||
const { requestId = -1, userId = -1, userName = null, close = null } = props;
|
||||
const { widgetHandler = null } = useRoomContext();
|
||||
|
||||
const accept = useCallback(() =>
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFriendRequestMessage(RoomWidgetFriendRequestMessage.ACCEPT, requestId));
|
||||
|
||||
close();
|
||||
}, [ requestId, widgetHandler, close ]);
|
||||
|
||||
const decline = useCallback(() =>
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFriendRequestMessage(RoomWidgetFriendRequestMessage.ACCEPT, requestId));
|
||||
|
||||
close();
|
||||
}, [ requestId, widgetHandler, close ]);
|
||||
|
||||
return (
|
||||
<UserLocationView userId={ userId }>
|
||||
<NitroLayoutBase className="nitro-friend-request-dialog nitro-context-menu p-2">
|
||||
<NitroLayoutFlexColumn>
|
||||
<NitroLayoutBase className="h6">
|
||||
{ LocalizeText('widget.friendrequest.from', [ 'username' ], [ userName ]) }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutFlex className="justify-content-end align-items-center" gap={ 2 }>
|
||||
<NitroLayoutButton variant="danger" size="sm" onClick={ decline }>
|
||||
{ LocalizeText('widget.friendrequest.decline') }
|
||||
</NitroLayoutButton>
|
||||
<NitroLayoutButton variant="success" size="sm" onClick={ accept }>
|
||||
{ LocalizeText('widget.friendrequest.accept') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlex>
|
||||
</NitroLayoutFlexColumn>
|
||||
</NitroLayoutBase>
|
||||
</UserLocationView>
|
||||
);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
export interface FriendRequestDialogViewProps
|
||||
{
|
||||
requestId: number;
|
||||
userId: number;
|
||||
userName: string;
|
||||
close: () => void;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { RoomWidgetUpdateFriendRequestEvent } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { FriendRequestDialogView } from './FriendRequestDialogView';
|
||||
|
||||
export const FriendRequestWidgetView: FC<{}> = props =>
|
||||
{
|
||||
const [ friendRequests, setFriendRequests ] = useState<{ requestId: number, userId: number, userName: string }[]>([]);
|
||||
const { eventDispatcher = null } = useRoomContext();
|
||||
|
||||
const showFriendRequest = useCallback((requestId: number, userId: number, userName: string) =>
|
||||
{
|
||||
const index = friendRequests.findIndex(value => (value.userId === userId));
|
||||
|
||||
if(index >= 0) return;
|
||||
|
||||
setFriendRequests(prevValue =>
|
||||
{
|
||||
const newValue = [ ...prevValue ];
|
||||
|
||||
newValue.push({ requestId, userId, userName });
|
||||
|
||||
return newValue;
|
||||
});
|
||||
}, [ friendRequests ]);
|
||||
|
||||
const hideFriendRequest = useCallback((requestId: number) =>
|
||||
{
|
||||
const index = friendRequests.findIndex(value => (value.requestId === requestId));
|
||||
|
||||
if(index === -1) return;
|
||||
|
||||
setFriendRequests(prevValue =>
|
||||
{
|
||||
const newValue = [ ...prevValue ];
|
||||
|
||||
newValue.splice(index, 1);
|
||||
|
||||
return newValue;
|
||||
})
|
||||
}, [ friendRequests ]);
|
||||
|
||||
const onRoomWidgetUpdateFriendRequestEvent = useCallback((event: RoomWidgetUpdateFriendRequestEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetUpdateFriendRequestEvent.SHOW_FRIEND_REQUEST:
|
||||
showFriendRequest(event.requestId, event.userId, event.userName);
|
||||
return;
|
||||
case RoomWidgetUpdateFriendRequestEvent.HIDE_FRIEND_REQUEST:
|
||||
hideFriendRequest(event.requestId);
|
||||
return;
|
||||
}
|
||||
}, [ showFriendRequest, hideFriendRequest ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateFriendRequestEvent.SHOW_FRIEND_REQUEST, eventDispatcher, onRoomWidgetUpdateFriendRequestEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateFriendRequestEvent.HIDE_FRIEND_REQUEST, eventDispatcher, onRoomWidgetUpdateFriendRequestEvent);
|
||||
|
||||
if(!friendRequests.length) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{ friendRequests.map((request, index) =>
|
||||
{
|
||||
return <FriendRequestDialogView key={ index } { ...request } close={ () => hideFriendRequest(request.userId) } />
|
||||
}) }
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetNitroInstance, GetRoomEngine, GetRoomSession } from '../../../../api';
|
||||
import { NitroLayoutBase } from '../../../../layout/base';
|
||||
import { ObjectLocationViewProps } from './ObjectLocationView.types';
|
||||
|
||||
export const ObjectLocationView: FC<ObjectLocationViewProps> = props =>
|
||||
{
|
||||
const { objectId = -1, category = -1, noFollow = false, children = null } = props;
|
||||
const { objectId = -1, category = -1, noFollow = false, children = null, ...rest } = props;
|
||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1 });
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
@ -50,8 +51,8 @@ export const ObjectLocationView: FC<ObjectLocationViewProps> = props =>
|
||||
}, [ updatePosition, noFollow ]);
|
||||
|
||||
return (
|
||||
<div ref={ elementRef } className={ 'object-location position-absolute ' + ( (pos.x + (elementRef.current ? elementRef.current.offsetWidth : 0 ) )> -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } }>
|
||||
<NitroLayoutBase innerRef={ elementRef } className={ 'object-location position-absolute ' + ( (pos.x + (elementRef.current ? elementRef.current.offsetWidth : 0 ) )> -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } } { ...rest }>
|
||||
{ children }
|
||||
</div>
|
||||
</NitroLayoutBase>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
export interface ObjectLocationViewProps
|
||||
import { NitroLayoutBaseProps } from '../../../../layout/base';
|
||||
|
||||
export interface ObjectLocationViewProps extends NitroLayoutBaseProps
|
||||
{
|
||||
objectId: number;
|
||||
category: number;
|
||||
|
19
src/views/room/widgets/user-location/UserLocationView.tsx
Normal file
19
src/views/room/widgets/user-location/UserLocationView.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { ObjectLocationView } from '../object-location/ObjectLocationView';
|
||||
import { UserLocationViewProps } from './UserLocationView.types';
|
||||
|
||||
export const UserLocationView: FC<UserLocationViewProps> = props =>
|
||||
{
|
||||
const { userId = -1, ...rest } = props;
|
||||
const { roomSession = null } = useRoomContext();
|
||||
|
||||
if((userId === -1) || !roomSession) return null;
|
||||
|
||||
const userData = roomSession.userDataManager.getUserData(userId);
|
||||
|
||||
if(!userData) return null;
|
||||
|
||||
return <ObjectLocationView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } { ...rest } />;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { NitroLayoutBaseProps } from '../../../../layout/base';
|
||||
|
||||
export interface UserLocationViewProps extends NitroLayoutBaseProps
|
||||
{
|
||||
userId: number;
|
||||
}
|
Loading…
Reference in New Issue
Block a user