Add doorbell room widget

This commit is contained in:
Bill 2021-08-13 04:05:46 -04:00
parent 51558c4f3c
commit dc628d605b
10 changed files with 226 additions and 0 deletions

View File

@ -7,6 +7,7 @@ import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
import { RoomContextProvider } from './context/RoomContext'; import { RoomContextProvider } from './context/RoomContext';
import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent'; import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent';
import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
import { DoorbellWidgetHandler } from './handlers/DoorbellWidgetHandler';
import { FurnitureContextMenuWidgetHandler } from './handlers/FurnitureContextMenuWidgetHandler'; import { FurnitureContextMenuWidgetHandler } from './handlers/FurnitureContextMenuWidgetHandler';
import { FurnitureCustomStackHeightWidgetHandler } from './handlers/FurnitureCustomStackHeightWidgetHandler'; import { FurnitureCustomStackHeightWidgetHandler } from './handlers/FurnitureCustomStackHeightWidgetHandler';
import { RoomWidgetRoomToolsHandler } from './handlers/RoomWidgetRoomToolsHandler'; import { RoomWidgetRoomToolsHandler } from './handlers/RoomWidgetRoomToolsHandler';
@ -44,6 +45,7 @@ export const RoomView: FC<RoomViewProps> = props =>
widgetHandlerManager.registerHandler(new RoomWidgetChatHandler()); widgetHandlerManager.registerHandler(new RoomWidgetChatHandler());
widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler()); widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler());
widgetHandlerManager.registerHandler(new FurnitureCustomStackHeightWidgetHandler()); widgetHandlerManager.registerHandler(new FurnitureCustomStackHeightWidgetHandler());
widgetHandlerManager.registerHandler(new DoorbellWidgetHandler());
setWidgetHandler(widgetHandlerManager); setWidgetHandler(widgetHandlerManager);

View File

@ -0,0 +1,22 @@
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
export class RoomWidgetDoorbellEvent extends RoomWidgetUpdateEvent
{
public static RINGING: string = 'RWDE_RINGING';
public static REJECTED: string = 'RWDE_REJECTED';
public static ACCEPTED: string = 'RWDE_ACCEPTED';
private _userName: string = '';
constructor(type: string, userName: string)
{
super(type);
this._userName = userName;
}
public get userName(): string
{
return this._userName;
}
}

View File

@ -1,4 +1,5 @@
export * from './RoomWidgetAvatarInfoEvent'; export * from './RoomWidgetAvatarInfoEvent';
export * from './RoomWidgetDoorbellEvent';
export * from './RoomWidgetFloodControlEvent'; export * from './RoomWidgetFloodControlEvent';
export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetObjectNameEvent';
export * from './RoomWidgetRoomEngineUpdateEvent'; export * from './RoomWidgetRoomEngineUpdateEvent';

View File

@ -0,0 +1,60 @@
import { NitroEvent, RoomSessionDoorbellEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer';
import { RoomWidgetDoorbellEvent, RoomWidgetUpdateEvent } from '../events';
import { RoomWidgetLetUserInMessage, RoomWidgetMessage } from '../messages';
import { RoomWidgetHandler } from './RoomWidgetHandler';
export class DoorbellWidgetHandler extends RoomWidgetHandler
{
public processEvent(event: NitroEvent): void
{
const doorbellEvent = (event as RoomSessionDoorbellEvent);
switch(event.type)
{
case RoomSessionDoorbellEvent.DOORBELL:
this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.RINGING, doorbellEvent.userName));
return;
case RoomSessionDoorbellEvent.RSDE_REJECTED:
this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.REJECTED, doorbellEvent.userName));
return;
case RoomSessionDoorbellEvent.RSDE_ACCEPTED:
this.container.eventDispatcher.dispatchEvent(new RoomWidgetDoorbellEvent(RoomWidgetDoorbellEvent.ACCEPTED, doorbellEvent.userName));
return;
}
}
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
{
switch(message.type)
{
case RoomWidgetLetUserInMessage.LET_USER_IN:
const letUserInMessage = (message as RoomWidgetLetUserInMessage);
this.container.roomSession.sendDoorbellApprovalMessage(letUserInMessage.userName, letUserInMessage.canEnter);
break;
}
return null;
}
public get type(): string
{
return RoomWidgetEnum.DOORBELL;
}
public get eventTypes(): string[]
{
return [
RoomSessionDoorbellEvent.DOORBELL,
RoomSessionDoorbellEvent.RSDE_REJECTED,
RoomSessionDoorbellEvent.RSDE_ACCEPTED
];
}
public get messageTypes(): string[]
{
return [
RoomWidgetLetUserInMessage.LET_USER_IN
];
}
}

View File

@ -0,0 +1,27 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetLetUserInMessage extends RoomWidgetMessage
{
public static LET_USER_IN: string = 'RWLUIM_LET_USER_IN';
private _userName: string;
private _canEnter: boolean;
constructor(userName: string, canEnter: boolean)
{
super(RoomWidgetLetUserInMessage.LET_USER_IN);
this._userName = userName;
this._canEnter = canEnter;
}
public get userName(): string
{
return this._userName;
}
public get canEnter(): boolean
{
return this._canEnter;
}
}

View File

@ -7,6 +7,7 @@ export * from './RoomWidgetChatTypingMessage';
export * from './RoomWidgetDanceMessage'; export * from './RoomWidgetDanceMessage';
export * from './RoomWidgetFurniActionMessage'; export * from './RoomWidgetFurniActionMessage';
export * from './RoomWidgetFurniToWidgetMessage'; export * from './RoomWidgetFurniToWidgetMessage';
export * from './RoomWidgetLetUserInMessage';
export * from './RoomWidgetMessage'; export * from './RoomWidgetMessage';
export * from './RoomWidgetRequestWidgetMessage'; export * from './RoomWidgetRequestWidgetMessage';
export * from './RoomWidgetRoomObjectMessage'; export * from './RoomWidgetRoomObjectMessage';

View File

@ -3,6 +3,7 @@
@import './chat/ChatWidgetView'; @import './chat/ChatWidgetView';
@import './chat-input/ChatInputView'; @import './chat-input/ChatInputView';
@import './context-menu/ContextMenu'; @import './context-menu/ContextMenu';
@import './doorbell/DoorbellWidgetView';
@import './furniture/FurnitureWidgets'; @import './furniture/FurnitureWidgets';
@import './infostand/InfoStandWidgetView'; @import './infostand/InfoStandWidgetView';
@import './object-location/ObjectLocationView'; @import './object-location/ObjectLocationView';

View File

@ -9,6 +9,7 @@ import { AvatarInfoWidgetView } from './avatar-info/AvatarInfoWidgetView';
import { CameraWidgetView } from './camera/CameraWidgetView'; import { CameraWidgetView } from './camera/CameraWidgetView';
import { ChatInputView } from './chat-input/ChatInputView'; import { ChatInputView } from './chat-input/ChatInputView';
import { ChatWidgetView } from './chat/ChatWidgetView'; import { ChatWidgetView } from './chat/ChatWidgetView';
import { DoorbellWidgetView } from './doorbell/DoorbellWidgetView';
import { FurnitureWidgetsView } from './furniture/FurnitureWidgetsView'; import { FurnitureWidgetsView } from './furniture/FurnitureWidgetsView';
import { InfoStandWidgetView } from './infostand/InfoStandWidgetView'; import { InfoStandWidgetView } from './infostand/InfoStandWidgetView';
import { RoomThumbnailWidgetView } from './room-thumbnail/RoomThumbnailWidgetView'; import { RoomThumbnailWidgetView } from './room-thumbnail/RoomThumbnailWidgetView';
@ -242,6 +243,7 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
<CameraWidgetView /> <CameraWidgetView />
<ChatWidgetView /> <ChatWidgetView />
<ChatInputView /> <ChatInputView />
<DoorbellWidgetView />
<FurnitureWidgetsView /> <FurnitureWidgetsView />
<InfoStandWidgetView /> <InfoStandWidgetView />
<RoomToolsWidgetView /> <RoomToolsWidgetView />

View File

@ -0,0 +1,22 @@
.nitro-widget-doorbell {
width: 250px;
.content-area {
min-height: 143px;
height: 143px;
}
.doorbell-user-list {
.list-item {
background: $grid-active-bg-color;
}
.col:nth-child(even) {
.list-item {
background: $white !important;
}
}
}
}

View File

@ -0,0 +1,88 @@
import { FC, useCallback, useState } from 'react';
import { CreateEventDispatcherHook } from '../../../../hooks';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
import { LocalizeText } from '../../../../utils';
import { useRoomContext } from '../../context/RoomContext';
import { RoomWidgetDoorbellEvent } from '../../events';
import { RoomWidgetLetUserInMessage } from '../../messages';
export const DoorbellWidgetView: FC<{}> = props =>
{
const [ isVisible, setIsVisible ] = useState(false);
const [ users, setUsers ] = useState<string[]>([]);
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
const addUser = useCallback((userName: string) =>
{
if(users.indexOf(userName) >= 0) return;
const newUsers = [ ...users, userName ];
setUsers(newUsers);
setIsVisible(true);
}, [ users ]);
const removeUser = useCallback((userName: string) =>
{
const index = users.indexOf(userName);
if(index === -1) return;
const newUsers = [ ...users ];
newUsers.splice(index, 1);
setUsers(newUsers);
if(!newUsers.length) setIsVisible(false);
}, [ users ]);
const onRoomWidgetDoorbellEvent = useCallback((event: RoomWidgetDoorbellEvent) =>
{
switch(event.type)
{
case RoomWidgetDoorbellEvent.RINGING:
addUser(event.userName);
return;
case RoomWidgetDoorbellEvent.REJECTED:
case RoomWidgetDoorbellEvent.ACCEPTED:
removeUser(event.userName);
return;
}
}, [ addUser, removeUser ]);
CreateEventDispatcherHook(RoomWidgetDoorbellEvent.RINGING, eventDispatcher, onRoomWidgetDoorbellEvent);
CreateEventDispatcherHook(RoomWidgetDoorbellEvent.REJECTED, eventDispatcher, onRoomWidgetDoorbellEvent);
CreateEventDispatcherHook(RoomWidgetDoorbellEvent.ACCEPTED, eventDispatcher, onRoomWidgetDoorbellEvent);
const answer = useCallback((userName: string, flag: boolean) =>
{
widgetHandler.processWidgetMessage(new RoomWidgetLetUserInMessage(userName, flag));
removeUser(userName);
}, [ widgetHandler, removeUser ]);
if(!users.length) return null;
return (
<NitroCardView className="nitro-widget-doorbell" simple={ true }>
<NitroCardHeaderView headerText={ LocalizeText('navigator.doorbell.title') } onCloseClick={ event => setIsVisible(false) } />
<NitroCardContentView>
<div className="row row-cols-1 doorbell-user-list">
{ (users.length > 0) && users.map(userName =>
{
return (
<div className="d-flex col align-items-center justify-content-between" key={ userName }>
<span className="fw-bold text-black">{ userName }</span>
<div>
<button type="button" className="btn btn-success btn-sm me-1" onClick={ event => answer(userName, true) }><i className="fas fa-check" /></button>
<button type="button" className="btn btn-danger btn-sm" onClick={ event => answer(userName, false) }><i className="fas fa-times" /></button>
</div>
</div>
);
}) }
</div>
</NitroCardContentView>
</NitroCardView>
);
}