Add friend name bubbles

This commit is contained in:
Bill 2021-07-07 03:56:11 -04:00
parent eac7794091
commit f6194e7f13
6 changed files with 112 additions and 42 deletions

View File

@ -0,0 +1,11 @@
import { RoomWidgetObjectNameEvent } from '../../views/room/events';
export class FriendEnteredRoomEvent extends RoomWidgetObjectNameEvent
{
public static ENTERED: string = 'FERE_ENTERED';
constructor(roomIndex: number, category: number, id: number, name: string, userType: number)
{
super(FriendEnteredRoomEvent.ENTERED, roomIndex, category, id, name, userType);
}
}

View File

@ -1 +1,2 @@
export * from './FriendEnteredRoomEvent';
export * from './FriendListEvent'; export * from './FriendListEvent';

View File

@ -1,8 +1,10 @@
import { MessengerInitComposer } from 'nitro-renderer'; import { MessengerInitComposer, RoomEngineObjectEvent, RoomObjectCategory } from 'nitro-renderer';
import React, { FC, useCallback, useEffect, useReducer, useState } from 'react'; import React, { FC, useCallback, useEffect, useReducer, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { FriendListEvent } from '../../events'; import { GetRoomSession } from '../../api';
import { useUiEvent } from '../../hooks/events/ui/ui-event'; import { FriendEnteredRoomEvent, FriendListEvent } from '../../events';
import { useRoomEngineEvent } from '../../hooks/events';
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
import { SendMessageHook } from '../../hooks/messages/message-event'; import { SendMessageHook } from '../../hooks/messages/message-event';
import { NitroCardAccordionItemView, NitroCardAccordionView, NitroCardHeaderView, NitroCardView } from '../../layout'; import { NitroCardAccordionItemView, NitroCardAccordionView, NitroCardHeaderView, NitroCardView } from '../../layout';
import { LocalizeText } from '../../utils/LocalizeText'; import { LocalizeText } from '../../utils/LocalizeText';
@ -48,6 +50,30 @@ export const FriendListView: FC<FriendListViewProps> = props =>
SendMessageHook(new MessengerInitComposer()); SendMessageHook(new MessengerInitComposer());
}, []); }, []);
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
{
const roomSession = GetRoomSession();
if(!roomSession) return;
if(event.category !== RoomObjectCategory.UNIT) return;
const userData = roomSession.userDataManager.getUserDataByIndex(event.objectId);
if(!userData) return;
const friend = friendListState.friends.find(friend =>
{
return (friend.id === userData.webID);
});
if(!friend) return;
dispatchUiEvent(new FriendEnteredRoomEvent(userData.roomIndex, RoomObjectCategory.UNIT, userData.webID, userData.name, userData.type));
}, [ friendListState.friends ]);
useRoomEngineEvent(RoomEngineObjectEvent.ADDED, onRoomEngineObjectEvent);
return ( return (
<FriendListContextProvider value={ { friendListState, dispatchFriendListState } }> <FriendListContextProvider value={ { friendListState, dispatchFriendListState } }>
<FriendListMessageHandler /> <FriendListMessageHandler />

View File

@ -10,9 +10,9 @@ export class RoomWidgetObjectNameEvent extends RoomWidgetUpdateEvent
private _name: string; private _name: string;
private _userType: number; private _userType: number;
constructor(roomIndex: number, category: number, id: number, name: string, userType: number) constructor(type: string, roomIndex: number, category: number, id: number, name: string, userType: number)
{ {
super(RoomWidgetObjectNameEvent.TYPE); super(type);
this._roomIndex = roomIndex; this._roomIndex = roomIndex;
this._category = category; this._category = category;

View File

@ -286,7 +286,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
} }
} }
if(name) this.container.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(message.id, message.category, id, name, userType)); if(name) this.container.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(RoomWidgetObjectNameEvent.TYPE, message.id, message.category, id, name, userType));
return null; return null;
} }

View File

@ -1,6 +1,8 @@
import { RoomEnterEffect, RoomObjectCategory } from 'nitro-renderer'; import { RoomEnterEffect, RoomObjectCategory } from 'nitro-renderer';
import { FC, useCallback, useMemo, useState } from 'react'; import { FC, useCallback, useMemo, useState } from 'react';
import { GetRoomSession, GetSessionDataManager } from '../../../../api'; import { GetRoomSession, GetSessionDataManager } from '../../../../api';
import { FriendEnteredRoomEvent } from '../../../../events';
import { useUiEvent } from '../../../../hooks/events';
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base'; import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events'; import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events';
@ -19,12 +21,35 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{ {
const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
const [ name, setName ] = useState<RoomWidgetObjectNameEvent>(null); const [ name, setName ] = useState<RoomWidgetObjectNameEvent>(null);
const [ nameBubbles, setNameBubbles ] = useState<RoomWidgetObjectNameEvent[]>([]);
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null); const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
const [ isGameMode, setGameMode ] = useState(false); const [ isGameMode, setGameMode ] = useState(false);
const [ isDancing, setIsDancing ] = useState(false); const [ isDancing, setIsDancing ] = useState(false);
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating); const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null); const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
const removeNameBubble = useCallback((index: number) =>
{
setNameBubbles(prevValue =>
{
const newValue = [ ...prevValue ];
newValue.splice(index, 1);
return newValue;
});
}, []);
const clearInfoStandEvent = useCallback(() =>
{
setInfoStandEvent(null);
}, []);
const clearName = useCallback(() =>
{
setName(null);
}, []);
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) => const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
{ {
switch(event.type) switch(event.type)
@ -50,6 +75,16 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
if(event.id === name.id) setName(null); if(event.id === name.id) setName(null);
} }
if(event.category === RoomObjectCategory.UNIT)
{
const nameBubbleIndex = nameBubbles.findIndex(bubble =>
{
return (bubble.roomIndex === event.id);
});
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
}
if(infoStandEvent) if(infoStandEvent)
{ {
if(infoStandEvent instanceof RoomWidgetUpdateInfostandFurniEvent) if(infoStandEvent instanceof RoomWidgetUpdateInfostandFurniEvent)
@ -67,7 +102,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null); if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
} }
} }
}, [ name, infoStandEvent ]); }, [ name, infoStandEvent, nameBubbles, removeNameBubble ]);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved); CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved); CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
@ -104,8 +139,6 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
{ {
if(!infoStandEvent) return; if(!infoStandEvent) return;
console.log('tru')
setInfoStandEvent(null); setInfoStandEvent(null);
}, [ infoStandEvent ]); }, [ infoStandEvent ]);
@ -142,26 +175,6 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
CreateEventDispatcherHook(RoomWidgetUpdateDanceStatusEvent.UPDATE_DANCE, eventDispatcher, onRoomWidgetUpdateDanceStatusEvent); CreateEventDispatcherHook(RoomWidgetUpdateDanceStatusEvent.UPDATE_DANCE, eventDispatcher, onRoomWidgetUpdateDanceStatusEvent);
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
{
switch(event.type)
{
case RoomWidgetRoomObjectUpdateEvent.USER_ADDED: {
// bubble if friend
return;
}
case RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED: {
// set if waiting for pet
return;
}
}
}, []);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) => const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) =>
{ {
setRentableBotChatEvent(event); setRentableBotChatEvent(event);
@ -169,6 +182,16 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent); CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
const onFriendEnteredRoomEvent = useCallback((event: FriendEnteredRoomEvent) =>
{
setNameBubbles(prevValue =>
{
return [ ...prevValue, event ];
})
}, []);
useUiEvent(FriendEnteredRoomEvent.ENTERED, onFriendEnteredRoomEvent);
const decorateView = useMemo(() => const decorateView = useMemo(() =>
{ {
GetRoomSession().isDecorating = isDecorating; GetRoomSession().isDecorating = isDecorating;
@ -182,23 +205,23 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
return <AvatarInfoWidgetDecorateView userId={ userId } userName={ userName } roomIndex={ roomIndex } setIsDecorating={ setIsDecorating } />; return <AvatarInfoWidgetDecorateView userId={ userId } userName={ userName } roomIndex={ roomIndex } setIsDecorating={ setIsDecorating } />;
}, [ isDecorating ]); }, [ isDecorating ]);
const clearInfoStandEvent = useCallback(() =>
{
setInfoStandEvent(null);
}, []);
const clearName = useCallback(() =>
{
setName(null);
}, []);
const currentView = useMemo(() => const currentView = useMemo(() =>
{ {
if(isGameMode) return null; if(isGameMode) return null;
if(decorateView) return decorateView; if(decorateView) return decorateView;
if(name) return <AvatarInfoWidgetNameView nameData={ name } close={ clearName } />; if(name)
{
const nameBubbleIndex = nameBubbles.findIndex(bubble =>
{
return (bubble.roomIndex === name.roomIndex);
});
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
return <AvatarInfoWidgetNameView nameData={ name } close={ clearName } />;
}
if(infoStandEvent) if(infoStandEvent)
{ {
@ -210,7 +233,12 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
if(event.isSpectatorMode) return null; if(event.isSpectatorMode) return null;
// if existing name bubble remove it const nameBubbleIndex = nameBubbles.findIndex(bubble =>
{
return (bubble.roomIndex === event.roomIndex);
});
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
if(event.isOwnUser) if(event.isOwnUser)
{ {
@ -241,11 +269,15 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
} }
return null; return null;
}, [ isGameMode, decorateView, name, isDancing, infoStandEvent, clearName, clearInfoStandEvent ]); }, [ isGameMode, decorateView, name, nameBubbles, isDancing, infoStandEvent, clearName, clearInfoStandEvent, removeNameBubble ]);
return ( return (
<> <>
{ currentView } { currentView }
{ (nameBubbles.length > 0) && nameBubbles.map((name, index) =>
{
return <AvatarInfoWidgetNameView nameData={ name } close={ () => removeNameBubble(index) } />;
}) }
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> } { rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
</> </>
) )