mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
Merge branch 'dev' into feature/user-profile
This commit is contained in:
commit
81b306ea94
18
package-lock.json
generated
18
package-lock.json
generated
@ -5919,6 +5919,11 @@
|
|||||||
"wrap-ansi": "^6.2.0"
|
"wrap-ansi": "^6.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"clsx": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA=="
|
||||||
|
},
|
||||||
"co": {
|
"co": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||||
@ -14876,6 +14881,19 @@
|
|||||||
"prop-types": "^15.6.2"
|
"prop-types": "^15.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-virtualized": {
|
||||||
|
"version": "9.22.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.3.tgz",
|
||||||
|
"integrity": "sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.7.2",
|
||||||
|
"clsx": "^1.0.4",
|
||||||
|
"dom-helpers": "^5.1.3",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"react-lifecycles-compat": "^3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"react-slider": "^1.3.1",
|
"react-slider": "^1.3.1",
|
||||||
"react-transition-group": "^4.4.2",
|
"react-transition-group": "^4.4.2",
|
||||||
|
"react-virtualized": "^9.22.3",
|
||||||
"typescript": "^4.3.5",
|
"typescript": "^4.3.5",
|
||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ConfigurationEvent, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, RoomEngineEvent, WebGL } from '@nitrots/nitro-renderer';
|
import { ConfigurationEvent, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent, WebGL } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { GetCommunication, GetConfiguration, GetNitroInstance } from './api';
|
import { GetCommunication, GetConfiguration, GetNitroInstance } from './api';
|
||||||
import { useConfigurationEvent } from './hooks/events/core/configuration/configuration-event';
|
import { useConfigurationEvent } from './hooks/events/core/configuration/configuration-event';
|
||||||
@ -17,7 +17,11 @@ export const App: FC<{}> = props =>
|
|||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||||
|
|
||||||
if(!GetNitroInstance()) Nitro.bootstrap();
|
if(!GetNitroInstance())
|
||||||
|
{
|
||||||
|
NitroVersion.UI_VERSION = '2.0.0';
|
||||||
|
Nitro.bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
const getPreloadAssetUrls = useCallback(() =>
|
const getPreloadAssetUrls = useCallback(() =>
|
||||||
{
|
{
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { GetRoomSessionManager } from '../nitro';
|
|
||||||
|
|
||||||
export function VisitRoom(roomId: number, password: string = null): void
|
|
||||||
{
|
|
||||||
GetRoomSessionManager().createSession(roomId, password);
|
|
||||||
}
|
|
6
src/api/nitro/session/CreateRoomSession.ts
Normal file
6
src/api/nitro/session/CreateRoomSession.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { GetRoomSessionManager } from './GetRoomSessionManager';
|
||||||
|
|
||||||
|
export function CreateRoomSession(roomId: number, password: string = null): void
|
||||||
|
{
|
||||||
|
GetRoomSessionManager().createSession(roomId, password);
|
||||||
|
}
|
7
src/api/nitro/session/GoToDesktop.ts
Normal file
7
src/api/nitro/session/GoToDesktop.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { DesktopViewComposer } from '@nitrots/nitro-renderer';
|
||||||
|
import { SendMessageHook } from '../../../hooks';
|
||||||
|
|
||||||
|
export function GoToDesktop(): void
|
||||||
|
{
|
||||||
|
SendMessageHook(new DesktopViewComposer());
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export * from './CanManipulateFurniture';
|
export * from './CanManipulateFurniture';
|
||||||
|
export * from './CreateRoomSession';
|
||||||
export * from './GetCanStandUp';
|
export * from './GetCanStandUp';
|
||||||
export * from './GetCanUseExpression';
|
export * from './GetCanUseExpression';
|
||||||
export * from './GetClubMemberLevel';
|
export * from './GetClubMemberLevel';
|
||||||
@ -9,6 +10,7 @@ export * from './GetProductDataForLocalization';
|
|||||||
export * from './GetRoomSession';
|
export * from './GetRoomSession';
|
||||||
export * from './GetRoomSessionManager';
|
export * from './GetRoomSessionManager';
|
||||||
export * from './GetSessionDataManager';
|
export * from './GetSessionDataManager';
|
||||||
|
export * from './GoToDesktop';
|
||||||
export * from './HasHabboClub';
|
export * from './HasHabboClub';
|
||||||
export * from './HasHabboVip';
|
export * from './HasHabboVip';
|
||||||
export * from './IsOwnerOfFurniture';
|
export * from './IsOwnerOfFurniture';
|
||||||
|
27
src/events/navigator/UpdateDoorStateEvent.ts
Normal file
27
src/events/navigator/UpdateDoorStateEvent.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { NitroEvent, RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export class UpdateDoorStateEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static START_DOORBELL: string = 'UDSE_START_DOORBELL';
|
||||||
|
public static START_PASSWORD: string = 'UDSE_START_PASSWORD';
|
||||||
|
public static STATE_PENDING_SERVER: string = 'UDSE_STATE_PENDING_SERVER';
|
||||||
|
public static UPDATE_STATE: string = 'UDSE_UPDATE_STATE';
|
||||||
|
public static STATE_WAITING: string = 'UDSE_STATE_WAITING';
|
||||||
|
public static STATE_NO_ANSWER: string = 'UDSE_STATE_NO_ANSWER';
|
||||||
|
public static STATE_WRONG_PASSWORD: string = 'UDSE_STATE_WRONG_PASSWORD';
|
||||||
|
public static STATE_ACCEPTED: string = 'UDSE_STATE_ACCEPTED';
|
||||||
|
|
||||||
|
private _roomData: RoomDataParser
|
||||||
|
|
||||||
|
constructor(type: string, roomData: RoomDataParser = null)
|
||||||
|
{
|
||||||
|
super(type);
|
||||||
|
|
||||||
|
this._roomData = roomData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get roomData(): RoomDataParser
|
||||||
|
{
|
||||||
|
return this._roomData;
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
export * from './NavigatorEvent';
|
export * from './NavigatorEvent';
|
||||||
|
export * from './UpdateDoorStateEvent';
|
||||||
|
28
src/events/room-widgets/choosers/RoomObjectItem.ts
Normal file
28
src/events/room-widgets/choosers/RoomObjectItem.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export class RoomObjectItem
|
||||||
|
{
|
||||||
|
private readonly _id: number;
|
||||||
|
private readonly _category: number;
|
||||||
|
private readonly _name: string;
|
||||||
|
|
||||||
|
constructor(id: number, category: number, name: string)
|
||||||
|
{
|
||||||
|
this._id = id;
|
||||||
|
this._category = category;
|
||||||
|
this._name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): number
|
||||||
|
{
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get category(): number
|
||||||
|
{
|
||||||
|
return this._category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get name(): string
|
||||||
|
{
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
import { RoomWidgetUpdateEvent } from '../../../views/room/events';
|
||||||
|
import { RoomObjectItem } from './RoomObjectItem';
|
||||||
|
|
||||||
|
export class RoomWidgetChooserContentEvent extends RoomWidgetUpdateEvent
|
||||||
|
{
|
||||||
|
public static USER_CHOOSER_CONTENT: string = 'RWCCE_USER_CHOOSER_CONTENT';
|
||||||
|
public static FURNI_CHOOSER_CONTENT: string = 'RWCCE_FURNI_CHOOSER_CONTENT';
|
||||||
|
|
||||||
|
private _items: RoomObjectItem[];
|
||||||
|
private _isAnyRoomController: boolean;
|
||||||
|
|
||||||
|
constructor(type: string, items: RoomObjectItem[], isAnyRoomController: boolean = false)
|
||||||
|
{
|
||||||
|
super(type);
|
||||||
|
|
||||||
|
this._items = items.slice();
|
||||||
|
this._isAnyRoomController = isAnyRoomController;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get items(): RoomObjectItem[]
|
||||||
|
{
|
||||||
|
return this._items;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isAnyRoomController(): boolean
|
||||||
|
{
|
||||||
|
return this._isAnyRoomController;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
import { GenericErrorEvent, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, RoomSettingsUpdatedEvent, UserInfoEvent } from '@nitrots/nitro-renderer';
|
import { GenericErrorEvent, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, RoomSettingsUpdatedEvent, UserInfoEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { GetRoomSessionManager, GetSessionDataManager } from '../../api';
|
import { CreateRoomSession, GetSessionDataManager } from '../../api';
|
||||||
import { VisitRoom } from '../../api/navigator/VisitRoom';
|
import { UpdateDoorStateEvent } from '../../events';
|
||||||
|
import { dispatchUiEvent } from '../../hooks';
|
||||||
import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { useNavigatorContext } from './context/NavigatorContext';
|
import { useNavigatorContext } from './context/NavigatorContext';
|
||||||
import { NavigatorMessageHandlerProps } from './NavigatorMessageHandler.types';
|
import { NavigatorMessageHandlerProps } from './NavigatorMessageHandler.types';
|
||||||
@ -65,13 +66,15 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
|||||||
switch(parser.data.doorMode)
|
switch(parser.data.doorMode)
|
||||||
{
|
{
|
||||||
case RoomDataParser.DOORBELL_STATE:
|
case RoomDataParser.DOORBELL_STATE:
|
||||||
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.START_DOORBELL, parser.data));
|
||||||
|
return;
|
||||||
case RoomDataParser.PASSWORD_STATE:
|
case RoomDataParser.PASSWORD_STATE:
|
||||||
//showLock();
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.START_PASSWORD, parser.data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetRoomSessionManager().createSession(parser.data.roomId);
|
CreateRoomSession(parser.data.roomId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -91,32 +94,42 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
// if(!parser.userName || (parser.userName.length === 0))
|
if(!parser.userName || (parser.userName.length === 0))
|
||||||
// {
|
{
|
||||||
// showLock(NavigatorLockViewStage.WAITING);
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.STATE_WAITING));
|
||||||
// }
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRoomDoorbellAcceptedEvent = useCallback((event: RoomDoorbellAcceptedEvent) =>
|
const onRoomDoorbellAcceptedEvent = useCallback((event: RoomDoorbellAcceptedEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
// if(!parser.userName || (parser.userName.length === 0))
|
if(!parser.userName || (parser.userName.length === 0))
|
||||||
// {
|
{
|
||||||
// hideLock();
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.STATE_ACCEPTED));
|
||||||
// }
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onRoomDoorbellRejectedEvent = useCallback((event: RoomDoorbellRejectedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser.userName || (parser.userName.length === 0))
|
||||||
|
{
|
||||||
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.STATE_NO_ANSWER));
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onGenericErrorEvent = useCallback((event: GenericErrorEvent) =>
|
const onGenericErrorEvent = useCallback((event: GenericErrorEvent) =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
// switch(parser.errorCode)
|
switch(parser.errorCode)
|
||||||
// {
|
{
|
||||||
// case -100002:
|
case -100002:
|
||||||
// showLock(NavigatorLockViewStage.FAILED);
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.STATE_WRONG_PASSWORD));
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onNavigatorMetadataEvent = useCallback((event: NavigatorMetadataEvent) =>
|
const onNavigatorMetadataEvent = useCallback((event: NavigatorMetadataEvent) =>
|
||||||
@ -159,7 +172,7 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
|||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
|
|
||||||
VisitRoom(parser.roomId);
|
CreateRoomSession(parser.roomId);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onNavigatorHomeRoomEvent = useCallback((event: NavigatorHomeRoomEvent) =>
|
const onNavigatorHomeRoomEvent = useCallback((event: NavigatorHomeRoomEvent) =>
|
||||||
@ -187,6 +200,7 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
|||||||
CreateMessageHook(RoomInfoEvent, onRoomInfoEvent);
|
CreateMessageHook(RoomInfoEvent, onRoomInfoEvent);
|
||||||
CreateMessageHook(RoomDoorbellEvent, onRoomDoorbellEvent);
|
CreateMessageHook(RoomDoorbellEvent, onRoomDoorbellEvent);
|
||||||
CreateMessageHook(RoomDoorbellAcceptedEvent, onRoomDoorbellAcceptedEvent);
|
CreateMessageHook(RoomDoorbellAcceptedEvent, onRoomDoorbellAcceptedEvent);
|
||||||
|
CreateMessageHook(RoomDoorbellRejectedEvent, onRoomDoorbellRejectedEvent);
|
||||||
CreateMessageHook(GenericErrorEvent, onGenericErrorEvent);
|
CreateMessageHook(GenericErrorEvent, onGenericErrorEvent);
|
||||||
CreateMessageHook(NavigatorMetadataEvent, onNavigatorMetadataEvent);
|
CreateMessageHook(NavigatorMetadataEvent, onNavigatorMetadataEvent);
|
||||||
CreateMessageHook(NavigatorSearchEvent, onNavigatorSearchEvent);
|
CreateMessageHook(NavigatorSearchEvent, onNavigatorSearchEvent);
|
||||||
|
@ -8,4 +8,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nitro-navigator-doorbell {
|
||||||
|
width: 250px;
|
||||||
|
|
||||||
|
.content-area {
|
||||||
|
min-height: 143px;
|
||||||
|
height: 143px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-navigator-password {
|
||||||
|
width: 250px;
|
||||||
|
|
||||||
|
.content-area {
|
||||||
|
min-height: 218px;
|
||||||
|
height: 218px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@import './views/NavigatorViews';
|
@import './views/NavigatorViews';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { ILinkEventTracker, NavigatorInitComposer, NavigatorSearchComposer, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
import { ILinkEventTracker, NavigatorInitComposer, NavigatorSearchComposer, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
import { FC, useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
||||||
import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api';
|
import { AddEventLinkTracker, GoToDesktop, RemoveLinkEventTracker } from '../../api';
|
||||||
import { TryVisitRoom } from '../../api/navigator/TryVisitRoom';
|
import { TryVisitRoom } from '../../api/navigator/TryVisitRoom';
|
||||||
import { NavigatorEvent } from '../../events';
|
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events';
|
||||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { SendMessageHook } from '../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||||
@ -13,8 +13,10 @@ import { NavigatorMessageHandler } from './NavigatorMessageHandler';
|
|||||||
import { NavigatorViewProps } from './NavigatorView.types';
|
import { NavigatorViewProps } from './NavigatorView.types';
|
||||||
import { initialNavigator, NavigatorActions, NavigatorReducer } from './reducers/NavigatorReducer';
|
import { initialNavigator, NavigatorActions, NavigatorReducer } from './reducers/NavigatorReducer';
|
||||||
import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView';
|
import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView';
|
||||||
|
import { NavigatorRoomDoorbellView } from './views/room-doorbell/NavigatorRoomDoorbellView';
|
||||||
import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView';
|
import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView';
|
||||||
import { NavigatorRoomLinkView } from './views/room-link/NavigatorRoomLinkView';
|
import { NavigatorRoomLinkView } from './views/room-link/NavigatorRoomLinkView';
|
||||||
|
import { NavigatorRoomPasswordView } from './views/room-password/NavigatorRoomPasswordView';
|
||||||
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
||||||
import { NavigatorSearchResultSetView } from './views/search-result-set/NavigatorSearchResultSetView';
|
import { NavigatorSearchResultSetView } from './views/search-result-set/NavigatorSearchResultSetView';
|
||||||
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
||||||
@ -25,6 +27,7 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
|||||||
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||||
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
||||||
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
||||||
|
const [ pendingDoorState, setPendingDoorState ] = useState<{ roomData: RoomDataParser, state: string }>(null);
|
||||||
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
||||||
const { needsNavigatorUpdate = false, topLevelContext = null, topLevelContexts = null } = navigatorState;
|
const { needsNavigatorUpdate = false, topLevelContext = null, topLevelContexts = null } = navigatorState;
|
||||||
|
|
||||||
@ -56,6 +59,49 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
|||||||
useUiEvent(NavigatorEvent.TOGGLE_ROOM_INFO, onNavigatorEvent);
|
useUiEvent(NavigatorEvent.TOGGLE_ROOM_INFO, onNavigatorEvent);
|
||||||
useUiEvent(NavigatorEvent.TOGGLE_ROOM_LINK, onNavigatorEvent);
|
useUiEvent(NavigatorEvent.TOGGLE_ROOM_LINK, onNavigatorEvent);
|
||||||
|
|
||||||
|
const onUpdateDoorStateEvent = useCallback((event: UpdateDoorStateEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case UpdateDoorStateEvent.START_DOORBELL:
|
||||||
|
setPendingDoorState({ roomData: event.roomData, state: event.type });
|
||||||
|
return;
|
||||||
|
case UpdateDoorStateEvent.START_PASSWORD:
|
||||||
|
setPendingDoorState({ roomData: event.roomData, state: event.type });
|
||||||
|
return;
|
||||||
|
case UpdateDoorStateEvent.STATE_WAITING:
|
||||||
|
setPendingDoorState(prevValue =>
|
||||||
|
{
|
||||||
|
return { roomData: prevValue.roomData, state: event.type }
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
case UpdateDoorStateEvent.STATE_NO_ANSWER:
|
||||||
|
setPendingDoorState(prevValue =>
|
||||||
|
{
|
||||||
|
if(prevValue.state === UpdateDoorStateEvent.STATE_WAITING) GoToDesktop();
|
||||||
|
|
||||||
|
return { roomData: prevValue.roomData, state: event.type }
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
case UpdateDoorStateEvent.STATE_WRONG_PASSWORD:
|
||||||
|
setPendingDoorState(prevValue =>
|
||||||
|
{
|
||||||
|
return { roomData: prevValue.roomData, state: event.type }
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
case UpdateDoorStateEvent.STATE_ACCEPTED:
|
||||||
|
setPendingDoorState(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(UpdateDoorStateEvent.START_DOORBELL, onUpdateDoorStateEvent);
|
||||||
|
useUiEvent(UpdateDoorStateEvent.START_PASSWORD, onUpdateDoorStateEvent);
|
||||||
|
useUiEvent(UpdateDoorStateEvent.STATE_WAITING, onUpdateDoorStateEvent);
|
||||||
|
useUiEvent(UpdateDoorStateEvent.STATE_NO_ANSWER, onUpdateDoorStateEvent);
|
||||||
|
useUiEvent(UpdateDoorStateEvent.STATE_WRONG_PASSWORD, onUpdateDoorStateEvent);
|
||||||
|
useUiEvent(UpdateDoorStateEvent.STATE_ACCEPTED, onUpdateDoorStateEvent);
|
||||||
|
|
||||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
@ -102,6 +148,18 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const closePendingDoorState = useCallback((state: string) =>
|
||||||
|
{
|
||||||
|
if(state !== null)
|
||||||
|
{
|
||||||
|
setPendingDoorState(prevValue =>
|
||||||
|
{
|
||||||
|
return { roomData: prevValue.roomData, state };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else setPendingDoorState(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
const linkTracker: ILinkEventTracker = {
|
const linkTracker: ILinkEventTracker = {
|
||||||
@ -135,9 +193,28 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
|||||||
sendSearch('', topLevelContexts[0].code);
|
sendSearch('', topLevelContexts[0].code);
|
||||||
}, [ topLevelContexts, sendSearch ]);
|
}, [ topLevelContexts, sendSearch ]);
|
||||||
|
|
||||||
|
const getRoomDoorState = useMemo(() =>
|
||||||
|
{
|
||||||
|
if(!pendingDoorState) return null;
|
||||||
|
|
||||||
|
switch(pendingDoorState.state)
|
||||||
|
{
|
||||||
|
case UpdateDoorStateEvent.START_DOORBELL:
|
||||||
|
case UpdateDoorStateEvent.STATE_WAITING:
|
||||||
|
case UpdateDoorStateEvent.STATE_NO_ANSWER:
|
||||||
|
return <NavigatorRoomDoorbellView roomData={ pendingDoorState.roomData } state={ pendingDoorState.state } onClose={ closePendingDoorState } />;
|
||||||
|
case UpdateDoorStateEvent.START_PASSWORD:
|
||||||
|
case UpdateDoorStateEvent.STATE_WRONG_PASSWORD:
|
||||||
|
return <NavigatorRoomPasswordView roomData={ pendingDoorState.roomData } state={ pendingDoorState.state } onClose={ closePendingDoorState } />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}, [ pendingDoorState, closePendingDoorState ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavigatorContextProvider value={ { navigatorState, dispatchNavigatorState } }>
|
<NavigatorContextProvider value={ { navigatorState, dispatchNavigatorState } }>
|
||||||
<NavigatorMessageHandler />
|
<NavigatorMessageHandler />
|
||||||
|
{ getRoomDoorState }
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
<NitroCardView uniqueKey="navigator" className="nitro-navigator">
|
<NitroCardView uniqueKey="navigator" className="nitro-navigator">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') } onCloseClick={ event => setIsVisible(false) } />
|
<NitroCardHeaderView headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') } onCloseClick={ event => setIsVisible(false) } />
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
import { FC, useCallback } from 'react';
|
||||||
|
import { CreateRoomSession, GoToDesktop } from '../../../../api';
|
||||||
|
import { UpdateDoorStateEvent } from '../../../../events';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { LocalizeText } from '../../../../utils';
|
||||||
|
import { NavigatorRoomDoorbellViewProps } from './NavigatorRoomDoorbellView.types';
|
||||||
|
|
||||||
|
export const NavigatorRoomDoorbellView: FC<NavigatorRoomDoorbellViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { roomData = null, state = null, onClose = null } = props;
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(state === UpdateDoorStateEvent.STATE_WAITING) GoToDesktop();
|
||||||
|
|
||||||
|
onClose(null);
|
||||||
|
}, [ state, onClose ]);
|
||||||
|
|
||||||
|
const ring = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(!roomData) return;
|
||||||
|
|
||||||
|
CreateRoomSession(roomData.roomId);
|
||||||
|
|
||||||
|
onClose(UpdateDoorStateEvent.STATE_PENDING_SERVER);
|
||||||
|
}, [ roomData, onClose ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-navigator-doorbell" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('navigator.doorbell.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView className="text-black d-flex flex-column">
|
||||||
|
{ roomData && <span className="fw-bold">{ roomData.roomName }</span> }
|
||||||
|
{ (state === UpdateDoorStateEvent.START_DOORBELL) && <span>{ LocalizeText('navigator.doorbell.info') }</span> }
|
||||||
|
{ (state === UpdateDoorStateEvent.STATE_WAITING) && <span>{ LocalizeText('navigator.doorbell.waiting') }</span> }
|
||||||
|
{ (state === UpdateDoorStateEvent.STATE_NO_ANSWER) && <span>{ LocalizeText('navigator.doorbell.no.answer') }</span> }
|
||||||
|
<div className="d-flex flex-column mt-1">
|
||||||
|
{ (state === UpdateDoorStateEvent.START_DOORBELL) && <button type="button" className="btn btn-success btn-sm" onClick={ ring }>{ LocalizeText('navigator.doorbell.button.ring') }</button> }
|
||||||
|
<button type="button" className="btn btn-danger btn-sm mt-1" onClick={ close }>{ LocalizeText('generic.cancel') }</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export interface NavigatorRoomDoorbellViewProps
|
||||||
|
{
|
||||||
|
roomData: RoomDataParser;
|
||||||
|
state: string;
|
||||||
|
onClose: (state: string) => void;
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { CreateRoomSession } from '../../../../api';
|
||||||
|
import { UpdateDoorStateEvent } from '../../../../events';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { LocalizeText } from '../../../../utils';
|
||||||
|
import { NavigatorRoomPasswordViewProps } from './NavigatorRoomPasswordView.types';
|
||||||
|
|
||||||
|
export const NavigatorRoomPasswordView: FC<NavigatorRoomPasswordViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { roomData = null, state = null, onClose = null } = props;
|
||||||
|
const [ password, setPassword ] = useState('');
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
onClose(null);
|
||||||
|
}, [ onClose ]);
|
||||||
|
|
||||||
|
const tryEntering = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(!roomData) return;
|
||||||
|
|
||||||
|
CreateRoomSession(roomData.roomId, password);
|
||||||
|
|
||||||
|
onClose(UpdateDoorStateEvent.STATE_PENDING_SERVER);
|
||||||
|
}, [ roomData, password, onClose ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-navigator-password" simple={ true }>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('navigator.password.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView className="text-black d-flex flex-column">
|
||||||
|
{ roomData && <span className="fw-bold">{ roomData.roomName }</span> }
|
||||||
|
{ (state === UpdateDoorStateEvent.START_PASSWORD) && <span>{ LocalizeText('navigator.password.info') }</span> }
|
||||||
|
{ (state === UpdateDoorStateEvent.STATE_WRONG_PASSWORD) && <span>{ LocalizeText('navigator.password.retryinfo') }</span> }
|
||||||
|
<div className="form-group mt-1">
|
||||||
|
<label>{ LocalizeText('navigator.password.enter') }</label>
|
||||||
|
<input type="password" className="form-control form-control-sm" onChange={ event => setPassword(event.target.value) } />
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-column mt-1">
|
||||||
|
<button type="button" className="btn btn-success btn-sm" onClick={ tryEntering }>{ LocalizeText('navigator.password.button.try') }</button>
|
||||||
|
<button type="button" className="btn btn-danger btn-sm mt-1" onClick={ close }>{ LocalizeText('generic.cancel') }</button>
|
||||||
|
</div>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
|
|
||||||
|
export interface NavigatorRoomPasswordViewProps
|
||||||
|
{
|
||||||
|
roomData: RoomDataParser;
|
||||||
|
state: string;
|
||||||
|
onClose: (state: string) => void;
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FC, MouseEvent } from 'react';
|
import { FC, MouseEvent } from 'react';
|
||||||
|
import { CreateRoomSession, GetSessionDataManager } from '../../../../api';
|
||||||
import { TryVisitRoom } from '../../../../api/navigator/TryVisitRoom';
|
import { TryVisitRoom } from '../../../../api/navigator/TryVisitRoom';
|
||||||
|
import { UpdateDoorStateEvent } from '../../../../events';
|
||||||
|
import { dispatchUiEvent } from '../../../../hooks';
|
||||||
import { NavigatorSearchResultItemViewProps } from './NavigatorSearchResultItemView.types';
|
import { NavigatorSearchResultItemViewProps } from './NavigatorSearchResultItemView.types';
|
||||||
|
|
||||||
export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProps> = props =>
|
export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProps> = props =>
|
||||||
@ -38,7 +41,27 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
|
|
||||||
function visitRoom(): void
|
function visitRoom(): void
|
||||||
{
|
{
|
||||||
TryVisitRoom(roomData.roomId);
|
if(roomData.ownerId !== GetSessionDataManager().userId)
|
||||||
|
{
|
||||||
|
if(roomData.habboGroupId !== 0)
|
||||||
|
{
|
||||||
|
TryVisitRoom(roomData.roomId);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(roomData.doorMode)
|
||||||
|
{
|
||||||
|
case RoomDataParser.DOORBELL_STATE:
|
||||||
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.START_DOORBELL, roomData));
|
||||||
|
return;
|
||||||
|
case RoomDataParser.PASSWORD_STATE:
|
||||||
|
dispatchUiEvent(new UpdateDoorStateEvent(UpdateDoorStateEvent.START_PASSWORD, roomData));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateRoomSession(roomData.roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -58,7 +81,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
|||||||
<i className="fas fa-info-circle text-secondary" onClick={ openInfo }></i>
|
<i className="fas fa-info-circle text-secondary" onClick={ openInfo }></i>
|
||||||
{ roomData.habboGroupId > 0 && <i className="fas fa-users mr-2"></i> }
|
{ roomData.habboGroupId > 0 && <i className="fas fa-users mr-2"></i> }
|
||||||
{ roomData.doorMode !== RoomDataParser.OPEN_STATE &&
|
{ roomData.doorMode !== RoomDataParser.OPEN_STATE &&
|
||||||
<i className={ 'mr-2 fas ' + classNames( {'fa-lock': roomData.doorMode === RoomDataParser.DOORBELL_STATE, 'fa-key': roomData.doorMode === RoomDataParser.PASSWORD_STATE })}></i>
|
<i className={ 'me-2 fas ' + classNames( {'fa-lock': roomData.doorMode === RoomDataParser.DOORBELL_STATE, 'fa-key': roomData.doorMode === RoomDataParser.PASSWORD_STATE })}></i>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,9 +7,12 @@ 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 { FurniChooserWidgetHandler } from './handlers/FurniChooserWidgetHandler';
|
||||||
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';
|
||||||
|
import { UserChooserWidgetHandler } from './handlers/UserChooserWidgetHandler';
|
||||||
import { RoomColorView } from './RoomColorView';
|
import { RoomColorView } from './RoomColorView';
|
||||||
import { RoomViewProps } from './RoomView.types';
|
import { RoomViewProps } from './RoomView.types';
|
||||||
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
||||||
@ -44,6 +47,9 @@ 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 FurniChooserWidgetHandler());
|
||||||
|
widgetHandlerManager.registerHandler(new UserChooserWidgetHandler());
|
||||||
|
widgetHandlerManager.registerHandler(new DoorbellWidgetHandler());
|
||||||
|
|
||||||
setWidgetHandler(widgetHandlerManager);
|
setWidgetHandler(widgetHandlerManager);
|
||||||
|
|
||||||
|
22
src/views/room/events/RoomWidgetDoorbellEvent.ts
Normal file
22
src/views/room/events/RoomWidgetDoorbellEvent.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
60
src/views/room/handlers/DoorbellWidgetHandler.ts
Normal file
60
src/views/room/handlers/DoorbellWidgetHandler.ts
Normal 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
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
115
src/views/room/handlers/FurniChooserWidgetHandler.ts
Normal file
115
src/views/room/handlers/FurniChooserWidgetHandler.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import { NitroEvent, RoomObjectCategory, RoomObjectVariable, RoomWidgetEnum } from '@nitrots/nitro-renderer';
|
||||||
|
import { GetNitroInstance, GetRoomEngine, GetSessionDataManager } from '../../../api';
|
||||||
|
import { RoomObjectItem } from '../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
import { RoomWidgetChooserContentEvent } from '../../../events/room-widgets/choosers/RoomWidgetChooserContentEvent';
|
||||||
|
import { dispatchUiEvent } from '../../../hooks';
|
||||||
|
import { RoomWidgetUpdateEvent } from '../events';
|
||||||
|
import { RoomWidgetMessage, RoomWidgetRequestWidgetMessage, RoomWidgetRoomObjectMessage } from '../messages';
|
||||||
|
import { dynamicSort } from '../widgets/choosers/utils/sorting';
|
||||||
|
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||||
|
|
||||||
|
export class FurniChooserWidgetHandler extends RoomWidgetHandler
|
||||||
|
{
|
||||||
|
public processEvent(event: NitroEvent): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||||
|
{
|
||||||
|
if(!message) return null;
|
||||||
|
|
||||||
|
switch(message.type)
|
||||||
|
{
|
||||||
|
case RoomWidgetRequestWidgetMessage.FURNI_CHOOSER:
|
||||||
|
this.processFurniChooser();
|
||||||
|
break;
|
||||||
|
case RoomWidgetRoomObjectMessage.SELECT_OBJECT:
|
||||||
|
this.selectFurni(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private selectFurni(message: RoomWidgetMessage): void
|
||||||
|
{
|
||||||
|
const event = message as RoomWidgetRoomObjectMessage;
|
||||||
|
|
||||||
|
if(event == null) return;
|
||||||
|
|
||||||
|
if(event.category === RoomObjectCategory.WALL || event.category === RoomObjectCategory.FLOOR)
|
||||||
|
{
|
||||||
|
GetRoomEngine().selectRoomObject(this.container.roomSession.roomId, event.id, event.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private processFurniChooser(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this.container == null || this.container.roomSession == null || GetRoomEngine() == null || this.container.roomSession.userDataManager == null) return;
|
||||||
|
|
||||||
|
const roomId = this.container.roomSession.roomId;
|
||||||
|
const furniInRoom : RoomObjectItem[] = [];
|
||||||
|
|
||||||
|
const wallItems = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.WALL);
|
||||||
|
const floorItems = GetRoomEngine().getRoomObjects(roomId, RoomObjectCategory.FLOOR);
|
||||||
|
|
||||||
|
wallItems.forEach( wallItem => {
|
||||||
|
if(!wallItem) return;
|
||||||
|
|
||||||
|
const type = wallItem.type;
|
||||||
|
let name = null;
|
||||||
|
if(type.startsWith('poster'))
|
||||||
|
{
|
||||||
|
const posterNumber = Number.parseInt(type.replace('poster', ''));
|
||||||
|
name = GetNitroInstance().localization.getValue('poster_' + posterNumber + '_name');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const furniTypeId = Number.parseInt(wallItem.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID));
|
||||||
|
const wallItemData = GetSessionDataManager().getWallItemData(furniTypeId);
|
||||||
|
if(wallItemData != null && wallItemData.name.length > 0)
|
||||||
|
{
|
||||||
|
name = wallItemData.name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
furniInRoom.push(new RoomObjectItem(wallItem.id, RoomObjectCategory.WALL, name));
|
||||||
|
});
|
||||||
|
|
||||||
|
floorItems.forEach(roomObject => {
|
||||||
|
if(!roomObject) return;
|
||||||
|
|
||||||
|
const furniTypeId = Number.parseInt(roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID));
|
||||||
|
const floorItemData = GetSessionDataManager().getFloorItemData(furniTypeId);
|
||||||
|
const name = floorItemData != null ? floorItemData.name : roomObject.type;
|
||||||
|
|
||||||
|
furniInRoom.push(new RoomObjectItem(roomObject.id, RoomObjectCategory.FLOOR, name));
|
||||||
|
});
|
||||||
|
|
||||||
|
furniInRoom.sort(dynamicSort('name'));
|
||||||
|
|
||||||
|
dispatchUiEvent(new RoomWidgetChooserContentEvent(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, furniInRoom, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public get type(): string
|
||||||
|
{
|
||||||
|
return RoomWidgetEnum.FURNI_CHOOSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get eventTypes(): string[]
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public get messageTypes(): string[]
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
RoomWidgetRequestWidgetMessage.FURNI_CHOOSER,
|
||||||
|
RoomWidgetRoomObjectMessage.SELECT_OBJECT
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
88
src/views/room/handlers/UserChooserWidgetHandler.ts
Normal file
88
src/views/room/handlers/UserChooserWidgetHandler.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import { NitroEvent, RoomObjectCategory, RoomWidgetEnum } from '@nitrots/nitro-renderer';
|
||||||
|
import { RoomWidgetHandler } from '.';
|
||||||
|
import { GetRoomEngine } from '../../../api';
|
||||||
|
import { RoomObjectItem } from '../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
import { RoomWidgetChooserContentEvent } from '../../../events/room-widgets/choosers/RoomWidgetChooserContentEvent';
|
||||||
|
import { dispatchUiEvent } from '../../../hooks';
|
||||||
|
import { RoomWidgetUpdateEvent } from '../events';
|
||||||
|
import { RoomWidgetMessage, RoomWidgetRequestWidgetMessage, RoomWidgetRoomObjectMessage } from '../messages';
|
||||||
|
import { dynamicSort } from '../widgets/choosers/utils/sorting';
|
||||||
|
|
||||||
|
export class UserChooserWidgetHandler extends RoomWidgetHandler
|
||||||
|
{
|
||||||
|
public processEvent(event: NitroEvent): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||||
|
{
|
||||||
|
if(!message) return null;
|
||||||
|
|
||||||
|
switch(message.type)
|
||||||
|
{
|
||||||
|
case RoomWidgetRequestWidgetMessage.USER_CHOOSER:
|
||||||
|
this.processUserChooser();
|
||||||
|
break;
|
||||||
|
case RoomWidgetRoomObjectMessage.SELECT_OBJECT:
|
||||||
|
this.selectUnit(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private processUserChooser(): void
|
||||||
|
{
|
||||||
|
|
||||||
|
if(this.container == null || this.container.roomSession == null || GetRoomEngine() == null || this.container.roomSession.userDataManager == null) return;
|
||||||
|
|
||||||
|
const roomId = this.container.roomSession.roomId;
|
||||||
|
const categoryId = RoomObjectCategory.UNIT;
|
||||||
|
const units : RoomObjectItem[] = [];
|
||||||
|
|
||||||
|
const roomObjects = GetRoomEngine().getRoomObjects(roomId, categoryId);
|
||||||
|
|
||||||
|
roomObjects.forEach(roomObject => {
|
||||||
|
if(!roomObject) return;
|
||||||
|
|
||||||
|
const unitData = this.container.roomSession.userDataManager.getUserDataByIndex(roomObject.id);
|
||||||
|
|
||||||
|
if(!unitData) return;
|
||||||
|
|
||||||
|
units.push(new RoomObjectItem(unitData.roomIndex, categoryId, unitData.name));
|
||||||
|
});
|
||||||
|
|
||||||
|
units.sort(dynamicSort('name'));
|
||||||
|
dispatchUiEvent(new RoomWidgetChooserContentEvent(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, units));
|
||||||
|
}
|
||||||
|
|
||||||
|
private selectUnit(k: RoomWidgetMessage): void
|
||||||
|
{
|
||||||
|
const event = k as RoomWidgetRoomObjectMessage;
|
||||||
|
|
||||||
|
if(event == null) return;
|
||||||
|
|
||||||
|
if(event.category === RoomObjectCategory.UNIT)
|
||||||
|
{
|
||||||
|
GetRoomEngine().selectRoomObject(this.container.roomSession.roomId, event.id, event.category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get type(): string
|
||||||
|
{
|
||||||
|
return RoomWidgetEnum.USER_CHOOSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get eventTypes(): string[]
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public get messageTypes(): string[]
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
RoomWidgetRequestWidgetMessage.USER_CHOOSER,
|
||||||
|
RoomWidgetRoomObjectMessage.SELECT_OBJECT
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
27
src/views/room/messages/RoomWidgetLetUserInMessage.ts
Normal file
27
src/views/room/messages/RoomWidgetLetUserInMessage.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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';
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
@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';
|
||||||
@import './room-tools/RoomToolsWidgetView';
|
@import './room-tools/RoomToolsWidgetView';
|
||||||
|
@import './choosers/ChooserWidgetView';
|
||||||
|
@ -9,6 +9,9 @@ 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 { FurniChooserWidgetView } from './choosers/FurniChooserWidgetView';
|
||||||
|
import { UserChooserWidgetView } from './choosers/UserChooserWidgetView';
|
||||||
|
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,10 +245,13 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
|||||||
<CameraWidgetView />
|
<CameraWidgetView />
|
||||||
<ChatWidgetView />
|
<ChatWidgetView />
|
||||||
<ChatInputView />
|
<ChatInputView />
|
||||||
|
<DoorbellWidgetView />
|
||||||
<FurnitureWidgetsView />
|
<FurnitureWidgetsView />
|
||||||
<InfoStandWidgetView />
|
<InfoStandWidgetView />
|
||||||
<RoomToolsWidgetView />
|
<RoomToolsWidgetView />
|
||||||
<RoomThumbnailWidgetView />
|
<RoomThumbnailWidgetView />
|
||||||
|
<FurniChooserWidgetView />
|
||||||
|
<UserChooserWidgetView />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
9
src/views/room/widgets/choosers/ChooserWidgetView.scss
Normal file
9
src/views/room/widgets/choosers/ChooserWidgetView.scss
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.chooser-widget {
|
||||||
|
.selected-item {
|
||||||
|
background-color: cadetblue;
|
||||||
|
}
|
||||||
|
.list-item {
|
||||||
|
color: black;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
87
src/views/room/widgets/choosers/ChooserWidgetView.tsx
Normal file
87
src/views/room/widgets/choosers/ChooserWidgetView.tsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import List from 'react-virtualized/dist/commonjs/List';
|
||||||
|
import { RoomObjectItem } from '../../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
import { CreateEventDispatcherHook } from '../../../../hooks';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||||
|
import { LocalizeText } from '../../../../utils';
|
||||||
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
|
import { RoomWidgetRoomObjectUpdateEvent } from '../../events';
|
||||||
|
import { RoomWidgetRequestWidgetMessage, RoomWidgetRoomObjectMessage } from '../../messages';
|
||||||
|
import { ChooserWidgetViewProps } from './ChooserWidgetView.type';
|
||||||
|
|
||||||
|
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
||||||
|
{
|
||||||
|
const [filteredItems, setFilteredItems] = useState<RoomObjectItem[]>([]);
|
||||||
|
const [selectedItem, setSelectedItem] = useState<RoomObjectItem>(null);
|
||||||
|
const [refreshTimeout, setRefreshTimeout] = useState<ReturnType<typeof setTimeout>>(null);
|
||||||
|
const [searchValue, setSearchValue] = useState('');
|
||||||
|
const { title = null, onCloseClick = null, displayItemId = false, items = null, messageType = null, roomWidgetRoomObjectUpdateEvents = null } = props;
|
||||||
|
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if (!items) return;
|
||||||
|
|
||||||
|
const filteredGroupItems = items.filter(item =>
|
||||||
|
{
|
||||||
|
return item.name.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
setFilteredItems(filteredGroupItems);
|
||||||
|
}, [items, searchValue, setFilteredItems]);
|
||||||
|
|
||||||
|
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||||
|
{
|
||||||
|
if (!event) return;
|
||||||
|
|
||||||
|
if (refreshTimeout) clearTimeout(refreshTimeout);
|
||||||
|
|
||||||
|
setRefreshTimeout(setTimeout(() =>
|
||||||
|
{
|
||||||
|
widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(messageType));
|
||||||
|
}, 100));
|
||||||
|
|
||||||
|
}, [refreshTimeout, messageType, widgetHandler]);
|
||||||
|
|
||||||
|
roomWidgetRoomObjectUpdateEvents.forEach(event => CreateEventDispatcherHook(event, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent));
|
||||||
|
|
||||||
|
const onClickItem = useCallback((item: RoomObjectItem) =>
|
||||||
|
{
|
||||||
|
setSelectedItem(item);
|
||||||
|
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category));
|
||||||
|
}, [setSelectedItem, widgetHandler]);
|
||||||
|
|
||||||
|
const rowRenderer = function ({
|
||||||
|
key, // Unique key within array of rows
|
||||||
|
index, // Index of row within collection
|
||||||
|
isScrolling, // The List is currently being scrolled
|
||||||
|
isVisible, // This row is visible within the List (eg it is not an overscanned row)
|
||||||
|
style, // Style object to be applied to row (to position it)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
<div key={key} style={style} onClick={() => onClickItem(filteredItems[index])} className={(selectedItem === filteredItems[index] ? 'selected-item ' : '') + 'list-item'}>
|
||||||
|
{filteredItems[index].name}
|
||||||
|
{displayItemId && (' - ' + filteredItems[index].id)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView>
|
||||||
|
<NitroCardHeaderView headerText={title} onCloseClick={onCloseClick}></NitroCardHeaderView>
|
||||||
|
<NitroCardContentView>
|
||||||
|
<div className="d-flex mb-1">
|
||||||
|
<div className="d-flex flex-grow-1 me-1">
|
||||||
|
<input type="text" className="form-control form-control-sm" placeholder={LocalizeText('generic.search')} value={searchValue} onChange={event => setSearchValue(event.target.value)} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<List width={150}
|
||||||
|
height={150}
|
||||||
|
rowCount={filteredItems.length}
|
||||||
|
rowHeight={20}
|
||||||
|
rowRenderer={rowRenderer} />
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
12
src/views/room/widgets/choosers/ChooserWidgetView.type.ts
Normal file
12
src/views/room/widgets/choosers/ChooserWidgetView.type.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { MouseEvent } from 'react';
|
||||||
|
import { RoomObjectItem } from '../../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
|
||||||
|
export interface ChooserWidgetViewProps
|
||||||
|
{
|
||||||
|
title: string;
|
||||||
|
onCloseClick: (event: MouseEvent) => void;
|
||||||
|
displayItemId: boolean;
|
||||||
|
items: RoomObjectItem[];
|
||||||
|
messageType: string;
|
||||||
|
roomWidgetRoomObjectUpdateEvents: string[];
|
||||||
|
}
|
37
src/views/room/widgets/choosers/FurniChooserWidgetView.tsx
Normal file
37
src/views/room/widgets/choosers/FurniChooserWidgetView.tsx
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { RoomObjectItem } from '../../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
import { RoomWidgetChooserContentEvent } from '../../../../events/room-widgets/choosers/RoomWidgetChooserContentEvent';
|
||||||
|
import { useUiEvent } from '../../../../hooks';
|
||||||
|
import { LocalizeText } from '../../../../utils';
|
||||||
|
import { RoomWidgetRoomObjectUpdateEvent } from '../../events';
|
||||||
|
import { RoomWidgetRequestWidgetMessage } from '../../messages';
|
||||||
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
|
export const FurniChooserWidgetView: FC = props =>
|
||||||
|
{
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
const [items, setItems] = useState<RoomObjectItem[]>(null);
|
||||||
|
|
||||||
|
const onFurniChooserContent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
||||||
|
{
|
||||||
|
setItems(event.items);
|
||||||
|
setIsVisible(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, onFurniChooserContent);
|
||||||
|
|
||||||
|
|
||||||
|
const onClose = useCallback(() =>
|
||||||
|
{
|
||||||
|
setIsVisible(false);
|
||||||
|
setItems(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!isVisible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="chooser-widget">
|
||||||
|
<ChooserWidgetView title={LocalizeText('widget.chooser.furni.title')} displayItemId={true} onCloseClick={onClose} items={items} messageType={RoomWidgetRequestWidgetMessage.FURNI_CHOOSER} roomWidgetRoomObjectUpdateEvents={[RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, RoomWidgetRoomObjectUpdateEvent.FURNI_ADDED]}></ChooserWidgetView>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
36
src/views/room/widgets/choosers/UserChooserWidgetView.tsx
Normal file
36
src/views/room/widgets/choosers/UserChooserWidgetView.tsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { RoomObjectItem } from '../../../../events/room-widgets/choosers/RoomObjectItem';
|
||||||
|
import { RoomWidgetChooserContentEvent } from '../../../../events/room-widgets/choosers/RoomWidgetChooserContentEvent';
|
||||||
|
import { useUiEvent } from '../../../../hooks';
|
||||||
|
import { LocalizeText } from '../../../../utils';
|
||||||
|
import { RoomWidgetRoomObjectUpdateEvent } from '../../events';
|
||||||
|
import { RoomWidgetRequestWidgetMessage } from '../../messages';
|
||||||
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
|
export const UserChooserWidgetView : FC = props =>
|
||||||
|
{
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
|
const [items, setItems] = useState<RoomObjectItem[]>(null);
|
||||||
|
|
||||||
|
const onUserChooserContent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
||||||
|
{
|
||||||
|
setItems(event.items);
|
||||||
|
setIsVisible(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, onUserChooserContent);
|
||||||
|
|
||||||
|
const onClose = useCallback(() =>
|
||||||
|
{
|
||||||
|
setIsVisible(false);
|
||||||
|
setItems(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if(!isVisible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="chooser-widget">
|
||||||
|
<ChooserWidgetView title={LocalizeText('widget.chooser.user.title')} displayItemId={false} onCloseClick={onClose} items={items} messageType={RoomWidgetRequestWidgetMessage.USER_CHOOSER} roomWidgetRoomObjectUpdateEvents={[RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, RoomWidgetRoomObjectUpdateEvent.USER_ADDED]}></ChooserWidgetView>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
18
src/views/room/widgets/choosers/utils/sorting.ts
Normal file
18
src/views/room/widgets/choosers/utils/sorting.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
export function dynamicSort(property)
|
||||||
|
{
|
||||||
|
// Source: https://stackoverflow.com/questions/1129216/sort-array-of-objects-by-string-property-value
|
||||||
|
let sortOrder = 1;
|
||||||
|
if(property[0] === '-')
|
||||||
|
{
|
||||||
|
sortOrder = -1;
|
||||||
|
property = property.substr(1);
|
||||||
|
}
|
||||||
|
return function (a,b)
|
||||||
|
{
|
||||||
|
/* next line works with strings and numbers,
|
||||||
|
* and you may want to customize it to your needs
|
||||||
|
*/
|
||||||
|
const result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
|
||||||
|
return result * sortOrder;
|
||||||
|
};
|
||||||
|
}
|
22
src/views/room/widgets/doorbell/DoorbellWidgetView.scss
Normal file
22
src/views/room/widgets/doorbell/DoorbellWidgetView.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
src/views/room/widgets/doorbell/DoorbellWidgetView.tsx
Normal file
88
src/views/room/widgets/doorbell/DoorbellWidgetView.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
import { DesktopViewComposer, Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, UserFigureEvent, UserInfoDataParser, UserInfoEvent, Wait } from '@nitrots/nitro-renderer';
|
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, UserFigureEvent, UserInfoDataParser, UserInfoEvent, Wait } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { GetRoomSession, GetRoomSessionManager } from '../../api';
|
import { GetRoomSession, GetRoomSessionManager, GoToDesktop } from '../../api';
|
||||||
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events';
|
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events';
|
||||||
import { AchievementsUIEvent } from '../../events/achievements';
|
import { AchievementsUIEvent } from '../../events/achievements';
|
||||||
import { UnseenItemTrackerUpdateEvent } from '../../events/inventory/UnseenItemTrackerUpdateEvent';
|
import { UnseenItemTrackerUpdateEvent } from '../../events/inventory/UnseenItemTrackerUpdateEvent';
|
||||||
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
import { ModToolsEvent } from '../../events/mod-tools/ModToolsEvent';
|
||||||
import { dispatchUiEvent, useRoomEngineEvent, useUiEvent } from '../../hooks';
|
import { dispatchUiEvent, useRoomEngineEvent, useUiEvent } from '../../hooks';
|
||||||
import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation';
|
import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation';
|
||||||
import { TransitionAnimationTypes } from '../../layout/transitions/TransitionAnimation.types';
|
import { TransitionAnimationTypes } from '../../layout/transitions/TransitionAnimation.types';
|
||||||
import { AvatarImageView } from '../shared/avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../shared/avatar-image/AvatarImageView';
|
||||||
@ -129,7 +129,7 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
{
|
{
|
||||||
if(!GetRoomSession()) return;
|
if(!GetRoomSession()) return;
|
||||||
|
|
||||||
SendMessageHook(new DesktopViewComposer());
|
GoToDesktop();
|
||||||
GetRoomSessionManager().removeSession(-1);
|
GetRoomSessionManager().removeSession(-1);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user