mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Navigator updates
This commit is contained in:
parent
2b10284506
commit
1308036a51
@ -1,24 +1,63 @@
|
||||
.nitro-navigator {
|
||||
width: $navigator-width;
|
||||
height: $navigator-height;
|
||||
}
|
||||
|
||||
.nitro-navigator-doorbell {
|
||||
width: 250px;
|
||||
.navigator-grid {
|
||||
|
||||
.content-area {
|
||||
min-height: 143px;
|
||||
height: 143px;
|
||||
.navigator-item {
|
||||
|
||||
.badge {
|
||||
width: 35px;
|
||||
min-width: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.two-columns) {
|
||||
|
||||
.navigator-item {
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: $grid-active-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.two-columns {
|
||||
|
||||
.navigator-item {
|
||||
|
||||
&:nth-child(4n-2),
|
||||
&:nth-child(4n-3) {
|
||||
background: $grid-active-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-navigator-doorbell,
|
||||
.nitro-navigator-password {
|
||||
width: 250px;
|
||||
|
||||
.content-area {
|
||||
min-height: 218px;
|
||||
height: 218px;
|
||||
}
|
||||
}
|
||||
|
||||
@import './views/NavigatorViews';
|
||||
.nitro-room-info {
|
||||
width: $room-info-width;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.nitro-room-link {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.nitro-room-settings {
|
||||
width: 400px;
|
||||
|
||||
.list-container {
|
||||
min-height: 100px;
|
||||
max-height: 100px;
|
||||
|
||||
.list-item {
|
||||
background-color: $grid-active-bg-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useReducer, useState } from 'react';
|
||||
import { AddEventLinkTracker, GoToDesktop, LocalizeText, RemoveLinkEventTracker, TryVisitRoom } from '../../api';
|
||||
import { Column } from '../../common/Column';
|
||||
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events';
|
||||
import { UseMountEffect } from '../../hooks';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
@ -246,15 +248,17 @@ export const NavigatorView: FC<{}> = props =>
|
||||
</NitroCardTabsItemView>
|
||||
);
|
||||
}) }
|
||||
<NitroCardTabsItemView isActive={ isCreatorOpen } onClick={ () => setCreatorOpen(true) }>
|
||||
<i className="fas fa-plus" />
|
||||
<NitroCardTabsItemView isActive={ isCreatorOpen } onClick={ event => setCreatorOpen(true) }>
|
||||
<FontAwesomeIcon icon="plus" />
|
||||
</NitroCardTabsItemView>
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView>
|
||||
{ !isCreatorOpen &&
|
||||
<>
|
||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||
{ (navigatorState.searchResult && navigatorState.searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||
<Column overflow="auto">
|
||||
{ (navigatorState.searchResult && navigatorState.searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||
</Column>
|
||||
</> }
|
||||
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
|
||||
</NitroCardContentView>
|
||||
|
@ -1,10 +1,3 @@
|
||||
import { NavigatorSearchResultList } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface NavigatorSearchResultViewProps
|
||||
{
|
||||
searchResult: NavigatorSearchResultList;
|
||||
}
|
||||
|
||||
export class NavigatorSearchResultViewDisplayMode
|
||||
{
|
||||
public static readonly LIST: number = 0;
|
@ -1,11 +1,13 @@
|
||||
import { HabboClubLevelEnum } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface NavigatorRoomCreatorViewProps
|
||||
export interface IRoomModel
|
||||
{
|
||||
|
||||
clubLevel: number;
|
||||
tileSize: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const NAVIGATOR_ROOM_MODELS: { clubLevel: number, tileSize: number, name: string }[] = [
|
||||
export const RoomModels: IRoomModel[] = [
|
||||
{ clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 104, name: 'a' },
|
||||
{ clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 94, name: 'b' },
|
||||
{ clubLevel: HabboClubLevelEnum.NO_CLUB, tileSize: 36, name: 'c' },
|
@ -1,6 +0,0 @@
|
||||
@import './creator/NavigatorRoomCreatorView';
|
||||
@import './search-result/NavigatorSearchResultView';
|
||||
@import './search-result-item/NavigatorSearchResultItemView';
|
||||
@import './room-info/NavigatorRoomInfoView';
|
||||
@import './room-link/NavigatorRoomLinkView';
|
||||
@import './room-settings/NavigatorRoomSettingsView';
|
@ -1,26 +0,0 @@
|
||||
.room-model-list {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
scroll-behavior: smooth;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
> div {
|
||||
border-color: $grid-border-color !important;
|
||||
background-color: $grid-bg-color;
|
||||
|
||||
&.active {
|
||||
border-color: $grid-active-border-color !important;
|
||||
background-color: $grid-active-bg-color;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
img {
|
||||
opacity: .5;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +1,47 @@
|
||||
/* eslint-disable no-template-curly-in-string */
|
||||
import { HabboClubLevelEnum, RoomCreateComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { GetConfiguration, GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { Grid } from '../../../../common/Grid';
|
||||
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
import { SendMessageHook } from '../../../../hooks/messages';
|
||||
import { CurrencyIcon } from '../../../../views/shared/currency-icon/CurrencyIcon';
|
||||
import { IRoomModel, RoomModels } from '../../common/RoomModels';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
import { NavigatorRoomCreatorViewProps, NAVIGATOR_ROOM_MODELS } from './NavigatorRoomCreatorView.types';
|
||||
|
||||
export const NavigatorRoomCreatorView: FC<NavigatorRoomCreatorViewProps> = props =>
|
||||
export const NavigatorRoomCreatorView: FC<{}> = props =>
|
||||
{
|
||||
const [ maxVisitorsList, setMaxVisitorsList ] = useState<number[]>(null);
|
||||
const [ name, setName ] = useState<string>(null);
|
||||
const [ description, setDescription ] = useState<string>(null);
|
||||
const [ category, setCategory ] = useState<number>(null);
|
||||
const [ visitorsCount, setVisitorsCount ] = useState<number>(null);
|
||||
const [ tradesSetting, setTradesSetting ] = useState<number>(0);
|
||||
const [ selectedModelName, setSelectedModelName ] = useState<string>(RoomModels[0].name);
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { categories = null } = navigatorState;
|
||||
|
||||
const [ maxVisitorsList, setMaxVisitorsList ] = useState(null);
|
||||
const [ name, setName ] = useState(null);
|
||||
const [ description, setDescription ] = useState(null);
|
||||
const [ category, setCategory ] = useState(null);
|
||||
const [ visitorsCount, setVisitorsCount ] = useState(null);
|
||||
const [ tradesSetting, setTradesSetting ] = useState(0);
|
||||
const [ selectedModelName, setSelectedModelName ] = useState(NAVIGATOR_ROOM_MODELS[0].name);
|
||||
const getRoomModelImage = (name: string) => GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`;
|
||||
|
||||
const selectModel = (model: IRoomModel) =>
|
||||
{
|
||||
if(!model) return;
|
||||
|
||||
if(model.clubLevel > GetSessionDataManager().clubLevel) return;
|
||||
|
||||
setSelectedModelName(name);
|
||||
}
|
||||
|
||||
const createRoom = () =>
|
||||
{
|
||||
if(!name || name.length < 3) return;
|
||||
|
||||
SendMessageHook(new RoomCreateComposer(name, description, 'model_' + selectedModelName, Number(category), Number(visitorsCount), tradesSetting));
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -27,13 +49,13 @@ export const NavigatorRoomCreatorView: FC<NavigatorRoomCreatorViewProps> = props
|
||||
{
|
||||
const list = [];
|
||||
|
||||
for(let i = 10; i <= 100; i = i + 10)
|
||||
{
|
||||
list.push(i);
|
||||
}
|
||||
for(let i = 10; i <= 100; i = i + 10) list.push(i);
|
||||
|
||||
setMaxVisitorsList(list);
|
||||
setVisitorsCount(list[0]);
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setMaxVisitorsList(list);
|
||||
setVisitorsCount(list[0]);
|
||||
});
|
||||
}
|
||||
}, [ maxVisitorsList ]);
|
||||
|
||||
@ -41,89 +63,60 @@ export const NavigatorRoomCreatorView: FC<NavigatorRoomCreatorViewProps> = props
|
||||
{
|
||||
if(categories) setCategory(categories[0].id);
|
||||
}, [ categories ]);
|
||||
|
||||
const getRoomModelImage = useCallback((name: string) =>
|
||||
{
|
||||
return GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`;
|
||||
}, []);
|
||||
|
||||
const selectModel = useCallback((name: string) =>
|
||||
{
|
||||
const model = NAVIGATOR_ROOM_MODELS.find(model => model.name === name);
|
||||
|
||||
if(!model) return;
|
||||
|
||||
if(model.clubLevel > GetSessionDataManager().clubLevel) return;
|
||||
|
||||
setSelectedModelName(name);
|
||||
}, [ setSelectedModelName ]);
|
||||
|
||||
const createRoom = useCallback(() =>
|
||||
{
|
||||
if(!name || name.length < 3) return;
|
||||
|
||||
SendMessageHook(new RoomCreateComposer(name, description, 'model_' + selectedModelName, Number(category), Number(visitorsCount), tradesSetting));
|
||||
}, [ name, description, category, visitorsCount, tradesSetting, selectedModelName ]);
|
||||
|
||||
return (
|
||||
<div className="text-black d-flex flex-column h-100 justify-content-center">
|
||||
<div className="row row-cols-2 mb-2">
|
||||
<div className="col mb-2">
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.createroom.roomnameinfo') }</label>
|
||||
<input type="text" className="form-control form-control-sm" onChange={ (e) => setName(e.target.value) } />
|
||||
</div>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.category') }</label>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setCategory(e.target.value) }>
|
||||
{ categories && categories.map(category =>
|
||||
{
|
||||
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.maxvisitors') }</label>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setVisitorsCount(e.target.value) }>
|
||||
{ maxVisitorsList && maxVisitorsList.map(value =>
|
||||
{
|
||||
return <option key={ value } value={ value }>{ value }</option>
|
||||
}) }
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col">
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('navigator.tradesettings') }</label>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setTradesSetting(Number(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>
|
||||
</div>
|
||||
<div className="form-group mb-3">
|
||||
<label>{ LocalizeText('navigator.createroom.roomdescinfo') }</label>
|
||||
<Column overflow="hidden">
|
||||
<Grid fullHeight={ false }>
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.createroom.roomnameinfo') }</Text>
|
||||
<input type="text" className="form-control form-control-sm" onChange={ (e) => setName(e.target.value) } />
|
||||
</Column>
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.category') }</Text>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setCategory(Number(e.target.value)) }>
|
||||
{ categories && categories.map(category =>
|
||||
{
|
||||
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
|
||||
}) }
|
||||
</select>
|
||||
</Column>
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.maxvisitors') }</Text>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setVisitorsCount(Number(e.target.value)) }>
|
||||
{ maxVisitorsList && maxVisitorsList.map(value =>
|
||||
{
|
||||
return <option key={ value } value={ value }>{ value }</option>
|
||||
}) }
|
||||
</select>
|
||||
</Column>
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.tradesettings') }</Text>
|
||||
<select className="form-select form-select-sm" onChange={ (e) => setTradesSetting(Number(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>
|
||||
</Column>
|
||||
</Grid>
|
||||
<Column gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.createroom.roomdescinfo') }</Text>
|
||||
<input type="text" className="form-control form-control-sm" onChange={ (e) => setDescription(e.target.value) } />
|
||||
</div>
|
||||
<div className="room-model-list pb-2 mb-2">
|
||||
</Column>
|
||||
<Flex overflow="auto" gap={ 1 }>
|
||||
{
|
||||
NAVIGATOR_ROOM_MODELS.map(model =>
|
||||
RoomModels.map(model =>
|
||||
{
|
||||
return (<div key={ model.name } onClick={ () => selectModel(model.name) } className={ 'h-100 cursor-pointer d-flex flex-column justify-content-center align-items-center p-1 me-2 rounded border border-2' + classNames({ ' active': selectedModelName === model.name, ' disabled': GetSessionDataManager().clubLevel < model.clubLevel }) }>
|
||||
<img alt="" src={ getRoomModelImage(model.name) } />
|
||||
<div>{ model.tileSize } { LocalizeText('navigator.createroom.tilesize') }</div>
|
||||
{ model.clubLevel > HabboClubLevelEnum.NO_CLUB && <CurrencyIcon type="hc" /> }
|
||||
</div>);
|
||||
return (<LayoutGridItem fullHeight key={ model.name } onClick={ () => selectModel(model) } itemActive={ (selectedModelName === model.name) } overflow="unset" gap={ 0 } className="p-1" disabled={ (GetSessionDataManager().clubLevel < model.clubLevel) }>
|
||||
<Flex fullHeight center overflow="hidden">
|
||||
<img alt="" src={ getRoomModelImage(model.name) } />
|
||||
</Flex>
|
||||
<Text bold>{ model.tileSize } { LocalizeText('navigator.createroom.tilesize') }</Text>
|
||||
{ model.clubLevel > HabboClubLevelEnum.NO_CLUB && <CurrencyIcon position="absolute" className="top-1 end-1" type="hc" /> }
|
||||
</LayoutGridItem>);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</Flex>
|
||||
<button className="btn btn-success float-end" onClick={ () => createRoom() } disabled={ !name || name.length < 3 }>{ LocalizeText('navigator.createroom.create') }</button>
|
||||
</div>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
@ -1,41 +1,60 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { CreateRoomSession, GoToDesktop, LocalizeText } from '../../../../api';
|
||||
import { Button } from '../../../../common/Button';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { UpdateDoorStateEvent } from '../../../../events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NavigatorRoomDoorbellViewProps } from './NavigatorRoomDoorbellView.types';
|
||||
|
||||
export interface NavigatorRoomDoorbellViewProps
|
||||
{
|
||||
roomData: RoomDataParser;
|
||||
state: string;
|
||||
onClose: (state: string) => void;
|
||||
}
|
||||
|
||||
export const NavigatorRoomDoorbellView: FC<NavigatorRoomDoorbellViewProps> = props =>
|
||||
{
|
||||
const { roomData = null, state = null, onClose = null } = props;
|
||||
|
||||
const close = useCallback(() =>
|
||||
const close = () =>
|
||||
{
|
||||
if(state === UpdateDoorStateEvent.STATE_WAITING) GoToDesktop();
|
||||
|
||||
onClose(null);
|
||||
}, [ state, onClose ]);
|
||||
}
|
||||
|
||||
const ring = useCallback(() =>
|
||||
const ring = () =>
|
||||
{
|
||||
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>
|
||||
<Column gap={ 1 }>
|
||||
{ roomData &&
|
||||
<Text bold>{ roomData.roomName }</Text> }
|
||||
{ (state === UpdateDoorStateEvent.START_DOORBELL) &&
|
||||
<Text>{ LocalizeText('navigator.doorbell.info') }</Text> }
|
||||
{ (state === UpdateDoorStateEvent.STATE_WAITING) &&
|
||||
<Text>{ LocalizeText('navigator.doorbell.waiting') }</Text> }
|
||||
{ (state === UpdateDoorStateEvent.STATE_NO_ANSWER) &&
|
||||
<Text>{ LocalizeText('navigator.doorbell.no.answer') }</Text> }
|
||||
</Column>
|
||||
{ (state === UpdateDoorStateEvent.START_DOORBELL) &&
|
||||
<Button variant="success" size="sm" onClick={ ring }>
|
||||
{ LocalizeText('navigator.doorbell.button.ring') }
|
||||
</Button> }
|
||||
<Button variant="danger" size="sm" onClick={ close }>
|
||||
{ LocalizeText('generic.cancel') }
|
||||
</Button>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface NavigatorRoomDoorbellViewProps
|
||||
{
|
||||
roomData: RoomDataParser;
|
||||
state: string;
|
||||
onClose: (state: string) => void;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
.nitro-room-info {
|
||||
width: $room-info-width;
|
||||
max-height: 300px;
|
||||
|
||||
|
||||
.gray {
|
||||
filter: grayscale(1);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.room-thumbnail {
|
||||
position: relative;
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
background: url("../../../../assets/images/navigator/thumbnail_placeholder.png") no-repeat center;
|
||||
background-color: rgba($black, .125);
|
||||
}
|
||||
|
||||
.group-badge {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
@ -133,11 +133,9 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
|
||||
{ roomInfoData.enteredGuestRoom &&
|
||||
<>
|
||||
<Flex gap={ 2 } overflow="hidden">
|
||||
<Flex center>
|
||||
<RoomThumbnailView customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef }>
|
||||
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
||||
</RoomThumbnailView>
|
||||
</Flex>
|
||||
<RoomThumbnailView customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef }>
|
||||
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
|
||||
</RoomThumbnailView>
|
||||
<Column grow gap={ 1 } overflow="hidden">
|
||||
<Flex gap={ 1 }>
|
||||
<Column grow gap={ 1 }>
|
||||
|
@ -1,3 +0,0 @@
|
||||
.nitro-room-link {
|
||||
width: 400px;
|
||||
}
|
@ -1,18 +1,28 @@
|
||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { CreateRoomSession, LocalizeText } from '../../../../api';
|
||||
import { Button } from '../../../../common/Button';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { UpdateDoorStateEvent } from '../../../../events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { NavigatorRoomPasswordViewProps } from './NavigatorRoomPasswordView.types';
|
||||
|
||||
export interface NavigatorRoomPasswordViewProps
|
||||
{
|
||||
roomData: RoomDataParser;
|
||||
state: string;
|
||||
onClose: (state: string) => void;
|
||||
}
|
||||
|
||||
export const NavigatorRoomPasswordView: FC<NavigatorRoomPasswordViewProps> = props =>
|
||||
{
|
||||
const { roomData = null, state = null, onClose = null } = props;
|
||||
const [ password, setPassword ] = useState('');
|
||||
|
||||
const close = useCallback(() =>
|
||||
const close = () =>
|
||||
{
|
||||
onClose(null);
|
||||
}, [ onClose ]);
|
||||
}
|
||||
|
||||
const tryEntering = useCallback(() =>
|
||||
{
|
||||
@ -26,18 +36,24 @@ export const NavigatorRoomPasswordView: FC<NavigatorRoomPasswordViewProps> = pro
|
||||
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>
|
||||
<NitroCardContentView>
|
||||
<Column gap={ 1 }>
|
||||
{ roomData &&
|
||||
<Text bold>{ roomData.roomName }</Text> }
|
||||
{ (state === UpdateDoorStateEvent.START_PASSWORD) &&
|
||||
<Text>{ LocalizeText('navigator.password.info') }</Text> }
|
||||
{ (state === UpdateDoorStateEvent.STATE_WRONG_PASSWORD) &&
|
||||
<Text>{ LocalizeText('navigator.password.retryinfo') }</Text> }
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.password.enter') }</Text>
|
||||
<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>
|
||||
</Column>
|
||||
<Button variant="success" size="sm" onClick={ tryEntering }>
|
||||
{ LocalizeText('navigator.password.button.try') }</Button>
|
||||
<Button variant="danger" size="sm" onClick={ close }>
|
||||
{ LocalizeText('generic.cancel') }
|
||||
</Button>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,8 +0,0 @@
|
||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
|
||||
export interface NavigatorRoomPasswordViewProps
|
||||
{
|
||||
roomData: RoomDataParser;
|
||||
state: string;
|
||||
onClose: (state: string) => void;
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
.nitro-room-settings {
|
||||
width: 400px;
|
||||
|
||||
.user-rights-container {
|
||||
|
||||
.row {
|
||||
|
||||
.col:nth-child(even) {
|
||||
//background: $light !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-container {
|
||||
max-height: 100px;
|
||||
min-height: 100px;
|
||||
overflow-y: scroll;
|
||||
background-color: white;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
|
||||
&.rights {
|
||||
max-height: 80%;
|
||||
min-height: 80%;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
&.friends-rights {
|
||||
max-height: 90%;
|
||||
min-height: 90%;
|
||||
}
|
||||
|
||||
.rights-button
|
||||
{
|
||||
float: right;
|
||||
margin: 2px;
|
||||
font-size: 7px;
|
||||
padding: 3px;
|
||||
min-height: unset;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
&.selected {
|
||||
background-color: cadetblue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,14 @@
|
||||
import { RoomBannedUsersComposer, RoomBannedUsersEvent, RoomSettingsEvent, RoomUsersWithRightsComposer, RoomUsersWithRightsEvent, SaveRoomSettingsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { FriendsEvent } from '../../../../events';
|
||||
import { FriendListContentEvent } from '../../../../events/friends/FriendListContentEvent';
|
||||
import { dispatchUiEvent, useUiEvent } from '../../../../hooks';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../layout';
|
||||
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||
import { NavigatorRoomSettingsAccessTabView } from './views/tab-access/NavigatorRoomSettingsAccessTabView';
|
||||
import { NavigatorRoomSettingsBasicTabView } from './views/tab-basic/NavigatorRoomSettingsBasicTabView';
|
||||
import { NavigatorRoomSettingsModTabView } from './views/tab-mod/NavigatorRoomSettingsModTabView';
|
||||
import { NavigatorRoomSettingsRightsTabView } from './views/tab-rights/NavigatorRoomSettingsRightsTabView';
|
||||
import { NavigatorRoomSettingsVipChatTabView } from './views/tab-vipchat/NavigatorRoomSettingsVipChatTabView';
|
||||
import { NavigatorRoomSettingsAccessTabView } from './views/NavigatorRoomSettingsAccessTabView';
|
||||
import { NavigatorRoomSettingsBasicTabView } from './views/NavigatorRoomSettingsBasicTabView';
|
||||
import { NavigatorRoomSettingsModTabView } from './views/NavigatorRoomSettingsModTabView';
|
||||
import { NavigatorRoomSettingsRightsTabView } from './views/NavigatorRoomSettingsRightsTabView';
|
||||
import { NavigatorRoomSettingsVipChatTabView } from './views/NavigatorRoomSettingsVipChatTabView';
|
||||
|
||||
const TABS: string[] = [
|
||||
'navigator.roomsettings.tab.1',
|
||||
@ -25,7 +22,6 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
{
|
||||
const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null);
|
||||
const [ currentTab, setCurrentTab ] = useState(TABS[0]);
|
||||
const [ friends, setFriends ] = useState<Map<number, string>>(new Map());
|
||||
|
||||
const updateSettings = useCallback((roomSettings: RoomSettingsData) =>
|
||||
{
|
||||
@ -73,24 +69,11 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
setRoomSettingsData(data);
|
||||
}, [roomSettingsData]);
|
||||
|
||||
const onFriendsListContentEvent = useCallback((event: FriendListContentEvent) =>
|
||||
{
|
||||
if(!roomSettingsData || !event.friends) return;
|
||||
|
||||
setFriends(event.friends);
|
||||
}, [roomSettingsData]);
|
||||
|
||||
CreateMessageHook(RoomSettingsEvent, onRoomSettingsEvent);
|
||||
CreateMessageHook(RoomUsersWithRightsEvent, onRoomUsersWithRightsEvent);
|
||||
CreateMessageHook(RoomBannedUsersEvent, onRoomBannedUsersEvent);
|
||||
useUiEvent(FriendListContentEvent.FRIEND_LIST_CONTENT, onFriendsListContentEvent);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(roomSettingsData) dispatchUiEvent(new FriendsEvent(FriendsEvent.REQUEST_FRIEND_LIST));
|
||||
}, [roomSettingsData])
|
||||
|
||||
const save = useCallback((data: RoomSettingsData) =>
|
||||
const saveSettings = useCallback((data: RoomSettingsData) =>
|
||||
{
|
||||
SendMessageHook(
|
||||
new SaveRoomSettingsComposer(
|
||||
@ -132,6 +115,109 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
}
|
||||
}, [ setRoomSettingsData ]);
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = Object.assign({}, 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;
|
||||
case 'allow_pets':
|
||||
roomSettings.allowPets = Boolean(value);
|
||||
break;
|
||||
case 'allow_pets_eat':
|
||||
roomSettings.allowPetsEat = Boolean(value);
|
||||
break;
|
||||
case 'hide_walls':
|
||||
roomSettings.hideWalls = Boolean(value);
|
||||
break;
|
||||
case 'wall_thickness':
|
||||
roomSettings.wallThickness = Number(value);
|
||||
break;
|
||||
case 'floor_thickness':
|
||||
roomSettings.floorThickness = Number(value);
|
||||
break;
|
||||
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 'moderation_mute':
|
||||
roomSettings.muteState = Number(value);
|
||||
break;
|
||||
case 'moderation_kick':
|
||||
roomSettings.kickState = Number(value);
|
||||
break;
|
||||
case 'moderation_ban':
|
||||
roomSettings.banState = Number(value);
|
||||
break;
|
||||
case 'bubble_mode':
|
||||
roomSettings.chatBubbleMode = Number(value);
|
||||
break;
|
||||
case 'chat_weight':
|
||||
roomSettings.chatBubbleWeight = Number(value);
|
||||
break;
|
||||
case 'bubble_speed':
|
||||
roomSettings.chatBubbleSpeed = Number(value);
|
||||
break;
|
||||
case 'flood_protection':
|
||||
roomSettings.chatFloodProtection = Number(value);
|
||||
break;
|
||||
case 'chat_distance':
|
||||
roomSettings.chatDistance = Number(value);
|
||||
save = false;
|
||||
break;
|
||||
case 'unban_user':
|
||||
roomSettings.bannedUsers.delete(Number(value));
|
||||
save = false;
|
||||
break;
|
||||
case 'remove_rights_user':
|
||||
roomSettings.usersWithRights.delete(Number(value));
|
||||
save = false;
|
||||
break;
|
||||
case 'remove_all_rights':
|
||||
roomSettings.usersWithRights.clear();
|
||||
save = false;
|
||||
break;
|
||||
case 'save':
|
||||
save = true;
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(roomSettings);
|
||||
|
||||
if(save) saveSettings(roomSettings);
|
||||
}, [ roomSettingsData, saveSettings ]);
|
||||
|
||||
if(!roomSettingsData) return null;
|
||||
|
||||
return (
|
||||
@ -143,12 +229,17 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
|
||||
return <NitroCardTabsItemView key={ tab } isActive={ (currentTab === tab) } onClick={ event => setCurrentTab(tab) }>{ LocalizeText(tab) }</NitroCardTabsItemView>
|
||||
}) }
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView className="text-black">
|
||||
{ currentTab === TABS[0] && <NavigatorRoomSettingsBasicTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[1] && <NavigatorRoomSettingsAccessTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[2] && <NavigatorRoomSettingsRightsTabView roomSettingsData= {roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } friends={friends} /> }
|
||||
{ currentTab === TABS[3] && <NavigatorRoomSettingsVipChatTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
{ currentTab === TABS[4] && <NavigatorRoomSettingsModTabView roomSettingsData={ roomSettingsData } setRoomSettingsData={ updateSettings } onSave={ save } /> }
|
||||
<NitroCardContentView>
|
||||
{ currentTab === TABS[0] &&
|
||||
<NavigatorRoomSettingsBasicTabView roomSettingsData={ roomSettingsData } handleChange={ handleChange } /> }
|
||||
{ currentTab === TABS[1] &&
|
||||
<NavigatorRoomSettingsAccessTabView roomSettingsData={ roomSettingsData } handleChange={ handleChange } /> }
|
||||
{ currentTab === TABS[2] &&
|
||||
<NavigatorRoomSettingsRightsTabView roomSettingsData= {roomSettingsData } handleChange={ handleChange } /> }
|
||||
{ currentTab === TABS[3] &&
|
||||
<NavigatorRoomSettingsVipChatTabView roomSettingsData={ roomSettingsData } handleChange={ handleChange } /> }
|
||||
{ currentTab === TABS[4] &&
|
||||
<NavigatorRoomSettingsModTabView roomSettingsData={ roomSettingsData } handleChange={ handleChange } /> }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,8 +0,0 @@
|
||||
import RoomSettingsData from '../../common/RoomSettingsData';
|
||||
|
||||
export class NavigatorRoomSettingsTabViewProps
|
||||
{
|
||||
roomSettingsData: RoomSettingsData;
|
||||
setRoomSettingsData: (roomSettings: RoomSettingsData) => void;
|
||||
onSave: (data: RoomSettingsData) => void;
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Column } from '../../../../../common/Column';
|
||||
import { Flex } from '../../../../../common/Flex';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { NavigatorRoomSettingsTabViewProps } from './NavigatorRoomSettingsTabViewProps.types';
|
||||
|
||||
export const NavigatorRoomSettingsAccessTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, handleChange = null } = props;
|
||||
|
||||
const isPasswordValid = useCallback(() =>
|
||||
{
|
||||
return (roomSettingsData.password && (roomSettingsData.password.length > 0) && (roomSettingsData.password === roomSettingsData.confirmPassword));
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const trySave = useCallback(() =>
|
||||
{
|
||||
if(isPasswordValid()) handleChange('save', null);
|
||||
}, [ isPasswordValid, handleChange ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.roomaccess.caption') }</Text>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.roomaccess.info') }</Text>
|
||||
</Column>
|
||||
<Column overflow="auto">
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.doormode') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ (roomSettingsData.lockState === 0) } onChange={ event => handleChange('lock_state', 0) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.open') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ (roomSettingsData.lockState === 1) } onChange={ event => handleChange('lock_state', 1) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.doorbell') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ (roomSettingsData.lockState === 2) } onChange={ event => handleChange('lock_state', 2) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.invisible') }</Text>
|
||||
</Flex>
|
||||
<Flex fullWidth gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ (roomSettingsData.lockState === 3) } onChange={ event => handleChange('lock_state', 3) } />
|
||||
{ (roomSettingsData.lockState !== 3) &&
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text> }
|
||||
{ (roomSettingsData.lockState === 3) &&
|
||||
<Column gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text>
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.password ?? '' } onChange={ (e) => handleChange('password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.password') } />
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.confirmPassword ?? '' } onChange={ (e) => handleChange('confirm_password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.passwordconfirm') } />
|
||||
{ !isPasswordValid() &&
|
||||
<Text bold small variant="danger">
|
||||
{ LocalizeText('navigator.roomsettings.invalidconfirm') }
|
||||
</Text> }
|
||||
</Column> }
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.pets') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPets } onChange={ event => handleChange('allow_pets', event.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowpets') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPetsEat } onChange={ event => handleChange('allow_pets_eat', event.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowfoodconsume') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
</Column>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,66 +1,31 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { Base } from '../../../../../../common/Base';
|
||||
import { Flex } from '../../../../../../common/Flex';
|
||||
import { Text } from '../../../../../../common/Text';
|
||||
import { GetMaxVisitorsList } from '../../../../common/RoomSettingsUtils';
|
||||
import { useNavigatorContext } from '../../../../context/NavigatorContext';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
import { FC, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Base } from '../../../../../common/Base';
|
||||
import { Flex } from '../../../../../common/Flex';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { GetMaxVisitorsList } from '../../../common/RoomSettingsUtils';
|
||||
import { useNavigatorContext } from '../../../context/NavigatorContext';
|
||||
import { NavigatorRoomSettingsTabViewProps } from './NavigatorRoomSettingsTabViewProps.types';
|
||||
|
||||
const DESC_MAX_LENGTH = 255;
|
||||
|
||||
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
const { roomSettingsData = null, handleChange = null } = props;
|
||||
const [ maxVisitorsList, setMaxVisitorsList ] = useState(GetMaxVisitorsList());
|
||||
const { navigatorState = null } = useNavigatorContext();
|
||||
const { categories = null } = navigatorState;
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const roomSettings = Object.assign({}, 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(roomSettings);
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.roomname') }</Text>
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomName } onChange={ event => handleChange('name', event.target.value) } onBlur={ () => onSave(roomSettingsData) } />
|
||||
<input className="form-control form-control-sm" value={ roomSettingsData.roomName } onChange={ event => handleChange('name', event.target.value) } onBlur={ event => handleChange('save', null) } />
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.roomsettings.desc') }</Text>
|
||||
<textarea className="form-control form-control-sm" value={ roomSettingsData.roomDescription } onChange={ event => handleChange('description', event.target.value) } onBlur={ () => onSave(roomSettingsData) } maxLength={ DESC_MAX_LENGTH } />
|
||||
<textarea className="form-control form-control-sm" value={ roomSettingsData.roomDescription } onChange={ event => handleChange('description', event.target.value) } onBlur={ event => handleChange('save', null) } maxLength={ DESC_MAX_LENGTH } />
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<Text className="col-3">{ LocalizeText('navigator.category') }</Text>
|
@ -0,0 +1,47 @@
|
||||
import { RoomUnbanUserComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Base } from '../../../../../common/Base';
|
||||
import { Button } from '../../../../../common/Button';
|
||||
import { Column } from '../../../../../common/Column';
|
||||
import { Grid } from '../../../../../common/Grid';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { SendMessageHook } from '../../../../../hooks';
|
||||
import { NavigatorRoomSettingsTabViewProps } from './NavigatorRoomSettingsTabViewProps.types';
|
||||
|
||||
export const NavigatorRoomSettingsModTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, handleChange = null } = props;
|
||||
const [ selectedUserId, setSelectedUserId ] = useState<number>(-1);
|
||||
|
||||
const unBanUser = useCallback((userId: number) =>
|
||||
{
|
||||
handleChange('unban_user', userId)
|
||||
|
||||
SendMessageHook(new RoomUnbanUserComposer(userId, roomSettingsData.roomId));
|
||||
setSelectedUserId(-1);
|
||||
}, [ roomSettingsData, handleChange ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid overflow="auto">
|
||||
<Column size={ 6 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.moderation.banned.users') } ({ roomSettingsData.bannedUsers.size })</Text>
|
||||
<Column className="bg-white rounded" overflow="hidden">
|
||||
<Base className="list-container" overflow="auto">
|
||||
{ Array.from(roomSettingsData.bannedUsers.entries()).map(([id, name], index) =>
|
||||
{
|
||||
return <Text key={index} className={ ((id === selectedUserId) ? 'selected' : '') } onClick={ event => setSelectedUserId(id)}> { name }</Text>
|
||||
}) }
|
||||
</Base>
|
||||
</Column>
|
||||
</Column>
|
||||
<Column size={ 6 } justifyContent="end">
|
||||
<Button disabled={ (selectedUserId < 1) } onClick={ event => unBanUser(selectedUserId) }>
|
||||
{ LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId) }
|
||||
</Button>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
import { RemoveAllRightsMessageComposer, RoomTakeRightsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Button } from '../../../../../common/Button';
|
||||
import { Column } from '../../../../../common/Column';
|
||||
import { Flex } from '../../../../../common/Flex';
|
||||
import { Grid } from '../../../../../common/Grid';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { SendMessageHook } from '../../../../../hooks';
|
||||
import { UserProfileIconView } from '../../../../../layout';
|
||||
import { NavigatorRoomSettingsTabViewProps } from './NavigatorRoomSettingsTabViewProps.types';
|
||||
|
||||
export const NavigatorRoomSettingsRightsTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, handleChange = null } = props;
|
||||
|
||||
const removeUserRights = useCallback( (userId: number) =>
|
||||
{
|
||||
handleChange('remove_rights_user', userId);
|
||||
|
||||
SendMessageHook(new RoomTakeRightsComposer(userId));
|
||||
}, [ handleChange ]);
|
||||
|
||||
const removeAllRights = useCallback( () =>
|
||||
{
|
||||
handleChange('remove_all_rights', null);
|
||||
|
||||
SendMessageHook(new RemoveAllRightsMessageComposer(roomSettingsData.roomId));
|
||||
}, [ roomSettingsData, handleChange ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Grid overflow="auto">
|
||||
<Column size={ 6 }>
|
||||
<Text bold>
|
||||
{ LocalizeText('navigator.flatctrls.userswithrights', [ 'displayed', 'total' ], [ roomSettingsData.usersWithRights.size.toString(), roomSettingsData.usersWithRights.size.toString() ]) }
|
||||
</Text>
|
||||
<Column fullWidth className="bg-white rounded list-container p-2" overflow="auto" gap={ 1 }>
|
||||
{ Array.from(roomSettingsData.usersWithRights.entries()).map(([id, name], index) =>
|
||||
{
|
||||
return (
|
||||
<Flex key={ index } alignItems="center" gap={ 1 } overflow="hidden">
|
||||
<UserProfileIconView userName={ name } />
|
||||
<Text pointer grow key={index} onClick={ event => removeUserRights(id) }> { name }</Text>
|
||||
</Flex>
|
||||
);
|
||||
}) }
|
||||
</Column>
|
||||
<Button variant="danger" disabled={ !roomSettingsData.usersWithRights.size } onClick={ removeAllRights } >
|
||||
{ LocalizeText('navigator.flatctrls.clear') }
|
||||
</Button>
|
||||
</Column>
|
||||
<Column size={ 6 }>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.moderation.mute.header') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ (roomSettingsData.muteState === 1) } onChange={ event => handleChange('moderation_mute', (event.target.checked ? 1 : 0)) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.moderation.rights') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.moderation.kick.header')}</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ (roomSettingsData.kickState === 0) } onChange={ event => handleChange('moderation_kick', (event.target.checked ? 0 : 2)) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.moderation.all') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ ((roomSettingsData.kickState === 1) || (roomSettingsData.kickState === 0)) } disabled={ (roomSettingsData.kickState === 0) } onChange={ event => handleChange('moderation_kick', (event.target.checked ? 1 : 2)) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.moderation.rights') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.moderation.ban.header')}</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ (roomSettingsData.banState === 1) } onChange={ event => handleChange('moderation_ban', (event.target.checked ? 1 : 0)) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.moderation.rights') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
import RoomSettingsData from '../../../common/RoomSettingsData';
|
||||
|
||||
export class NavigatorRoomSettingsTabViewProps
|
||||
{
|
||||
roomSettingsData: RoomSettingsData;
|
||||
handleChange: (field: string, value: string | number | boolean) => void;
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { Column } from '../../../../../common/Column';
|
||||
import { Flex } from '../../../../../common/Flex';
|
||||
import { Grid } from '../../../../../common/Grid';
|
||||
import { Text } from '../../../../../common/Text';
|
||||
import { NavigatorRoomSettingsTabViewProps } from './NavigatorRoomSettingsTabViewProps.types';
|
||||
|
||||
export const NavigatorRoomSettingsVipChatTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, handleChange = null } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.vip.caption')}</Text>
|
||||
<Text>{LocalizeText('navigator.roomsettings.vip.info')}</Text>
|
||||
</Column>
|
||||
<Grid overflow="auto">
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.chat_settings')}</Text>
|
||||
<Text>{LocalizeText('navigator.roomsettings.chat_settings.info')}</Text>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleMode} onChange={event => handleChange('bubble_mode', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.mode.free.flow')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.mode.line.by.line')}</option>
|
||||
</select>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleWeight} onChange={event => handleChange('chat_weight', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.bubbles.width.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.bubbles.width.thin')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.bubbles.width.wide')}</option>
|
||||
</select>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleSpeed} onChange={event => handleChange('bubble_speed', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.speed.fast')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.speed.normal')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.speed.slow')}</option>
|
||||
</select>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatFloodProtection} onChange={event => handleChange('flood_protection', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.flood.loose')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.flood.normal')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.flood.strict')}</option>
|
||||
</select>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.chat_settings.hearing.distance') }</Text>
|
||||
<input type="number" min="0" className="form-control form-control-sm" value={roomSettingsData.chatDistance} onChange={event => handleChange('chat_distance', event.target.valueAsNumber)} onBlur={ event => handleChange('save', null) } />
|
||||
</Column>
|
||||
<Column size={ 6 } gap={ 1 }>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.vip_settings')}</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={roomSettingsData.hideWalls} onChange={(e) => handleChange('hide_walls', e.target.checked)} />
|
||||
<Text>{LocalizeText('navigator.roomsettings.hide_walls')}</Text>
|
||||
</Flex>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.wallThickness} onChange={event => handleChange('wall_thickness', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.wall_thickness.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.wall_thickness.thick')}</option>
|
||||
<option value="-1">{LocalizeText('navigator.roomsettings.wall_thickness.thin')}</option>
|
||||
<option value="-2">{LocalizeText('navigator.roomsettings.wall_thickness.thinnest')}</option>
|
||||
</select>
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.floorThickness} onChange={event => handleChange('floor_thickness', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.floor_thickness.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.floor_thickness.thick')}</option>
|
||||
<option value="-1">{LocalizeText('navigator.roomsettings.floor_thickness.thin')}</option>
|
||||
<option value="-2">{LocalizeText('navigator.roomsettings.floor_thickness.thinnest')}</option>
|
||||
</select>
|
||||
</Column>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { Column } from '../../../../../../common/Column';
|
||||
import { Flex } from '../../../../../../common/Flex';
|
||||
import { Text } from '../../../../../../common/Text';
|
||||
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 = Object.assign({}, 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(roomSettings);
|
||||
}, [ roomSettingsData, setRoomSettingsData, onSave ]);
|
||||
|
||||
const isPasswordValid = useCallback(() =>
|
||||
{
|
||||
return (roomSettingsData.password && (roomSettingsData.password.length > 0) && (roomSettingsData.password === roomSettingsData.confirmPassword));
|
||||
}, [ roomSettingsData ]);
|
||||
|
||||
const trySave = useCallback(() =>
|
||||
{
|
||||
if(isPasswordValid()) onSave(roomSettingsData);
|
||||
}, [isPasswordValid, onSave, roomSettingsData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text bold>{LocalizeText('navigator.roomsettings.roomaccess.caption')}</Text>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.roomaccess.info') }</Text>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.doormode') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 0 } onChange={ (e) => handleChange('lock_state', 0) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.open') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 1 } onChange={ (e) => handleChange('lock_state', 1) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.doorbell') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 2 } onChange={ (e) => handleChange('lock_state', 2) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.invisible') }</Text>
|
||||
</Flex>
|
||||
<Flex fullWidth gap={ 1 }>
|
||||
<input className="form-check-input" type="radio" name="lockState" checked={ roomSettingsData.lockState === 3 } onChange={ (e) => handleChange('lock_state', 3) } />
|
||||
{ (roomSettingsData.lockState !== 3) && <Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text> }
|
||||
{ roomSettingsData.lockState === 3 &&
|
||||
<Column gap={ 1 }>
|
||||
<Text>{ LocalizeText('navigator.roomsettings.doormode.password') }</Text>
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.password ?? '' } onChange={ (e) => handleChange('password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.password') } />
|
||||
<input type="password" className="form-control form-control-sm col-4" value={ roomSettingsData.confirmPassword ?? '' } onChange={ (e) => handleChange('confirm_password', e.target.value) } onBlur={ trySave } placeholder={ LocalizeText('navigator.roomsettings.passwordconfirm') } />
|
||||
{ !isPasswordValid() &&
|
||||
<small className="text-danger fw-bold">
|
||||
{ LocalizeText('navigator.roomsettings.invalidconfirm') }
|
||||
</small> }
|
||||
</Column> }
|
||||
</Flex>
|
||||
</Column>
|
||||
<Column gap={ 1 }>
|
||||
<Text bold>{ LocalizeText('navigator.roomsettings.pets') }</Text>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPets } onChange={ (e) => handleChange('allow_pets', e.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowpets') }</Text>
|
||||
</Flex>
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<input className="form-check-input" type="checkbox" checked={ roomSettingsData.allowPetsEat } onChange={ (e) => handleChange('allow_pets_eat', e.target.checked) } />
|
||||
<Text>{ LocalizeText('navigator.roomsettings.allowfoodconsume') }</Text>
|
||||
</Flex>
|
||||
</Column>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
import { RoomUnbanUserComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { SendMessageHook } from '../../../../../../hooks';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsModTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
const [selectedUserId, setSelectedUserId] = useState<number>(-1);
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'moderation_mute':
|
||||
clone.muteState = Number(value);
|
||||
break;
|
||||
case 'moderation_kick':
|
||||
clone.kickState = Number(value);
|
||||
break;
|
||||
case 'moderation_ban':
|
||||
clone.banState = Number(value);
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(clone);
|
||||
|
||||
if(save) onSave(clone);
|
||||
}, [roomSettingsData, setRoomSettingsData, onSave]);
|
||||
|
||||
const unBanUser = useCallback((userId: number) =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
|
||||
clone.bannedUsers.delete(userId);
|
||||
setRoomSettingsData(clone);
|
||||
|
||||
SendMessageHook(new RoomUnbanUserComposer(userId, roomSettingsData.roomId));
|
||||
setSelectedUserId(-1);
|
||||
}, [roomSettingsData, setRoomSettingsData]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-3">{LocalizeText('navigator.roomsettings.moderation.header')}</div>
|
||||
<div className="form-group mb-1" >
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.moderation.mute.header')}</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_mute" checked={roomSettingsData.muteState === 0} onChange={(e) => handleChange('moderation_mute', 0)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.none')}</label>
|
||||
</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_mute" checked={roomSettingsData.muteState === 1} onChange={(e) => handleChange('moderation_mute', 1)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.rights')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group mb-1" >
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.moderation.kick.header')}</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_kick" checked={roomSettingsData.kickState === 0} onChange={(e) => handleChange('moderation_kick', 0)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.all')}</label>
|
||||
</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_kick" checked={roomSettingsData.kickState === 1} onChange={(e) => handleChange('moderation_kick', 1)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.rights')}</label>
|
||||
</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_kick" checked={roomSettingsData.kickState === 2} onChange={(e) => handleChange('moderation_kick', 2)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.none')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group mb-1" >
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.moderation.ban.header')}</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_ban" checked={roomSettingsData.banState === 0} onChange={(e) => handleChange('moderation_ban', 0)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.none')}</label>
|
||||
</div>
|
||||
<div className="form-check form-check-inline">
|
||||
<input className="form-check-input" type="radio" name="moderation_ban" checked={roomSettingsData.banState === 1} onChange={(e) => handleChange('moderation_ban', 1)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.moderation.rights')}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className="fw-bold mt-3 mb-1">{LocalizeText('navigator.roomsettings.moderation.banned.users')} ({roomSettingsData.bannedUsers.size})</div>
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<div className="list-container">
|
||||
{
|
||||
Array.from(roomSettingsData.bannedUsers.entries()).map(([id, name], index) =>
|
||||
{
|
||||
return <div key={index} className={'list-item' + ((id === selectedUserId) ? ' selected' : '')} onClick={e => setSelectedUserId(id)} >
|
||||
{name}
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<button className={'btn btn-primary btn-sm w-100' + ((selectedUserId < 1) ? ' disabled' : '')} onClick={ e => unBanUser(selectedUserId) }>{LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
import { RemoveAllRightsMessageComposer, RoomGiveRightsComposer, RoomTakeRightsComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useMemo } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { SendMessageHook } from '../../../../../../hooks';
|
||||
import { UserProfileIconView } from '../../../../../../layout';
|
||||
import { NavigatorRoomSettingsRightsTabViewProps } from './NavigatorRoomSettingsRightsTabView.types';
|
||||
|
||||
export const NavigatorRoomSettingsRightsTabView: FC<NavigatorRoomSettingsRightsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null, friends = null } = props;
|
||||
|
||||
const removeUserRights = useCallback( (userId: number) =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
|
||||
clone.usersWithRights.delete(userId);
|
||||
|
||||
setRoomSettingsData(clone);
|
||||
SendMessageHook(new RoomTakeRightsComposer(userId));
|
||||
}, [roomSettingsData, setRoomSettingsData]);
|
||||
|
||||
const giveUserRights = useCallback( (userId: number, name: string) =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
|
||||
clone.usersWithRights.set(userId, name);
|
||||
|
||||
setRoomSettingsData(clone);
|
||||
SendMessageHook(new RoomGiveRightsComposer(userId));
|
||||
}, [roomSettingsData, setRoomSettingsData]);
|
||||
|
||||
const removeAllRights = useCallback( () =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
|
||||
clone.usersWithRights = new Map();
|
||||
|
||||
setRoomSettingsData(clone);
|
||||
SendMessageHook(new RemoveAllRightsMessageComposer(clone.roomId));
|
||||
}, [roomSettingsData, setRoomSettingsData]);
|
||||
|
||||
const friendsWithoutRights = useMemo(() =>
|
||||
{
|
||||
const map = new Map<number, string>();
|
||||
|
||||
friends.forEach((name, id) =>
|
||||
{
|
||||
if(!roomSettingsData.usersWithRights.has(id))
|
||||
map.set(id, name);
|
||||
});
|
||||
|
||||
return map;
|
||||
}, [friends, roomSettingsData]);
|
||||
|
||||
return (
|
||||
<div className="d-flex flex-column h-100 overflow-hidden user-rights">
|
||||
<div className="row">
|
||||
<div className="col">
|
||||
filter
|
||||
</div>
|
||||
</div>
|
||||
<div className="row h-100">
|
||||
<div className="col-6 d-flex flex-column h-100">
|
||||
<div className="fw-bold mb-1">{ LocalizeText('navigator.flatctrls.userswithrights', [ 'displayed', 'total' ], [ roomSettingsData.usersWithRights.size.toString(), roomSettingsData.usersWithRights.size.toString() ]) }</div>
|
||||
<div className="d-flex flex-column justify-content-between rounded bg-white h-100 overflow-hidden px-2 py-1 user-rights-container">
|
||||
<div className="row row-cols-1 overflow-auto">
|
||||
{ Array.from(roomSettingsData.usersWithRights.entries()).map(([id, name], index) =>
|
||||
{
|
||||
return (
|
||||
<div key={index} className="d-flex align-items-center col w-100" onClick={ () => removeUserRights(id) }>
|
||||
<div className="d-flex align-items-center me-2">
|
||||
<UserProfileIconView userName={ name } />
|
||||
<span>{ name }</span>
|
||||
</div>
|
||||
<i className="fas fa-caret-right fw-bold text-black me-2" />
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
<button className="btn btn-danger btn-sm w-100" disabled={ !roomSettingsData.usersWithRights.size } onClick={ removeAllRights } >{ LocalizeText('navigator.flatctrls.clear') }</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6 d-flex flex-column h-100">
|
||||
<div className="fw-bold mb-1">{ LocalizeText('navigator.flatctrls.friends', [ 'displayed', 'total' ], [ friendsWithoutRights.size.toString(), friendsWithoutRights.size.toString() ]) }</div>
|
||||
<div className="d-flex flex-column rounded bg-white h-100 overflow-hidden px-2 py-1 user-rights-container">
|
||||
<div className="row row-cols-1 overflow-auto">
|
||||
{ Array.from(friendsWithoutRights.entries()).map(([id, name], index) =>
|
||||
{
|
||||
return (
|
||||
<div key={index} className="d-flex align-items-center col w-100" onClick={ () => giveUserRights(id, name) }>
|
||||
<i className="fas fa-caret-left fw-bold text-black me-2" />
|
||||
<div className="d-flex align-items-center">
|
||||
<UserProfileIconView userName={ name } />
|
||||
<span>{ name }</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
// <div className="row h-100">
|
||||
// <div className="col-6">
|
||||
// <div className="fw-bold mb-2">{LocalizeText('navigator.flatctrls.userswithrights', ['displayed', 'total'], [roomSettingsData.usersWithRights.size.toString(), roomSettingsData.usersWithRights.size.toString()])}</div>
|
||||
// </div>
|
||||
// <div className="col-6">
|
||||
// <div className="fw-bold mb-2">{LocalizeText('navigator.flatctrls.friends', ['displayed', 'total'], [friendsWithoutRights.size.toString(), friendsWithoutRights.size.toString()])}</div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <div className="row h-100">
|
||||
// <div className="col-6 d-flex flex-column h-100">
|
||||
// <div className="row row-cols-1 g-0 overflow-auto">
|
||||
// {
|
||||
// Array.from(roomSettingsData.usersWithRights.entries()).map(([id, name], index) =>
|
||||
// {
|
||||
// return (
|
||||
// <div key={ index } className="col">
|
||||
// <span className="w-100" >{name}</span>
|
||||
// <button className="btn btn-danger btn-sm rights-button" onClick={ () => removeUserRights(id) }>
|
||||
// <i className="fas fa-times" />
|
||||
// </button>
|
||||
// </div>
|
||||
// );
|
||||
// })
|
||||
// }
|
||||
// </div>
|
||||
// <button className={'btn btn-danger btn-sm w-100' + ((roomSettingsData.usersWithRights.size < 1) ? ' disabled' : '')} onClick={ removeAllRights } >{ LocalizeText('navigator.flatctrls.clear') }</button>
|
||||
// </div>
|
||||
// <div className="col-6 d-flex flex-column h-100">
|
||||
// <div className="row row-cols-1 g-0 overflow-auto bg-white h-100">
|
||||
// {
|
||||
// Array.from(friendsWithoutRights.entries()).map(([id, name], index) =>
|
||||
// {
|
||||
// return (
|
||||
// <div key={index} className="col">
|
||||
// <span className="w-100">{name}</span>
|
||||
// <button className="btn btn-success btn-sm rights-button" onClick={ () => giveUserRights(id, name) }>
|
||||
// <i className="fas fa-chevron-left" />
|
||||
// </button>
|
||||
// </div>
|
||||
// );
|
||||
// })
|
||||
// }
|
||||
// </div>
|
||||
// </div >
|
||||
// </div >
|
||||
);
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export interface NavigatorRoomSettingsRightsTabViewProps extends NavigatorRoomSettingsTabViewProps
|
||||
{
|
||||
friends: Map<number, string>;
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { NavigatorRoomSettingsTabViewProps } from '../../NavigatorRoomSettingsView.types';
|
||||
|
||||
export const NavigatorRoomSettingsVipChatTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
|
||||
{
|
||||
const { roomSettingsData = null, setRoomSettingsData = null, onSave = null } = props;
|
||||
|
||||
const handleChange = useCallback((field: string, value: string | number | boolean) =>
|
||||
{
|
||||
const clone = Object.assign({}, roomSettingsData);
|
||||
let save = true;
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case 'hide_walls':
|
||||
clone.hideWalls = Boolean(value);
|
||||
break;
|
||||
case 'wall_thickness':
|
||||
clone.wallThickness = Number(value);
|
||||
break;
|
||||
case 'floor_thickness':
|
||||
clone.floorThickness = Number(value);
|
||||
break;
|
||||
case 'bubble_mode':
|
||||
clone.chatBubbleMode = Number(value);
|
||||
break;
|
||||
case 'chat_weight':
|
||||
clone.chatBubbleWeight = Number(value);
|
||||
break;
|
||||
case 'bubble_speed':
|
||||
clone.chatBubbleSpeed = Number(value);
|
||||
break;
|
||||
case 'flood_protection':
|
||||
clone.chatFloodProtection = Number(value);
|
||||
break;
|
||||
case 'chat_distance':
|
||||
clone.chatDistance = Number(value);
|
||||
save = false;
|
||||
break;
|
||||
}
|
||||
|
||||
setRoomSettingsData(clone);
|
||||
|
||||
if(save) onSave(clone);
|
||||
}, [roomSettingsData, setRoomSettingsData, onSave]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.vip.caption')}</div>
|
||||
<div className="mb-3">{LocalizeText('navigator.roomsettings.vip.info')}</div>
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.vip_settings')}</div>
|
||||
<div className="form-check">
|
||||
<input className="form-check-input" type="checkbox" checked={roomSettingsData.hideWalls} onChange={(e) => handleChange('hide_walls', e.target.checked)} />
|
||||
<label className="form-check-label">{LocalizeText('navigator.roomsettings.hide_walls')}</label>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.wallThickness} onChange={event => handleChange('wall_thickness', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.wall_thickness.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.wall_thickness.thick')}</option>
|
||||
<option value="-1">{LocalizeText('navigator.roomsettings.wall_thickness.thin')}</option>
|
||||
<option value="-2">{LocalizeText('navigator.roomsettings.wall_thickness.thinnest')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.floorThickness} onChange={event => handleChange('floor_thickness', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.floor_thickness.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.floor_thickness.thick')}</option>
|
||||
<option value="-1">{LocalizeText('navigator.roomsettings.floor_thickness.thin')}</option>
|
||||
<option value="-2">{LocalizeText('navigator.roomsettings.floor_thickness.thinnest')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="fw-bold">{LocalizeText('navigator.roomsettings.chat_settings')}</div>
|
||||
<div className="mb-2">{LocalizeText('navigator.roomsettings.chat_settings.info')}</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleMode} onChange={event => handleChange('bubble_mode', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.mode.free.flow')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.mode.line.by.line')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleWeight} onChange={event => handleChange('chat_weight', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.bubbles.width.normal')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.bubbles.width.thin')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.bubbles.width.wide')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatBubbleSpeed} onChange={event => handleChange('bubble_speed', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.speed.fast')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.speed.normal')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.speed.slow')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-1">
|
||||
<select className="form-select form-select-sm" value={roomSettingsData.chatFloodProtection} onChange={event => handleChange('flood_protection', event.target.value)}>
|
||||
<option value="0">{LocalizeText('navigator.roomsettings.chat.flood.loose')}</option>
|
||||
<option value="1">{LocalizeText('navigator.roomsettings.chat.flood.normal')}</option>
|
||||
<option value="2">{LocalizeText('navigator.roomsettings.chat.flood.strict')}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group mb-0">
|
||||
<label>{LocalizeText('navigator.roomsettings.chat_settings.hearing.distance')}</label>
|
||||
<input type="number" min="0" className="form-control form-control-sm" value={roomSettingsData.chatDistance} onChange={event => handleChange('chat_distance', event.target.valueAsNumber)} onBlur={() => onSave(roomSettingsData)} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
.nitro-navigator-result {
|
||||
color: $black;
|
||||
|
||||
.badge {
|
||||
width: 35px;
|
||||
|
||||
.fas {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
@ -2,12 +2,13 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { RoomDataParser } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent } from 'react';
|
||||
import { CreateRoomSession, GetSessionDataManager, TryVisitRoom } from '../../../../api';
|
||||
import { Flex, FlexProps } from '../../../../common/Flex';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { LayoutGridItemProps } from '../../../../common/layout/LayoutGridItem';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { UpdateDoorStateEvent } from '../../../../events';
|
||||
import { dispatchUiEvent } from '../../../../hooks';
|
||||
|
||||
export interface NavigatorSearchResultItemViewProps extends FlexProps
|
||||
export interface NavigatorSearchResultItemViewProps extends LayoutGridItemProps
|
||||
{
|
||||
roomData: RoomDataParser
|
||||
}
|
||||
@ -70,7 +71,7 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex pointer onClick={ visitRoom } overflow="hidden" gap={ 2 } { ...rest }>
|
||||
<Flex pointer overflow="hidden" alignItems="center" onClick={ visitRoom } gap={ 2 } className="navigator-item px-2 py-1 small" { ...rest }>
|
||||
<Flex center className={ 'badge p-1 ' + getUserCounterColor() } gap={ 1 }>
|
||||
<FontAwesomeIcon icon="user" />
|
||||
{ roomData.userCount }
|
||||
@ -82,26 +83,6 @@ export const NavigatorSearchResultItemView: FC<NavigatorSearchResultItemViewProp
|
||||
{ (roomData.doorMode !== RoomDataParser.OPEN_STATE) &&
|
||||
<i className={ ('icon icon-navigator-room-' + ((roomData.doorMode === RoomDataParser.DOORBELL_STATE) ? 'locked' : (roomData.doorMode === RoomDataParser.PASSWORD_STATE) ? 'password' : (roomData.doorMode === RoomDataParser.INVISIBLE_STATE) ? 'invisible' : '')) } /> }
|
||||
</Flex>
|
||||
{/* <div className="d-flex flex-column justify-content-center align-items-center nitro-navigator-result small cursor-pointer" onClick={ visitRoom }>
|
||||
<div className="d-flex justify-content-between w-100 px-2 py-1">
|
||||
<div className="d-flex justify-content-center flex-grow-1 overflow-hidden">
|
||||
<div className={ 'd-flex align-items-center justify-content-center badge p-1 ' + getUserCounterColor() }>
|
||||
<i className="fas fa-user"></i>
|
||||
{ roomData.userCount }
|
||||
</div>
|
||||
<div className="d-flex flex-column justify-content-center align-items-start flex-grow-1 px-2 overflow-hidden">
|
||||
<span className="d-block text-truncate" style={ { maxWidth: '95%' } }>{ roomData.roomName }</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-row-reverse align-items-center">
|
||||
<i className="icon icon-navigator-info" onClick={ openInfo }></i>
|
||||
{ roomData.habboGroupId > 0 && <i className="icon icon-navigator-room-group me-2"></i> }
|
||||
{ roomData.doorMode !== RoomDataParser.OPEN_STATE &&
|
||||
<i className={ 'me-2 icon icon-navigator-room-' + classNames( { 'locked': roomData.doorMode === RoomDataParser.DOORBELL_STATE, 'password': roomData.doorMode === RoomDataParser.PASSWORD_STATE, 'invisible': roomData.doorMode === RoomDataParser.INVISIBLE_STATE })}></i>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
{ children }
|
||||
</Flex>
|
||||
);
|
@ -1,35 +0,0 @@
|
||||
.nitro-navigator-search-result {
|
||||
border: 1px solid #ced4da;
|
||||
|
||||
.nitro-navigator-result-list {
|
||||
|
||||
.nitro-navigator-result {
|
||||
background: $grid-active-bg-color;
|
||||
}
|
||||
|
||||
&.row {
|
||||
|
||||
&.row-cols-1 {
|
||||
|
||||
.col:nth-child(even) {
|
||||
|
||||
.nitro-navigator-result {
|
||||
background: $white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.row-cols-2 {
|
||||
|
||||
.col:nth-child(4n+3),
|
||||
.col:nth-child(4n+4) {
|
||||
|
||||
.nitro-navigator-result {
|
||||
background: $white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,48 +1,39 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { NavigatorSearchResultList } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../api';
|
||||
import { Column } from '../../../../common/Column';
|
||||
import { Flex } from '../../../../common/Flex';
|
||||
import { Grid } from '../../../../common/Grid';
|
||||
import { Text } from '../../../../common/Text';
|
||||
import { NavigatorSearchResultItemView } from '../search-result-item/NavigatorSearchResultItemView';
|
||||
import { NavigatorSearchResultViewDisplayMode, NavigatorSearchResultViewProps } from './NavigatorSearchResultView.types';
|
||||
import { BatchUpdates } from '../../../../hooks';
|
||||
import { NavigatorSearchResultViewDisplayMode } from '../../common/NavigatorSearchResultViewDisplayMode';
|
||||
import { NavigatorSearchResultItemView } from './NavigatorSearchResultItemView';
|
||||
|
||||
export interface NavigatorSearchResultViewProps
|
||||
{
|
||||
searchResult: NavigatorSearchResultList;
|
||||
}
|
||||
|
||||
export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = props =>
|
||||
{
|
||||
const { searchResult = null } = props;
|
||||
|
||||
const [ isExtended, setIsExtended ] = useState(true);
|
||||
const [ displayMode, setDisplayMode ] = useState<number>(0);
|
||||
const [ isExtended, setIsExtended ] = useState(true);
|
||||
const [ displayMode, setDisplayMode ] = useState<number>(0);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!searchResult) return;
|
||||
|
||||
//setIsExtended(searchResult.closed);
|
||||
//setDisplayMode(searchResult.mode);
|
||||
}, [ searchResult ]);
|
||||
|
||||
function getResultTitle(): string
|
||||
const getResultTitle = () =>
|
||||
{
|
||||
let name = searchResult.code;
|
||||
|
||||
if(!name || !name.length) return searchResult.data;
|
||||
|
||||
if(name.startsWith('${')) return name.substr(2, (name.length - 3));
|
||||
if(name.startsWith('${')) return name.slice(2, (name.length - 1));
|
||||
|
||||
return ('navigator.searchcode.title.' + name);
|
||||
}
|
||||
|
||||
function toggleExtended(): void
|
||||
{
|
||||
setIsExtended(prevValue =>
|
||||
{
|
||||
return !prevValue;
|
||||
});
|
||||
}
|
||||
|
||||
function toggleDisplayMode(): void
|
||||
const toggleDisplayMode = () =>
|
||||
{
|
||||
setDisplayMode(prevValue =>
|
||||
{
|
||||
@ -51,23 +42,33 @@ export const NavigatorSearchResultView: FC<NavigatorSearchResultViewProps> = pro
|
||||
return NavigatorSearchResultViewDisplayMode.LIST;
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!searchResult) return;
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
//setIsExtended(searchResult.closed);
|
||||
setDisplayMode(searchResult.mode);
|
||||
});
|
||||
}, [ searchResult ]);
|
||||
|
||||
const gridHasTwoColumns = (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS);
|
||||
|
||||
return (
|
||||
<Column className="bg-white rounded p-1" overflow="hidden">
|
||||
<Flex fullWidth alignItems="center" justifyContent="between" className="p-1">
|
||||
<Flex alignItems="center" gap={ 1 }>
|
||||
<FontAwesomeIcon icon={ isExtended ? 'minus' : 'plus' } className="text-secondary" onClick={ toggleExtended } />
|
||||
<Column className="bg-white rounded border border-muted" gap={ 0 }>
|
||||
<Flex fullWidth alignItems="center" justifyContent="between" className="px-2 py-1">
|
||||
<Flex grow pointer alignItems="center" gap={ 1 } onClick={ event => setIsExtended(prevValue => !prevValue) }>
|
||||
<FontAwesomeIcon icon={ isExtended ? 'minus' : 'plus' } className="text-secondary" />
|
||||
<Text>{ LocalizeText(getResultTitle()) }</Text>
|
||||
</Flex>
|
||||
<FontAwesomeIcon icon={ ((displayMode === NavigatorSearchResultViewDisplayMode.LIST) ? 'bars' : (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS) ? 'th' : null) } className="text-secondary" onClick={ toggleExtended } />
|
||||
<FontAwesomeIcon icon={ ((displayMode === NavigatorSearchResultViewDisplayMode.LIST) ? 'bars' : (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS) ? 'th' : null) } className="text-secondary" onClick={ toggleDisplayMode } />
|
||||
</Flex>
|
||||
<Grid columnCount={ ((displayMode === NavigatorSearchResultViewDisplayMode.LIST) ? 1 : (displayMode >= NavigatorSearchResultViewDisplayMode.THUMBNAILS) ? 2 : 1) }>
|
||||
{ isExtended &&
|
||||
searchResult.rooms.length > 0 && searchResult.rooms.map((room, index) =>
|
||||
{
|
||||
return <NavigatorSearchResultItemView key={ index } roomData={ room } />
|
||||
}) }
|
||||
</Grid>
|
||||
{ isExtended &&
|
||||
<Grid columnCount={ (gridHasTwoColumns ? 2 : 1) } className={ 'navigator-grid' + (gridHasTwoColumns ? ' two-columns' : '') } gap={ 0 }>
|
||||
{ searchResult.rooms.length > 0 && searchResult.rooms.map((room, index) => <NavigatorSearchResultItemView key={ index } roomData={ room } />) }
|
||||
</Grid> }
|
||||
</Column>
|
||||
// <div className="nitro-navigator-search-result bg-white rounded mb-2 overflow-hidden">
|
||||
// <div className="d-flex flex-column">
|
||||
|
Loading…
Reference in New Issue
Block a user