Issue #75 - Room settings tags

This commit is contained in:
oobjectt 2022-12-13 01:40:04 +01:00
parent b479210aca
commit e4a9b8a9ba
7 changed files with 96 additions and 15 deletions

View File

@ -0,0 +1,10 @@
export class RoomSettingsErrorType
{
public static readonly PASSWORD_REQUIRED = 5;
public static readonly ROOM_NAME_MISSING = 7;
public static readonly ROOM_NAME_BADWORDS = 8;
public static readonly ROOM_DESCRIPTION_BADWORDS = 10;
public static readonly ROOM_TAGS_BADWWORDS = 11;
public static readonly RESTRICTED_TAGS = 12;
public static readonly TAGS_TOO_LONG = 13;
}

View File

@ -7,6 +7,7 @@ export * from './IRoomModel';
export * from './IRoomModerationSettings';
export * from './NavigatorSearchResultViewDisplayMode';
export * from './RoomInfoData';
export * from './RoomSettingsErrorType';
export * from './RoomSettingsUtils';
export * from './SearchFilterOptions';
export * from './TryVisitRoom';

View File

@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoomMuteComposer, RoomSettingsComposer, SecurityLevel, ToggleStaffPickMessageComposer, UpdateHomeRoomMessageComposer } from '@nitrots/nitro-renderer';
import { NavigatorSearchComposer, RoomMuteComposer, RoomSettingsComposer, SecurityLevel, ToggleStaffPickMessageComposer, UpdateHomeRoomMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { CreateLinkEvent, DispatchUiEvent, GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../api';
import { Button, classNames, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../common';
@ -47,6 +47,8 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
if(newRoomId > 0) SendMessageComposer(new UpdateHomeRoomMessageComposer(newRoomId));
return;
case 'navigator_search_tag':
CreateLinkEvent(`navigator/search/${ value }`);
SendMessageComposer(new NavigatorSearchComposer('hotel_view', `tag:${ value }`));
return;
case 'open_room_thumbnail_camera':
DispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));

View File

@ -1,30 +1,52 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoomDeleteComposer } from '@nitrots/nitro-renderer';
import { RoomDeleteComposer, RoomSettingsSaveErrorEvent } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { CreateLinkEvent, GetMaxVisitorsList, IRoomData, LocalizeText, SendMessageComposer } from '../../../../api';
import { CreateLinkEvent, GetMaxVisitorsList, IRoomData, LocalizeText, RoomSettingsErrorType, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, Text } from '../../../../common';
import { useNavigator, useNotification } from '../../../../hooks';
import { useMessageEvent, useNavigator, useNotification } from '../../../../hooks';
const ROOM_NAME_MIN_LENGTH = 3;
const ROOM_NAME_MAX_LENGTH = 60;
const DESC_MAX_LENGTH = 255;
const TAGS_MAX_LENGTH = 15;
interface NavigatorRoomSettingsTabViewProps
{
roomData: IRoomData;
handleChange: (field: string, value: string | number | boolean) => void;
handleChange: (field: string, value: string | number | boolean | string[]) => void;
onClose: () => void;
}
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
{
const { roomData = null, handleChange = null, onClose = null } = props;
const [ roomName, setRoomName ] = useState<string>('');
const [ roomDescription, setRoomDescription ] = useState<string>('');
const [ roomTag1, setRoomTag1 ] = useState<string>('');
const [ roomTag2, setRoomTag2 ] = useState<string>('');
const [ tagIndex, setTagIndex ] = useState(0);
const [ typeError, setTypeError ] = useState<string>('');
const { showConfirm = null } = useNotification();
const { categories = null } = useNavigator();
useMessageEvent<RoomSettingsSaveErrorEvent>(RoomSettingsSaveErrorEvent, event =>
{
const parser = event.getParser();
if (!parser) return;
switch (parser.code)
{
case RoomSettingsErrorType.ROOM_TAGS_BADWWORDS:
case RoomSettingsErrorType.RESTRICTED_TAGS:
setTypeError('trading.mode.not.allowed');
break;
default:
setTypeError('');
break;
}
});
const deleteRoom = () =>
{
showConfirm(LocalizeText('navigator.roomsettings.deleteroom.confirm.message', [ 'room_name' ], [ roomData.roomName ] ), () =>
@ -50,12 +72,27 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
if((roomDescription === roomData.roomDescription) || (roomDescription.length > DESC_MAX_LENGTH)) return;
handleChange('description', roomDescription);
}
}
const saveTags = (index: number) =>
{
if(index === 0 && (roomTag1 === roomData.tags[0]) || (roomTag1.length > TAGS_MAX_LENGTH)) return;
if(index === 1 && (roomTag2 === roomData.tags[1]) || (roomTag2.length > TAGS_MAX_LENGTH)) return;
if(roomTag1 === '' && roomTag2 !== '') setRoomTag2('');
setTypeError('');
setTagIndex(index);
handleChange('tags', (roomTag1 === '' && roomTag2 !== '') ? [ roomTag2 ] : [ roomTag1, roomTag2 ]);
}
useEffect(() =>
{
setRoomName(roomData.roomName);
setRoomDescription(roomData.roomDescription);
setRoomTag1((roomData.tags.length > 0 && roomData.tags[0]) ? roomData.tags[0] : '');
setRoomTag2((roomData.tags.length > 0 && roomData.tags[1]) ? roomData.tags[1] : '');
}, [ roomData ]);
return (
@ -94,6 +131,31 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
<option value="2">{ LocalizeText('navigator.roomsettings.trade_allowed') }</option>
</select>
</Flex>
<Flex alignItems="center" gap={ 1 }>
<Text className="col-3">{ LocalizeText('navigator.tags') }</Text>
<Column fullWidth gap={ 0 }>
<input className="form-control form-control-sm" value={ roomTag1 } onChange={ event => setRoomTag1(event.target.value) } onBlur={ () => saveTags(0) } />
{ (roomTag1.length > TAGS_MAX_LENGTH) &&
<Text bold small variant="danger">
{ LocalizeText('navigator.roomsettings.toomanycharacters') }
</Text> }
{ (tagIndex === 0 && typeError != '') &&
<Text bold small variant="danger">
{ LocalizeText(typeError) }
</Text> }
</Column>
<Column fullWidth gap={ 0 }>
<input className="form-control form-control-sm" value={ roomTag2 } onChange={ event => setRoomTag2(event.target.value) } onBlur={ () => saveTags(1) } />
{ (roomTag2.length > TAGS_MAX_LENGTH) &&
<Text bold small variant="danger">
{ LocalizeText('navigator.roomsettings.toomanycharacters') }
</Text> }
{ (tagIndex === 1 && typeError != '') &&
<Text bold small variant="danger">
{ LocalizeText(typeError) }
</Text> }
</Column>
</Flex>
<Flex alignItems="center" gap={ 1 }>
<Base className="col-3" />
<input className="form-check-input" type="checkbox" checked={ roomData.allowWalkthrough } onChange={ event => handleChange('allow_walkthrough', event.target.checked) } />

View File

@ -69,7 +69,7 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
setCurrentTab(TABS[0]);
}
const handleChange = (field: string, value: string | number | boolean) =>
const handleChange = (field: string, value: string | number | boolean | string[]) =>
{
setRoomData(prevValue =>
{
@ -92,6 +92,9 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
case 'trade_state':
newValue.tradeState = Number(value);
break;
case 'tags':
newValue.tags = value as Array<string>;
break;
case 'allow_walkthrough':
newValue.allowWalkthrough = Boolean(value);
break;

View File

@ -49,7 +49,6 @@
background: rgba($dark, .95);
box-shadow: inset 0px 5px lighten(rgba($dark, .6), 2.5), inset 0 -4px darken(rgba($dark, .6), 4);
transition: all .2s ease;
pointer-events: none;
max-width: 250px;
}
}

View File

@ -1,4 +1,4 @@
import { GetGuestRoomResultEvent, RateFlatMessageComposer } from '@nitrots/nitro-renderer';
import { GetGuestRoomResultEvent, NavigatorSearchComposer, RateFlatMessageComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react';
import { CreateLinkEvent, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
import { Base, classNames, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
@ -14,7 +14,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
const { navigatorData = null } = useNavigator();
const { roomSession = null } = useRoom();
const handleToolClick = (action: string) =>
const handleToolClick = (action: string, value?: string) =>
{
switch(action)
{
@ -25,10 +25,10 @@ export const RoomToolsWidgetView: FC<{}> = props =>
setIsZoomedIn(prevValue =>
{
let scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1);
if(!prevValue) scale /= 2;
else scale *= 2;
GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale);
return !prevValue;
@ -43,6 +43,10 @@ export const RoomToolsWidgetView: FC<{}> = props =>
case 'toggle_room_link':
CreateLinkEvent('navigator/toggle-room-link');
return;
case 'navigator_search_tag':
CreateLinkEvent(`navigator/search/${ value }`);
SendMessageComposer(new NavigatorSearchComposer('hotel_view', `tag:${ value }`));
return;
}
}
@ -65,7 +69,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
return () => clearTimeout(timeout);
}, [ roomName, roomOwner, roomTags ]);
return (
<Flex className="nitro-room-tools-container" gap={ 2 }>
<Column center className="nitro-room-tools p-2">
@ -85,7 +89,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
</Column>
{ roomTags && roomTags.length > 0 &&
<Flex gap={ 2 }>
{ roomTags.map((tag, index) => <Text key={ index } small variant="white" className="rounded bg-primary p-1">#{ tag }</Text>) }
{ roomTags.map((tag, index) => <Text key={ index } small pointer variant="white" className="rounded bg-primary p-1" onClick={ () => handleToolClick('navigator_search_tag', tag) }>#{ tag }</Text>) }
</Flex> }
</Column>
</Column>