mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-18 21:36:27 +01:00
Merge branch '@feature/room-tools' into dev
This commit is contained in:
commit
dfe4f0eb0f
@ -2,7 +2,6 @@
|
||||
"socket.url": "wss://ws.nitrots.co:2096",
|
||||
"asset.url": "https://nitro.nitrots.co",
|
||||
"image.library.url": "https://swf.nitrots.co/c_images/",
|
||||
"internal.samples.url": "",
|
||||
"external.samples.url": "https://swf.nitrots.co/dcr/hof_furni/mp3/sound_machine_sample_%sample%.mp3",
|
||||
"image.library.notifications.url": "${image.library.url}notifications/%image%.png",
|
||||
"achievements.images.url": "${image.library.url}Quests/%image%.png",
|
||||
@ -20,7 +19,7 @@
|
||||
"avatar.asset.url": "${asset.url}/bundled/figure/%libname%.nitro",
|
||||
"avatar.asset.effect.url": "${asset.url}/bundled/effect/%libname%.nitro",
|
||||
"furni.extras.url": "${asset.url}/images/furniextras/%image%.png",
|
||||
"url.prefix": "",
|
||||
"url.prefix": "http://localhost:3000",
|
||||
"chat.viewer.height.percentage": 0.40,
|
||||
"auth.system.enabled": true,
|
||||
"auth.system.http.enabled": true,
|
||||
|
BIN
src/assets/images/icons/arrows.png
Normal file
BIN
src/assets/images/icons/arrows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 222 B |
BIN
src/assets/images/icons/camera-small.png
Normal file
BIN
src/assets/images/icons/camera-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 296 B |
BIN
src/assets/images/icons/house-small.png
Normal file
BIN
src/assets/images/icons/house-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 361 B |
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 883 B |
@ -442,12 +442,36 @@
|
||||
width: 7px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
|
||||
&.icon-sign-soccer {
|
||||
background: url('../images/icons/sign-soccer.png');
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
&.icon-house-small {
|
||||
background: url('../images/icons/house-small.png');
|
||||
width: 19px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
&.icon-camera-small {
|
||||
background: url('../images/icons/camera-small.png');
|
||||
width: 17px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
&.icon-arrows {
|
||||
background: url('../images/icons/arrows.png');
|
||||
width: 17px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
&.icon-fb-profile {
|
||||
background: url('../images/toolbar/icons/friend-bar/profile.png');
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
&.icon-camera-colormatrix {
|
||||
background: url('../images/icons/camera-colormatrix.png');
|
||||
|
@ -5,6 +5,9 @@ export class NavigatorEvent extends NitroEvent
|
||||
public static SHOW_NAVIGATOR: string = 'NE_SHOW_NAVIGATOR';
|
||||
public static HIDE_NAVIGATOR: string = 'NE_HIDE_NAVIGATOR';
|
||||
public static TOGGLE_NAVIGATOR: string = 'NE_TOGGLE_NAVIGATOR';
|
||||
public static TOGGLE_ROOM_INFO: string = 'NE_TOGGLE_ROOM_INFO';
|
||||
public static TOGGLE_ROOM_LINK: string = 'NE_TOGGLE_ROOM_LINK';
|
||||
public static TOGGLE_ROOM_SETTINGS: string = 'NE_TOGGLE_ROOM_SETTINGS';
|
||||
|
||||
private _roomId: number;
|
||||
private _password: string;
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { RoomWidgetUpdateEvent } from '../../../views/room/events/RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetThumbnailEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static SHOW_THUMBNAIL: string = 'NE_SHOW_THUMBNAIL';
|
||||
public static HIDE_THUMBNAIL: string = 'NE_HIDE_THUMBNAIL';
|
||||
public static TOGGLE_THUMBNAIL: string = 'NE_TOGGLE_THUMBNAIL';
|
||||
}
|
1
src/events/room-widgets/thumbnail/index.ts
Normal file
1
src/events/room-widgets/thumbnail/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './RoomWidgetThumbnailEvent';
|
@ -1,14 +0,0 @@
|
||||
import { createContext, FC, useContext } from 'react';
|
||||
import { AvatarEditorContextProps, IAvatarEditorContext } from './AvatarEditorContext.types';
|
||||
|
||||
const AvatarEditorContext = createContext<IAvatarEditorContext>({
|
||||
avatarEditorState: null,
|
||||
dispatchAvatarEditorState: null
|
||||
});
|
||||
|
||||
export const AvatarEditorContextProvider: FC<AvatarEditorContextProps> = props =>
|
||||
{
|
||||
return <AvatarEditorContext.Provider value={ props.value }>{ props.children }</AvatarEditorContext.Provider>
|
||||
}
|
||||
|
||||
export const useAvatarEditorContext = () => useContext(AvatarEditorContext);
|
@ -1,13 +0,0 @@
|
||||
import { Dispatch, ProviderProps } from 'react';
|
||||
import { IAvatarEditorAction, IAvatarEditorState } from '../reducers/AvatarEditorReducer';
|
||||
|
||||
export interface IAvatarEditorContext
|
||||
{
|
||||
avatarEditorState: IAvatarEditorState;
|
||||
dispatchAvatarEditorState: Dispatch<IAvatarEditorAction>;
|
||||
}
|
||||
|
||||
export interface AvatarEditorContextProps extends ProviderProps<IAvatarEditorContext>
|
||||
{
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { GenericErrorEvent, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, UserInfoEvent } from 'nitro-renderer';
|
||||
import { GenericErrorEvent, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomForwardEvent, RoomInfoComposer, RoomInfoEvent, RoomInfoOwnerEvent, RoomSettingsUpdatedEvent, UserInfoEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { GetRoomSessionManager, GetSessionDataManager } from '../../api';
|
||||
import { VisitRoom } from '../../api/navigator/VisitRoom';
|
||||
@ -9,7 +9,7 @@ import { NavigatorActions } from './reducers/NavigatorReducer';
|
||||
|
||||
export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =>
|
||||
{
|
||||
const { dispatchNavigatorState = null } = useNavigatorContext();
|
||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
||||
|
||||
const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
|
||||
{
|
||||
@ -28,8 +28,19 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const roomInfoData = navigatorState.roomInfoData;
|
||||
roomInfoData.currentRoomOwner = parser.isOwner;
|
||||
roomInfoData.currentRoomId = parser.roomId;
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
||||
payload: {
|
||||
roomInfoData: roomInfoData
|
||||
}
|
||||
});
|
||||
|
||||
SendMessageHook(new RoomInfoComposer(parser.roomId, true, false));
|
||||
}, []);
|
||||
}, [ navigatorState, dispatchNavigatorState ]);
|
||||
|
||||
const onRoomInfoEvent = useCallback((event: RoomInfoEvent) =>
|
||||
{
|
||||
@ -37,17 +48,15 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
||||
|
||||
if(parser.roomEnter)
|
||||
{
|
||||
// this._data.enteredGuestRoom = parser.data;
|
||||
// this._data.staffPick = parser.data.roomPicker;
|
||||
const roomInfoData = navigatorState.roomInfoData;
|
||||
roomInfoData.enteredGuestRoom = parser.data;
|
||||
|
||||
// const isCreatedRoom = (this._data.createdRoomId === parser.data.roomId);
|
||||
|
||||
// if(!isCreatedRoom && parser.data.displayRoomEntryAd)
|
||||
// {
|
||||
// // display ad
|
||||
// }
|
||||
|
||||
// this._data.createdRoomId = 0;
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
||||
payload: {
|
||||
roomInfoData: roomInfoData
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(parser.roomForward)
|
||||
{
|
||||
@ -66,10 +75,17 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
||||
}
|
||||
else
|
||||
{
|
||||
// this._data.enteredGuestRoom = parser.data;
|
||||
// this._data.staffPick = parser.data.roomPicker;
|
||||
const roomInfoData = navigatorState.roomInfoData;
|
||||
roomInfoData.enteredGuestRoom = parser.data;
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_ROOM_INFO_DATA,
|
||||
payload: {
|
||||
roomInfoData: roomInfoData
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
}, [ dispatchNavigatorState, navigatorState ]);
|
||||
|
||||
const onRoomDoorbellEvent = useCallback((event: RoomDoorbellEvent) =>
|
||||
{
|
||||
@ -146,6 +162,25 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
||||
VisitRoom(parser.roomId);
|
||||
}, []);
|
||||
|
||||
const onNavigatorHomeRoomEvent = useCallback((event: NavigatorHomeRoomEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
||||
payload: {
|
||||
homeRoomId: parser.homeRoomId
|
||||
}
|
||||
});
|
||||
}, [ dispatchNavigatorState ]);
|
||||
|
||||
const onRoomSettingsUpdatedEvent = useCallback((event: RoomSettingsUpdatedEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
SendMessageHook(new RoomInfoComposer(parser.roomId, false, false));
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(UserInfoEvent, onUserInfoEvent);
|
||||
CreateMessageHook(RoomForwardEvent, onRoomForwardEvent);
|
||||
CreateMessageHook(RoomInfoOwnerEvent, onRoomInfoOwnerEvent);
|
||||
@ -157,6 +192,8 @@ export const NavigatorMessageHandler: FC<NavigatorMessageHandlerProps> = props =
|
||||
CreateMessageHook(NavigatorSearchEvent, onNavigatorSearchEvent);
|
||||
CreateMessageHook(NavigatorCategoriesEvent, onNavigatorCategoriesEvent);
|
||||
CreateMessageHook(RoomCreatedEvent, onRoomCreatedEvent);
|
||||
CreateMessageHook(NavigatorHomeRoomEvent, onNavigatorHomeRoomEvent);
|
||||
CreateMessageHook(RoomSettingsUpdatedEvent, onRoomSettingsUpdatedEvent);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ import { NavigatorMessageHandler } from './NavigatorMessageHandler';
|
||||
import { NavigatorViewProps } from './NavigatorView.types';
|
||||
import { initialNavigator, NavigatorActions, NavigatorReducer } from './reducers/NavigatorReducer';
|
||||
import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView';
|
||||
import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView';
|
||||
import { NavigatorRoomLinkView } from './views/room-link/NavigatorRoomLinkView';
|
||||
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
||||
import { NavigatorSearchResultSetView } from './views/search-result-set/NavigatorSearchResultSetView';
|
||||
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
||||
|
||||
@ -18,6 +21,8 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
||||
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
||||
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
||||
const { needsNavigatorUpdate = false, topLevelContext = null, topLevelContexts = null } = navigatorState;
|
||||
|
||||
@ -34,12 +39,20 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
||||
case NavigatorEvent.TOGGLE_NAVIGATOR:
|
||||
setIsVisible(value => !value);
|
||||
return;
|
||||
case NavigatorEvent.TOGGLE_ROOM_INFO:
|
||||
setRoomInfoOpen(value => !value);
|
||||
return;
|
||||
case NavigatorEvent.TOGGLE_ROOM_LINK:
|
||||
setRoomLinkOpen(value => !value);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useUiEvent(NavigatorEvent.SHOW_NAVIGATOR, onNavigatorEvent);
|
||||
useUiEvent(NavigatorEvent.HIDE_NAVIGATOR, onNavigatorEvent);
|
||||
useUiEvent(NavigatorEvent.TOGGLE_NAVIGATOR, onNavigatorEvent);
|
||||
useUiEvent(NavigatorEvent.TOGGLE_ROOM_INFO, onNavigatorEvent);
|
||||
useUiEvent(NavigatorEvent.TOGGLE_ROOM_LINK, onNavigatorEvent);
|
||||
|
||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||
{
|
||||
@ -110,6 +123,9 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView> }
|
||||
{ isRoomInfoOpen && <NavigatorRoomInfoView onCloseClick={ () => setRoomInfoOpen(false) } /> }
|
||||
{ isRoomLinkOpen && <NavigatorRoomLinkView onCloseClick={ () => setRoomLinkOpen(false) } /> }
|
||||
<NavigatorRoomSettingsView />
|
||||
</NavigatorContextProvider>
|
||||
);
|
||||
}
|
||||
|
60
src/views/navigator/common/RoomInfoData.ts
Normal file
60
src/views/navigator/common/RoomInfoData.ts
Normal file
@ -0,0 +1,60 @@
|
||||
import { RoomDataParser } from 'nitro-renderer';
|
||||
|
||||
export class RoomInfoData
|
||||
{
|
||||
private _enteredGuestRoom: RoomDataParser = null;
|
||||
private _createdRoomId: number = 0;
|
||||
private _currentRoomId: number = 0;
|
||||
private _currentRoomOwner: boolean = false;
|
||||
private _canRate: boolean = false;
|
||||
|
||||
public get enteredGuestRoom(): RoomDataParser
|
||||
{
|
||||
return this._enteredGuestRoom;
|
||||
}
|
||||
|
||||
public set enteredGuestRoom(data: RoomDataParser)
|
||||
{
|
||||
this._enteredGuestRoom = data;
|
||||
}
|
||||
|
||||
public get createdRoomId(): number
|
||||
{
|
||||
return this._createdRoomId;
|
||||
}
|
||||
|
||||
public set createdRoomId(id: number)
|
||||
{
|
||||
this._createdRoomId = id;
|
||||
}
|
||||
|
||||
public get currentRoomId(): number
|
||||
{
|
||||
return this._currentRoomId;
|
||||
}
|
||||
|
||||
public set currentRoomId(id: number)
|
||||
{
|
||||
this._currentRoomId = id;
|
||||
}
|
||||
|
||||
public get currentRoomOwner(): boolean
|
||||
{
|
||||
return this._currentRoomOwner;
|
||||
}
|
||||
|
||||
public set currentRoomOwner(flag: boolean)
|
||||
{
|
||||
this._currentRoomOwner = flag;
|
||||
}
|
||||
|
||||
public get canRate(): boolean
|
||||
{
|
||||
return this._canRate;
|
||||
}
|
||||
|
||||
public set canRate(flag: boolean)
|
||||
{
|
||||
this._canRate = flag;
|
||||
}
|
||||
}
|
95
src/views/navigator/common/RoomSettingsData.ts
Normal file
95
src/views/navigator/common/RoomSettingsData.ts
Normal file
@ -0,0 +1,95 @@
|
||||
export default class RoomSettingsData
|
||||
{
|
||||
public roomId: number;
|
||||
public roomName: string;
|
||||
public roomOriginalName: string;
|
||||
public roomDescription: string;
|
||||
public categoryId: number;
|
||||
public userCount: number;
|
||||
public tags: string[];
|
||||
public tradeState: number;
|
||||
public allowWalkthrough: boolean;
|
||||
|
||||
public lockState: number;
|
||||
public originalLockState: number;
|
||||
public password: string;
|
||||
public confirmPassword: string;
|
||||
public allowPets: boolean;
|
||||
public allowPetsEat: boolean;
|
||||
|
||||
public usersWithRights: Map<number, string>;
|
||||
public friendsWithoutRights: Map<number, string>;
|
||||
|
||||
public hideWalls: boolean;
|
||||
public wallThickness: number;
|
||||
public floorThickness: number;
|
||||
public chatBubbleMode: number;
|
||||
public chatBubbleWeight: number;
|
||||
public chatBubbleSpeed: number;
|
||||
public chatFloodProtection: number;
|
||||
public chatDistance: number;
|
||||
|
||||
public muteState: number;
|
||||
public kickState: number;
|
||||
public banState: number;
|
||||
public bannedUsers: Map<number, string>;
|
||||
public selectedUserToUnban: number;
|
||||
|
||||
constructor()
|
||||
{
|
||||
this.roomId = 0;
|
||||
this.roomName = null;
|
||||
this.roomOriginalName = null;
|
||||
this.roomDescription = null;
|
||||
this.categoryId = 0;
|
||||
this.userCount = 0;
|
||||
this.tags = [];
|
||||
this.tradeState = 0;
|
||||
this.allowWalkthrough = false;
|
||||
|
||||
this.lockState = 0;
|
||||
this.originalLockState = 0;
|
||||
this.password = null;
|
||||
this.confirmPassword = null;
|
||||
this.allowPets = false;
|
||||
this.allowPetsEat = false;
|
||||
|
||||
this.usersWithRights = new Map<number, string>();
|
||||
this.friendsWithoutRights = new Map<number, string>();
|
||||
|
||||
this.hideWalls = false;
|
||||
this.wallThickness = 0;
|
||||
this.floorThickness = 0;
|
||||
this.chatBubbleMode = 0;
|
||||
this.chatBubbleWeight = 0;
|
||||
this.chatBubbleSpeed = 0;
|
||||
this.chatFloodProtection = 0;
|
||||
this.chatDistance = 0;
|
||||
|
||||
this.muteState = 0;
|
||||
this.kickState = 0;
|
||||
this.banState = 0;
|
||||
this.bannedUsers = new Map<number, string>();
|
||||
this.selectedUserToUnban = 0;
|
||||
}
|
||||
|
||||
public selectUserToUnban(userId: number): void
|
||||
{
|
||||
if(this.selectedUserToUnban === userId)
|
||||
{
|
||||
this.selectedUserToUnban = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectedUserToUnban = userId;
|
||||
}
|
||||
}
|
||||
|
||||
public get selectedUsernameToUnban(): string
|
||||
{
|
||||
if(this.selectedUserToUnban > 0)
|
||||
return this.bannedUsers.get(this.selectedUserToUnban);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { NavigatorCategoryDataParser, NavigatorSearchResultSet, NavigatorTopLevelContext } from 'nitro-renderer';
|
||||
import { Reducer } from 'react';
|
||||
import { RoomInfoData } from '../common/RoomInfoData';
|
||||
|
||||
export interface INavigatorState
|
||||
{
|
||||
@ -8,6 +9,8 @@ export interface INavigatorState
|
||||
topLevelContexts: NavigatorTopLevelContext[];
|
||||
searchResult: NavigatorSearchResultSet;
|
||||
categories: NavigatorCategoryDataParser[];
|
||||
roomInfoData: RoomInfoData;
|
||||
homeRoomId: number;
|
||||
}
|
||||
|
||||
export interface INavigatorAction
|
||||
@ -19,6 +22,8 @@ export interface INavigatorAction
|
||||
topLevelContexts?: NavigatorTopLevelContext[];
|
||||
searchResult?: NavigatorSearchResultSet;
|
||||
categories?: NavigatorCategoryDataParser[];
|
||||
roomInfoData?: RoomInfoData;
|
||||
homeRoomId?: number;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +34,8 @@ export class NavigatorActions
|
||||
public static SET_TOP_LEVEL_CONTEXTS: string = 'NA_SET_TOP_LEVEL_CONTEXTS';
|
||||
public static SET_SEARCH_RESULT: string = 'NA_SET_SEARCH_RESULT';
|
||||
public static SET_CATEGORIES: string = 'NA_SET_CATEGORIES';
|
||||
public static SET_ROOM_INFO_DATA: string = 'NA_SET_ROOM_INFO_DATA';
|
||||
public static SET_HOME_ROOM_ID: string = 'NA_SET_HOME_ROOM_ID';
|
||||
}
|
||||
|
||||
export const initialNavigator: INavigatorState = {
|
||||
@ -36,7 +43,9 @@ export const initialNavigator: INavigatorState = {
|
||||
topLevelContext: null,
|
||||
topLevelContexts: null,
|
||||
searchResult: null,
|
||||
categories: null
|
||||
categories: null,
|
||||
roomInfoData: new RoomInfoData(),
|
||||
homeRoomId: null
|
||||
}
|
||||
|
||||
export const NavigatorReducer: Reducer<INavigatorState, INavigatorAction> = (state, action) =>
|
||||
@ -90,6 +99,16 @@ export const NavigatorReducer: Reducer<INavigatorState, INavigatorAction> = (sta
|
||||
|
||||
return { ...state, categories };
|
||||
}
|
||||
case NavigatorActions.SET_ROOM_INFO_DATA: {
|
||||
const roomInfoData = (action.payload.roomInfoData || state.roomInfoData || null);
|
||||
|
||||
return { ...state, roomInfoData };
|
||||
}
|
||||
case NavigatorActions.SET_HOME_ROOM_ID: {
|
||||
const homeRoomId = (action.payload.homeRoomId || state.homeRoomId || null);
|
||||
|
||||
return { ...state, homeRoomId };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -2,3 +2,6 @@
|
||||
@import './search/NavigatorSearchView';
|
||||
@import './search-result/NavigatorSearchResultView';
|
||||
@import './search-result-item/NavigatorSearchResultItemView';
|
||||
@import './room-info/NavigatorRoomInfoView';
|
||||
@import './room-link/NavigatorRoomLinkView';
|
||||
@import './room-settings/NavigatorRoomSettingsView';
|
||||
|
@ -0,0 +1,20 @@
|
||||
.nitro-room-info {
|
||||
width: 230px;
|
||||
|
||||
.gray {
|
||||
filter: grayscale(1);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.room-thumbnail {
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin: 0 auto;
|
||||
background-image: url(../../../../assets/images/navigator/thumbnail_placeholder.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: rgba($black, .125);
|
||||
border-color: $black !important;
|
||||
}
|
||||
}
|
148
src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx
Normal file
148
src/views/navigator/views/room-info/NavigatorRoomInfoView.tsx
Normal file
@ -0,0 +1,148 @@
|
||||
import classNames from 'classnames';
|
||||
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, UserHomeRoomComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetConfiguration } from '../../../../api';
|
||||
import { NavigatorEvent } from '../../../../events';
|
||||
import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail';
|
||||
import { dispatchUiEvent } from '../../../../hooks/events';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorActions } from '../../reducers/NavigatorReducer';
|
||||
import { NavigatorRoomInfoViewProps } from './NavigatorRoomInfoView.types';
|
||||
|
||||
export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
|
||||
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null, homeRoomId = null } = navigatorState;
|
||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||
const [ isRoomPicked, setIsRoomPicked ] = useState(false);
|
||||
const [ isRoomMuted, setIsRoomMuted ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
if(roomInfoData.enteredGuestRoom.officialRoomPicRef)
|
||||
{
|
||||
setRoomThumbnail(GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
||||
}
|
||||
|
||||
setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker);
|
||||
setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted);
|
||||
}, [ roomInfoData ]);
|
||||
|
||||
const processAction = useCallback((action: string, value?: string) =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case 'set_home_room':
|
||||
let newRoomId = -1;
|
||||
|
||||
if(homeRoomId !== roomInfoData.enteredGuestRoom.roomId)
|
||||
{
|
||||
newRoomId = roomInfoData.enteredGuestRoom.roomId;
|
||||
}
|
||||
|
||||
dispatchNavigatorState({
|
||||
type: NavigatorActions.SET_HOME_ROOM_ID,
|
||||
payload: {
|
||||
homeRoomId: newRoomId
|
||||
}
|
||||
});
|
||||
|
||||
SendMessageHook(new UserHomeRoomComposer(newRoomId));
|
||||
return;
|
||||
case 'navigator_search_tag':
|
||||
return;
|
||||
case 'open_room_thumbnail_camera':
|
||||
dispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
|
||||
return;
|
||||
case 'open_group_info':
|
||||
return;
|
||||
case 'toggle_room_link':
|
||||
dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
||||
return;
|
||||
case 'open_room_settings':
|
||||
SendMessageHook(new RoomSettingsComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_pick':
|
||||
setIsRoomPicked(value => !value);
|
||||
SendMessageHook(new RoomStaffPickComposer(roomInfoData.enteredGuestRoom.roomId));
|
||||
return;
|
||||
case 'toggle_mute':
|
||||
setIsRoomMuted(value => !value);
|
||||
SendMessageHook(new RoomMuteComposer());
|
||||
return;
|
||||
case 'close':
|
||||
onCloseClick();
|
||||
return;
|
||||
}
|
||||
|
||||
}, [ onCloseClick, dispatchNavigatorState, roomInfoData, homeRoomId ]);
|
||||
|
||||
if(!roomInfoData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-info" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardContentView className="text-black">
|
||||
{ roomInfoData.enteredGuestRoom && <>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="fw-bold">
|
||||
{ roomInfoData.enteredGuestRoom.roomName }
|
||||
</div>
|
||||
<i onClick={ () => processAction('set_home_room') } className={ 'icon icon-house-small cursor-pointer' + classNames({' gray': homeRoomId !== roomInfoData.enteredGuestRoom.roomId }) } />
|
||||
</div>
|
||||
<div className="d-flex align-items-center">
|
||||
{ roomInfoData.enteredGuestRoom.showOwner && <>
|
||||
<div className="fw-bold text-muted me-1">{ LocalizeText('navigator.roomownercaption') }</div>
|
||||
<div className="d-flex align-items-center cursor-pointer">
|
||||
<i className="icon icon-user-profile me-1" />
|
||||
<div>{ roomInfoData.enteredGuestRoom.ownerName }</div>
|
||||
</div>
|
||||
</> }
|
||||
</div>
|
||||
<div>
|
||||
<span className="fw-bold text-muted me-1">{ LocalizeText('navigator.roomrating') }</span> { roomInfoData.enteredGuestRoom.score }
|
||||
</div>
|
||||
<div className="d-flex mb-1">
|
||||
{ roomInfoData.enteredGuestRoom.tags.map(tag =>
|
||||
{
|
||||
return <div className="bg-muted p-1 rounded me-1 cursor-pointer" onClick={ () => processAction('navigator_search_tag', tag) }>#{ tag }</div>
|
||||
}) }
|
||||
</div>
|
||||
<div>{ roomInfoData.enteredGuestRoom.description }</div>
|
||||
<div className="room-thumbnail border mt-1 mb-2">
|
||||
<i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer" onClick={ () => processAction('open_room_thumbnail_camera') } />
|
||||
{ roomThumbnail && <img alt="" src={ roomThumbnail } /> }
|
||||
</div>
|
||||
{ roomInfoData.enteredGuestRoom.habboGroupId > 0 && <div className="d-flex align-items-center mb-2 cursor-pointer" onClick={ () => processAction('open_group_info') }>
|
||||
<div className="me-2">
|
||||
<BadgeImageView badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
|
||||
</div>
|
||||
<div className="text-decoration-underline">
|
||||
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) }
|
||||
</div>
|
||||
</div> }
|
||||
<div className="cursor-pointer text-decoration-underline d-flex align-items-center mb-2" onClick={ () => processAction('toggle_room_link') }>
|
||||
<i className="icon icon-arrows me-1" />
|
||||
<span>{ LocalizeText('navigator.embed.caption') }</span>
|
||||
</div>
|
||||
<button className="btn btn-sm btn-primary w-100 mb-1" onClick={ () => processAction('open_room_settings') }>{ LocalizeText('navigator.room.popup.info.room.settings') }</button>
|
||||
<button className="btn btn-sm btn-primary w-100 mb-1" disabled={ true }>{ LocalizeText('open.floor.plan.editor') }</button>
|
||||
<button className="btn btn-sm btn-primary w-100 mb-1" onClick={ () => processAction('toggle_pick') }>{ LocalizeText(isRoomPicked ? 'navigator.staffpicks.unpick' : 'navigator.staffpicks.pick') }</button>
|
||||
<button className="btn btn-sm btn-danger w-100 mb-1" disabled={ true }>{ LocalizeText('help.emergency.main.report.room') }</button>
|
||||
<button className="btn btn-sm btn-primary w-100" onClick={ () => processAction('toggle_mute') }>{ LocalizeText(isRoomMuted ? 'navigator.muteall_on' : 'navigator.muteall_off') }</button>
|
||||
</> }
|
||||
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
|
||||
export class NavigatorRoomInfoViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
.nitro-room-link {
|
||||
width: 400px;
|
||||
|
||||
.room-thumbnail {
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
background-image: url(../../../../assets/images/navigator/thumbnail_placeholder.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: rgba($black, .125);
|
||||
border-color: $black !important;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetConfiguration } from '../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorRoomLinkViewProps } from './NavigatorRoomLinkView.types';
|
||||
|
||||
export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { roomInfoData = null } = navigatorState;
|
||||
|
||||
const [ roomThumbnail, setRoomThumbnail ] = useState(null);
|
||||
const [ roomLink, setRoomLink ] = useState(null);
|
||||
|
||||
const elementRef = useRef<HTMLInputElement>();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
if(roomInfoData.enteredGuestRoom.officialRoomPicRef)
|
||||
{
|
||||
setRoomThumbnail(GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
||||
}
|
||||
|
||||
const roomLinkRaw = Nitro.instance.core.configuration.interpolate(LocalizeText('navigator.embed.src', ['roomId'], [roomInfoData.enteredGuestRoom.roomId.toString()]));
|
||||
|
||||
setRoomLink(roomLinkRaw);
|
||||
}, [ roomInfoData ]);
|
||||
|
||||
const processAction = useCallback((action: string) =>
|
||||
{
|
||||
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case 'copy_room_link':
|
||||
elementRef.current.select();
|
||||
document.execCommand('copy');
|
||||
return;
|
||||
case 'close':
|
||||
onCloseClick();
|
||||
return;
|
||||
}
|
||||
|
||||
}, [onCloseClick, roomInfoData]);
|
||||
|
||||
if(!roomInfoData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-link" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardContentView className="text-black d-flex align-items-center">
|
||||
<div className="me-3">
|
||||
<div className="room-thumbnail border">
|
||||
{ roomThumbnail && <img alt="" src={ roomThumbnail } /> }
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="h5 fw-bold m-0">{ LocalizeText('navigator.embed.headline') }</div>
|
||||
<div>{ LocalizeText('navigator.embed.info') }</div>
|
||||
{ roomLink && <input ref={ elementRef } type="text" readOnly className="form-control form-control-sm" value={ roomLink } /> }
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
|
||||
export class NavigatorRoomLinkViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.nitro-room-settings {
|
||||
width: 400px;
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
import { RoomSettingsEvent, SaveRoomSettingsComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||
import { NavigatorRoomSettingsAccessTabView } from './views/tab-access/NavigatorRoomSettingsAccessTabView';
|
||||
import { NavigatorRoomSettingsBasicTabView } from './views/tab-basic/NavigatorRoomSettingsBasicTabView';
|
||||
|
||||
const TABS: string[] = [
|
||||
'navigator.roomsettings.tab.1',
|
||||
'navigator.roomsettings.tab.2',
|
||||
'navigator.roomsettings.tab.3',
|
||||
'navigator.roomsettings.tab.4',
|
||||
'navigator.roomsettings.tab.5'
|
||||
];
|
||||
|
||||
export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
{
|
||||
const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null);
|
||||
const [ currentTab, setCurrentTab ] = useState(TABS[0]);
|
||||
|
||||
const updateSettings = useCallback((roomSettings: RoomSettingsData) =>
|
||||
{
|
||||
console.log('update', roomSettings);
|
||||
setRoomSettingsData(roomSettings);
|
||||
}, [ setRoomSettingsData ]);
|
||||
|
||||
const onRoomSettingsEvent = useCallback((event: RoomSettingsEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const roomSettingsData = new RoomSettingsData();
|
||||
|
||||
roomSettingsData.roomId = parser.roomId;
|
||||
roomSettingsData.roomName = parser.name;
|
||||
roomSettingsData.roomOriginalName = parser.name;
|
||||
roomSettingsData.roomDescription = parser.description;
|
||||
roomSettingsData.categoryId = parser.categoryId;
|
||||
roomSettingsData.userCount = parser.userCount;
|
||||
roomSettingsData.tradeState = parser.tradeMode;
|
||||
roomSettingsData.allowWalkthrough = parser.allowWalkthrough;
|
||||
|
||||
roomSettingsData.lockState = parser.state;
|
||||
roomSettingsData.originalLockState = parser.state;
|
||||
roomSettingsData.allowPets = parser.allowPets;
|
||||
|
||||
roomSettingsData.hideWalls = parser.hideWalls;
|
||||
roomSettingsData.wallThickness = parser.thicknessWall;
|
||||
roomSettingsData.floorThickness = parser.thicknessFloor;
|
||||
roomSettingsData.chatBubbleMode = parser.chatSettings.mode;
|
||||
roomSettingsData.chatBubbleWeight = parser.chatSettings.weight;
|
||||
roomSettingsData.chatBubbleSpeed = parser.chatSettings.speed;
|
||||
roomSettingsData.chatFloodProtection = parser.chatSettings.protection;
|
||||
roomSettingsData.chatDistance = parser.chatSettings.distance;
|
||||
|
||||
roomSettingsData.muteState = parser.moderationSettings.allowMute;
|
||||
roomSettingsData.kickState = parser.moderationSettings.allowKick;
|
||||
roomSettingsData.banState = parser.moderationSettings.allowBan;
|
||||
|
||||
setRoomSettingsData(roomSettingsData);
|
||||
}, []);
|
||||
|
||||
CreateMessageHook(RoomSettingsEvent, onRoomSettingsEvent);
|
||||
|
||||
const save = useCallback(() =>
|
||||
{
|
||||
console.log('save', roomSettingsData)
|
||||
const composer = new SaveRoomSettingsComposer(
|
||||
roomSettingsData.roomId,
|
||||
roomSettingsData.roomName,
|
||||
roomSettingsData.roomDescription,
|
||||
roomSettingsData.lockState,
|
||||
roomSettingsData.password,
|
||||
roomSettingsData.userCount,
|
||||
roomSettingsData.categoryId,
|
||||
roomSettingsData.tags.length,
|
||||
roomSettingsData.tags,
|
||||
roomSettingsData.tradeState,
|
||||
roomSettingsData.allowPets,
|
||||
roomSettingsData.allowPetsEat,
|
||||
roomSettingsData.allowWalkthrough,
|
||||
roomSettingsData.hideWalls,
|
||||
roomSettingsData.wallThickness,
|
||||
roomSettingsData.floorThickness,
|
||||
roomSettingsData.muteState,
|
||||
roomSettingsData.kickState,
|
||||
roomSettingsData.banState,
|
||||
roomSettingsData.chatBubbleMode,
|
||||
roomSettingsData.chatBubbleWeight,
|
||||
roomSettingsData.chatBubbleSpeed,
|
||||
roomSettingsData.chatDistance,
|
||||
roomSettingsData.chatFloodProtection
|
||||
);
|
||||
|
||||
SendMessageHook(composer);
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const processAction = useCallback((action: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'close':
|
||||
setRoomSettingsData(null);
|
||||
setCurrentTab(TABS[0]);
|
||||
return;
|
||||
}
|
||||
}, [ setRoomSettingsData ]);
|
||||
|
||||
if(!roomSettingsData) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-settings">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings') } onCloseClick={ () => processAction('close') } />
|
||||
<NitroCardTabsView>
|
||||
{ TABS.map(tab =>
|
||||
{
|
||||
return <NitroCardTabsItemView key={ tab } isActive={ currentTab === tab } onClick={ event => setCurrentTab(tab) }>{ LocalizeText(tab) }</NitroCardTabsItemView>
|
||||
}) }
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView className="text-black px-4">
|
||||
{ currentTab === TABS[0] && <NavigatorRoomSettingsBasicTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[1] && <NavigatorRoomSettingsAccessTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||
|
||||
export class NavigatorRoomSettingsTabViewProps
|
||||
{
|
||||
roomSettingsData: RoomSettingsData;
|
||||
setRoomSettingsData: (roomSettings: RoomSettingsData) => void;
|
||||
onSave: () => void;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import RoomSettingsData from '../../../../common/RoomSettingsData';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = ({...roomSettingsData} as RoomSettingsData);
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'lock_state':
|
||||
roomSettings.lockState = Number(value);
|
||||
|
||||
if(Number(value) === 3) save = false;
|
||||
break;
|
||||
case 'password':
|
||||
roomSettings.password = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'confirm_password':
|
||||
roomSettings.confirmPassword = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'allow_pets':
|
||||
roomSettings.allowPets = Boolean(value);
|
||||
break;
|
||||
case 'allow_pets_eat':
|
||||
roomSettings.allowPetsEat = Boolean(value);
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(roomSettings);
|
||||
|
||||
if(save) onSave();
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
const isPasswordValid = useCallback(() =>
|
||||
{
|
||||
return (roomSettingsData.password && roomSettingsData.password.length > 0 && roomSettingsData.password === roomSettingsData.confirmPassword);
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const trySave = useCallback(() =>
|
||||
{
|
||||
if(isPasswordValid()) onSave();
|
||||
}, [ isPasswordValid, onSave ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fw-bold">{ LocalizeText('navigator.roomsettings.doormode') }</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 0 } onChange={ (e) => handleChange('lock_state', 0) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.open') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 1 } onChange={ (e) => handleChange('lock_state', 1) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.doorbell') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 2 } onChange={ (e) => handleChange('lock_state', 2) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.invisible') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 3 } onChange={ (e) => handleChange('lock_state', 3) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.doormode.password') }</label>
|
||||
</div>
|
||||
{ roomSettingsData.lockState === 3 && <>
|
||||
<div className="form-group mt-2">
|
||||
<label>{ LocalizeText('navigator.roomsettings.password') }</label>
|
||||
<input type="password" className="form-control form-control-sm" value={ roomSettingsData.password ?? '' } onChange={ (e) => handleChange('password', e.target.value) } onBlur={ trySave } placeholder="*****" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.roomsettings.passwordconfirm') }</label>
|
||||
<input type="password" className="form-control form-control-sm" value={ roomSettingsData.confirmPassword ?? '' } onChange={ (e) => handleChange('confirm_password', e.target.value) } onBlur={ trySave } placeholder="*****" />
|
||||
{ !isPasswordValid() && <small className="text-danger fw-bold">
|
||||
{ LocalizeText('navigator.roomsettings.invalidconfirm') }
|
||||
</small> }
|
||||
</div>
|
||||
</> }
|
||||
<div className="fw-bold mt-2">{ LocalizeText('navigator.roomsettings.pets') }</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPets } onChange={ (e) => handleChange('allow_pets', e.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allowpets') }</label>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPetsEat } onChange={ (e) => handleChange('allow_pets_eat', e.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allowfoodconsume') }</label>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
@ -0,0 +1,107 @@
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import RoomSettingsData from '../../../../common/RoomSettingsData';
|
||||
import { useNavigatorContext } from '../../../../context/NavigatorContext';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { categories = null } = navigatorState;
|
||||
|
||||
const [ maxVisitorsList, setMaxVisitorsList ] = useState(null);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!maxVisitorsList)
|
||||
{
|
||||
const list = [];
|
||||
|
||||
for(let i = 10; i <= 100; i = i + 10)
|
||||
{
|
||||
list.push(i);
|
||||
}
|
||||
|
||||
setMaxVisitorsList(list);
|
||||
}
|
||||
}, [ maxVisitorsList ]);
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = ({...roomSettingsData} as RoomSettingsData);
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'name':
|
||||
roomSettings.roomName = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'description':
|
||||
roomSettings.roomDescription = String(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'category':
|
||||
roomSettings.categoryId = Number(value);
|
||||
break;
|
||||
case 'max_visitors':
|
||||
roomSettings.userCount = Number(value);
|
||||
break;
|
||||
case 'trade_state':
|
||||
roomSettings.tradeState = Number(value);
|
||||
break;
|
||||
case 'allow_walkthrough':
|
||||
roomSettings.allowWalkthrough = Boolean(value);
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(roomSettings);
|
||||
|
||||
if(save) onSave();
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.roomname') }</label>
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomName } onChange={ e => handleChange('name', e.target.value) } onBlur={ onSave } />
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.roomsettings.desc') }</label>
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomDescription } onChange={ e => handleChange('description', e.target.value) } onBlur={ () => onSave() } />
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.category') }</label>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ (e) => handleChange('category', e.target.value) }>
|
||||
{ categories && categories.map(category =>
|
||||
{
|
||||
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.maxvisitors') }</label>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ (e) => handleChange('max_visitors', e.target.value) }>
|
||||
{ maxVisitorsList && maxVisitorsList.map(value =>
|
||||
{
|
||||
return <option key={ value } value={ value }>{ value }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<label>{ LocalizeText('navigator.tradesettings') }</label>
|
||||
<select className="form-select form-select-sm" value={ roomSettingsData.tradeState } onChange={ (e) => handleChange('trade_state', e.target.value) }>
|
||||
<option value="0">{ LocalizeText('${navigator.roomsettings.trade_not_allowed}') }</option>
|
||||
<option value="1">{ LocalizeText('${navigator.roomsettings.trade_not_with_Controller}') }</option>
|
||||
<option value="2">{ LocalizeText('${navigator.roomsettings.trade_allowed}') }</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowWalkthrough } onChange={ (e) => handleChange('allow_walkthrough', e.target.checked) } />
|
||||
<label className="form-check-label">{ LocalizeText('navigator.roomsettings.allow_walk_through') }</label>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
@ -7,7 +7,10 @@ import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent';
|
||||
import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
|
||||
import { RoomContextProvider } from './context/RoomContext';
|
||||
import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent';
|
||||
import { FurnitureContextMenuWidgetHandler, FurnitureCustomStackHeightWidgetHandler, IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
|
||||
import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
|
||||
import { FurnitureContextMenuWidgetHandler } from './handlers/FurnitureContextMenuWidgetHandler';
|
||||
import { FurnitureCustomStackHeightWidgetHandler } from './handlers/FurnitureCustomStackHeightWidgetHandler';
|
||||
import { RoomWidgetRoomToolsHandler } from './handlers/RoomWidgetRoomToolsHandler';
|
||||
import { RoomColorView } from './RoomColorView';
|
||||
import { RoomViewProps } from './RoomView.types';
|
||||
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
||||
@ -36,6 +39,7 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetRoomToolsHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler());
|
||||
|
38
src/views/room/handlers/RoomWidgetRoomToolsHandler.ts
Normal file
38
src/views/room/handlers/RoomWidgetRoomToolsHandler.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { NitroEvent, RoomWidgetEnum, RoomZoomEvent } from 'nitro-renderer';
|
||||
import { GetRoomEngine } from '../../../api';
|
||||
import { RoomWidgetUpdateEvent } from '../events';
|
||||
import { RoomWidgetMessage, RoomWidgetZoomToggleMessage } from '../messages';
|
||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||
|
||||
export class RoomWidgetRoomToolsHandler extends RoomWidgetHandler
|
||||
{
|
||||
public processEvent(event: NitroEvent): void
|
||||
{}
|
||||
|
||||
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
if(message instanceof RoomWidgetZoomToggleMessage)
|
||||
{
|
||||
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(GetRoomEngine().activeRoomId, message.zoomedIn ? 0 : 1, false));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return RoomWidgetEnum.ROOM_TOOLS;
|
||||
}
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomWidgetZoomToggleMessage.ZOOM_TOGGLE
|
||||
];
|
||||
}
|
||||
}
|
18
src/views/room/messages/RoomWidgetZoomToggleMessage.ts
Normal file
18
src/views/room/messages/RoomWidgetZoomToggleMessage.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { RoomWidgetMessage } from '.';
|
||||
|
||||
export class RoomWidgetZoomToggleMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static ZOOM_TOGGLE: string = 'RWZTM_ZOOM_TOGGLE';
|
||||
private _zoomedIn: boolean;
|
||||
|
||||
constructor(zoomedIn: boolean)
|
||||
{
|
||||
super(RoomWidgetZoomToggleMessage.ZOOM_TOGGLE);
|
||||
this._zoomedIn = zoomedIn;
|
||||
}
|
||||
|
||||
public get zoomedIn(): boolean
|
||||
{
|
||||
return this._zoomedIn;
|
||||
}
|
||||
}
|
@ -12,3 +12,4 @@ export * from './RoomWidgetRequestWidgetMessage';
|
||||
export * from './RoomWidgetRoomObjectMessage';
|
||||
export * from './RoomWidgetUseProductMessage';
|
||||
export * from './RoomWidgetUserActionMessage';
|
||||
export * from './RoomWidgetZoomToggleMessage';
|
||||
|
@ -6,3 +6,5 @@
|
||||
@import './furniture/FurnitureWidgets';
|
||||
@import './infostand/InfoStandWidgetView';
|
||||
@import './object-location/ObjectLocationView';
|
||||
@import './room-tools/RoomToolsWidgetView';
|
||||
@import './room-thumbnail/RoomThumbnailView';
|
||||
|
@ -11,8 +11,9 @@ import { ChatInputView } from './chat-input/ChatInputView';
|
||||
import { ChatWidgetView } from './chat/ChatWidgetView';
|
||||
import { FurnitureWidgetsView } from './furniture/FurnitureWidgetsView';
|
||||
import { InfoStandWidgetView } from './infostand/InfoStandWidgetView';
|
||||
import { RoomThumbnailWidgetView } from './room-thumbnail/RoomThumbnailWidgetView';
|
||||
import { RoomToolsWidgetView } from './room-tools/RoomToolsWidgetView';
|
||||
import { RoomWidgetViewProps } from './RoomWidgets.types';
|
||||
|
||||
export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
{
|
||||
const { roomSession = null, eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
@ -243,6 +244,8 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
<ChatInputView />
|
||||
<FurnitureWidgetsView />
|
||||
<InfoStandWidgetView />
|
||||
<RoomToolsWidgetView />
|
||||
<RoomThumbnailWidgetView />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ export const FurnitureFriendFurniView: FC<{}> = props =>
|
||||
|
||||
return (
|
||||
<>
|
||||
{ engravingStage > 0 && <NitroCardView className="nitro-engraving-lock">
|
||||
{ engravingStage > 0 && <NitroCardView className="nitro-engraving-lock" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('friend.furniture.confirm.lock.caption') } onCloseClick={ event => processAction('close_request') } />
|
||||
<NitroCardContentView>
|
||||
<h5 className="text-black text-center fw-bold mt-2 mb-2">
|
||||
|
14
src/views/room/widgets/room-thumbnail/RoomThumbnailView.scss
Normal file
14
src/views/room/widgets/room-thumbnail/RoomThumbnailView.scss
Normal file
@ -0,0 +1,14 @@
|
||||
.nitro-room-thumbnail {
|
||||
width: 300px;
|
||||
|
||||
.option {
|
||||
font-size: 30px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@import './views/builder/RoomThumbnailWidgetBuilderView';
|
||||
@import './views/camera/RoomThumbnailWidgetCameraView';
|
@ -0,0 +1,69 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { RoomWidgetThumbnailEvent } from '../../../../events/room-widgets/thumbnail';
|
||||
import { useUiEvent } from '../../../../hooks/events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { RoomThumbnailWidgetBuilderView } from './views/builder/RoomThumbnailWidgetBuilderView';
|
||||
import { RoomThumbnailWidgetCameraView } from './views/camera/RoomThumbnailWidgetCameraView';
|
||||
|
||||
export const RoomThumbnailWidgetView: FC<{}> = props =>
|
||||
{
|
||||
const [ isSelectorVisible, setIsSelectorVisible ] = useState(false);
|
||||
const [ isBuilderVisible, setIsBuilderVisible ] = useState(false);
|
||||
const [ isCameraVisible, setIsCameraVisible ] = useState(false);
|
||||
|
||||
const onNitroEvent = useCallback((event: RoomWidgetThumbnailEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetThumbnailEvent.SHOW_THUMBNAIL:
|
||||
setIsSelectorVisible(true);
|
||||
return;
|
||||
case RoomWidgetThumbnailEvent.HIDE_THUMBNAIL:
|
||||
setIsSelectorVisible(false);
|
||||
setIsBuilderVisible(false);
|
||||
setIsCameraVisible(false);
|
||||
return;
|
||||
case RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL:
|
||||
setIsSelectorVisible(value => !value);
|
||||
setIsBuilderVisible(false);
|
||||
setIsCameraVisible(false);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useUiEvent(RoomWidgetThumbnailEvent.SHOW_THUMBNAIL, onNitroEvent);
|
||||
useUiEvent(RoomWidgetThumbnailEvent.HIDE_THUMBNAIL, onNitroEvent);
|
||||
useUiEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL, onNitroEvent);
|
||||
|
||||
const handleAction = useCallback((action: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'camera':
|
||||
setIsSelectorVisible(false);
|
||||
setIsCameraVisible(true);
|
||||
return;
|
||||
case 'builder':
|
||||
setIsSelectorVisible(false);
|
||||
setIsBuilderVisible(true);
|
||||
return;
|
||||
}
|
||||
}, [ setIsSelectorVisible, setIsCameraVisible, setIsBuilderVisible ]);
|
||||
|
||||
return (<>
|
||||
{ isSelectorVisible && <NitroCardView className="nitro-room-thumbnail">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.thumbeditor.caption') } onCloseClick={ () => setIsSelectorVisible(false) } />
|
||||
<NitroCardContentView className="d-flex align-items-center justify-content-center text-muted">
|
||||
<div className="option me-5" onClick={ () => handleAction('camera') }>
|
||||
<i className="fas fa-camera" />
|
||||
</div>
|
||||
<div className="option" onClick={ () => handleAction('builder') }>
|
||||
<i className="fas fa-pencil-ruler" />
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView> }
|
||||
{ isBuilderVisible && <RoomThumbnailWidgetBuilderView onCloseClick={ () => setIsBuilderVisible(false) } /> }
|
||||
{ isCameraVisible && <RoomThumbnailWidgetCameraView onCloseClick={ () => setIsCameraVisible(false) } /> }
|
||||
</>);
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
export class RoomThumbnailWidgetBuilderViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.nitro-room-thumbnail-builder {
|
||||
width: 600px;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../../layout';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import { RoomThumbnailWidgetBuilderViewProps } from './RoomThumbnailWidgetBuilderView.props';
|
||||
|
||||
const TABS: string[] = [
|
||||
'navigator.thumbeditor.bgtab',
|
||||
'navigator.thumbeditor.objtab',
|
||||
'navigator.thumbeditor.toptab',
|
||||
];
|
||||
|
||||
export const RoomThumbnailWidgetBuilderView: FC<RoomThumbnailWidgetBuilderViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
|
||||
const [ currentTab, setCurrentTab ] = useState(TABS[0]);
|
||||
|
||||
const processAction = useCallback((action: string, value?: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'change_tab':
|
||||
setCurrentTab(value);
|
||||
return;
|
||||
}
|
||||
}, [ setCurrentTab ]);
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-room-thumbnail-builder">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('navigator.thumbeditor.caption') } onCloseClick={ onCloseClick } />
|
||||
<div className="d-flex">
|
||||
<div className="w-100">
|
||||
<NitroCardTabsView>
|
||||
{ TABS.map(tab =>
|
||||
{
|
||||
return <NitroCardTabsItemView key={ tab } isActive={ currentTab === tab } onClick={ event => processAction('change_tab', tab) }>
|
||||
{ LocalizeText(tab) }
|
||||
</NitroCardTabsItemView>
|
||||
}) }
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView>
|
||||
<div className="d-flex h-100 overflow-auto effects px-2">
|
||||
<div className="row row-cols-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</div>
|
||||
<div>
|
||||
<NitroCardTabsView></NitroCardTabsView>
|
||||
<NitroCardContentView>
|
||||
<div className="d-flex justify-content-between mt-2">
|
||||
<div className="d-flex justify-content-end">
|
||||
<button className="btn btn-primary me-2" onClick={ event => processAction('cancel') }>{ LocalizeText('generic.cancel') }</button>
|
||||
<button className="btn btn-success" onClick={ event => processAction('checkout') }>{ LocalizeText('camera.preview.button.text') }</button>
|
||||
</div>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</div>
|
||||
</div>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
.nitro-room-thumbnail-camera {
|
||||
width: 132px;
|
||||
height: 192px;
|
||||
background-image: url('../../../../../../assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png');
|
||||
|
||||
.camera-frame {
|
||||
position: absolute;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
margin-top: 38px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
import { NitroRectangle } from 'nitro-renderer';
|
||||
import { FC, useCallback, useRef } from 'react';
|
||||
import { GetRoomEngine, GetRoomSession } from '../../../../../../api';
|
||||
import { DraggableWindow } from '../../../../../../layout';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import { RoomThumbnailWidgetCameraViewProps } from './RoomThumbnailWidgetCameraView.types';
|
||||
|
||||
export const RoomThumbnailWidgetCameraView: FC<RoomThumbnailWidgetCameraViewProps> = props =>
|
||||
{
|
||||
const { onCloseClick = null } = props;
|
||||
|
||||
const cameraFrameRef = useRef<HTMLDivElement>();
|
||||
|
||||
const takePicture = useCallback(() =>
|
||||
{
|
||||
const frameBounds = cameraFrameRef.current.getBoundingClientRect();
|
||||
|
||||
if(!frameBounds) return;
|
||||
|
||||
const rectangle = new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height));
|
||||
|
||||
const image = GetRoomEngine().createRoomScreenshot(GetRoomSession().roomId, 1, rectangle);
|
||||
|
||||
//SendMessageHook(new RoomWidgetCameraRoomThumbnailComposer(0, []));
|
||||
onCloseClick();
|
||||
}, [ onCloseClick ]);
|
||||
|
||||
return (
|
||||
<DraggableWindow handle=".nitro-room-thumbnail-camera">
|
||||
<div className="nitro-room-thumbnail-camera px-2">
|
||||
<div ref={ cameraFrameRef } className={ 'camera-frame' }></div>
|
||||
<div className="d-flex align-items-end h-100 pb-2">
|
||||
<button className="btn btn-sm btn-danger w-100 mb-1 me-2" onClick={ onCloseClick }>{ LocalizeText('cancel') }</button>
|
||||
<button className="btn btn-sm btn-success w-100 mb-1" onClick={ () => takePicture() }>{ LocalizeText('navigator.thumbeditor.save') }</button>
|
||||
</div>
|
||||
</div>
|
||||
</DraggableWindow>
|
||||
);
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
export class RoomThumbnailWidgetCameraViewProps
|
||||
{
|
||||
onCloseClick: () => void;
|
||||
}
|
39
src/views/room/widgets/room-tools/RoomToolsWidgetView.scss
Normal file
39
src/views/room/widgets/room-tools/RoomToolsWidgetView.scss
Normal file
@ -0,0 +1,39 @@
|
||||
.nitro-room-tools {
|
||||
position: fixed;
|
||||
bottom: 125px;
|
||||
left: -133px;
|
||||
background: rgba($dark,.95);
|
||||
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
||||
border-top-right-radius: $border-radius;
|
||||
border-bottom-right-radius: $border-radius;
|
||||
transition: all .2s ease;
|
||||
|
||||
&.open {
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
background: transparent;
|
||||
padding: 3px 0px;
|
||||
color: $white;
|
||||
border-color: rgba($black, 0.3);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
}
|
68
src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx
Normal file
68
src/views/room/widgets/room-tools/RoomToolsWidgetView.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import classNames from 'classnames';
|
||||
import { RoomLikeRoomComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { NavigatorEvent } from '../../../../events';
|
||||
import { dispatchUiEvent } from '../../../../hooks/events';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { RoomWidgetZoomToggleMessage } from '../../messages';
|
||||
|
||||
export const RoomToolsWidgetView: FC<{}> = props =>
|
||||
{
|
||||
const { widgetHandler = null } = useRoomContext();
|
||||
|
||||
const [ isExpended, setIsExpanded ] = useState(false);
|
||||
const [ isZoomedIn, setIsZoomedIn ] = useState(false);
|
||||
const [ isLiked, setIsLiked ] = useState(false);
|
||||
|
||||
const handleToolClick = useCallback((action: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'settings':
|
||||
dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_INFO));
|
||||
return;
|
||||
case 'zoom':
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetZoomToggleMessage(!isZoomedIn));
|
||||
setIsZoomedIn(value => !value);
|
||||
return;
|
||||
case 'chat_history':
|
||||
return;
|
||||
case 'like_room':
|
||||
if(isLiked) return;
|
||||
|
||||
SendMessageHook(new RoomLikeRoomComposer(1));
|
||||
setIsLiked(true);
|
||||
return;
|
||||
case 'toggle_room_link':
|
||||
dispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK));
|
||||
return;
|
||||
}
|
||||
}, [ isZoomedIn, isLiked, widgetHandler ]);
|
||||
|
||||
return (
|
||||
<div className={'nitro-room-tools ps-3 d-flex' + classNames({' open': isExpended})}>
|
||||
<div className="list-group list-group-flush w-100 me-1">
|
||||
<div className="list-group-item" onClick={ () => handleToolClick('settings') }>
|
||||
<i className="fas fa-cog me-2" />{ LocalizeText('room.settings.button.text') }
|
||||
</div>
|
||||
<div className="list-group-item" onClick={ () => handleToolClick('zoom') }>
|
||||
<i className={ 'fas me-2 ' +classNames({'fa-search-minus': !isZoomedIn, 'fa-search-plus': isZoomedIn}) } />{ LocalizeText('room.zoom.button.text') }
|
||||
</div>
|
||||
<div className="list-group-item" onClick={ () => handleToolClick('chat_history') }>
|
||||
<i className="fas fa-comment-alt me-2" />{ LocalizeText('room.chathistory.button.text') }
|
||||
</div>
|
||||
<div className={ 'list-group-item' + classNames({' disabled': isLiked})} onClick={ () => handleToolClick('like_room') }>
|
||||
<i className="fas fa-heart me-2" />{ LocalizeText('room.like.button.text') }
|
||||
</div>
|
||||
<div className="list-group-item" onClick={ () => handleToolClick('toggle_room_link') }>
|
||||
<i className="fas fa-link me-2" />{ LocalizeText('navigator.embed.caption') }
|
||||
</div>
|
||||
</div>
|
||||
<div className="cursor-pointer d-flex align-items-center px-2" onClick={() => setIsExpanded(value => !value)}>
|
||||
<i className={ 'fas ' + classNames({'fa-chevron-left': isExpended, 'fa-chevron-right': !isExpended}) } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user