Feature - Rooms history
BIN
src/assets/images/icons/room-history-back-disabled.png
Normal file
After Width: | Height: | Size: 267 B |
BIN
src/assets/images/icons/room-history-back-enabled.png
Normal file
After Width: | Height: | Size: 280 B |
BIN
src/assets/images/icons/room-history-disabled.png
Normal file
After Width: | Height: | Size: 393 B |
BIN
src/assets/images/icons/room-history-enabled.png
Normal file
After Width: | Height: | Size: 402 B |
BIN
src/assets/images/icons/room-history-next-disabled.png
Normal file
After Width: | Height: | Size: 260 B |
BIN
src/assets/images/icons/room-history-next-enabled.png
Normal file
After Width: | Height: | Size: 267 B |
BIN
src/assets/images/icons/toggle_bg.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/icons/toggle_left.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/images/icons/toggle_right.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
@ -107,6 +107,27 @@
|
|||||||
// Button Sizes
|
// Button Sizes
|
||||||
//
|
//
|
||||||
|
|
||||||
|
.btn-toggle {
|
||||||
|
border-image-source: url("@/assets/images/icons/toggle_bg.png");
|
||||||
|
border-image-slice: 6 6 6 6 fill;
|
||||||
|
border-image-width: 6px 6px 6px 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.toggle-icon {
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
width: 6px;
|
||||||
|
height: 8px;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
background-image: url("@/assets/images/icons/toggle_left.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right {
|
||||||
|
background-image: url("@/assets/images/icons/toggle_right.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.btn-lg {
|
.btn-lg {
|
||||||
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
|
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
|
||||||
}
|
}
|
||||||
|
@ -613,6 +613,42 @@
|
|||||||
height: 19px;
|
height: 19px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-back-enabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-back-enabled.png');
|
||||||
|
width: 34px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-back-disabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-back-disabled.png');
|
||||||
|
width: 34px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-enabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-enabled.png');
|
||||||
|
width: 33px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-disabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-disabled.png');
|
||||||
|
width: 33px;
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-next-enabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-next-enabled.png');
|
||||||
|
width: 34px;
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-room-history-next-disabled {
|
||||||
|
background-image: url('@/assets/images/icons/room-history-next-disabled.png');
|
||||||
|
width: 34px;
|
||||||
|
height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
&.spin {
|
&.spin {
|
||||||
animation: rotating 1s linear infinite;
|
animation: rotating 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
border-bottom-right-radius: $border-radius;
|
border-bottom-right-radius: $border-radius;
|
||||||
transition: all .2s ease;
|
transition: all .2s ease;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
margin-left: -20px;
|
||||||
|
|
||||||
.list-group-item {
|
.list-group-item {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
@ -45,6 +46,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nitro-room-history {
|
||||||
|
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;
|
||||||
|
width: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.nitro-room-tools-info {
|
.nitro-room-tools-info {
|
||||||
background: rgba($dark, .95);
|
background: rgba($dark, .95);
|
||||||
box-shadow: inset 0px 5px lighten(rgba($dark, .6), 2.5), inset 0 -4px darken(rgba($dark, .6), 4);
|
box-shadow: inset 0px 5px lighten(rgba($dark, .6), 2.5), inset 0 -4px darken(rgba($dark, .6), 4);
|
||||||
@ -53,6 +63,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nitro-room-tools-history {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.wordquiz-question {
|
.wordquiz-question {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
@ -99,6 +115,28 @@
|
|||||||
height: $nitro-doorbell-height;
|
height: $nitro-doorbell-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.toggle-roomtool {
|
||||||
|
min-height: 95px;
|
||||||
|
width: 20px;
|
||||||
|
margin-left: -5px;
|
||||||
|
padding-left: 10px;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.room-tool-item {
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-icons {
|
||||||
|
margin-top: -14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-button-history {
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
@import './avatar-info/AvatarInfoWidgetView';
|
@import './avatar-info/AvatarInfoWidgetView';
|
||||||
@import './chat/ChatWidgetView';
|
@import './chat/ChatWidgetView';
|
||||||
@import './chat-input/ChatInputView';
|
@import './chat-input/ChatInputView';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { GetGuestRoomResultEvent, NavigatorSearchComposer, RateFlatMessageComposer } from '@nitrots/nitro-renderer';
|
import { GetGuestRoomResultEvent, NavigatorSearchComposer, RateFlatMessageComposer, RoomDataParser } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { CreateLinkEvent, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../api';
|
import { CreateLinkEvent, GetRoomEngine, LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom } from '../../../../api';
|
||||||
import { Base, classNames, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
|
import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes, classNames } from '../../../../common';
|
||||||
import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks';
|
import { useMessageEvent, useNavigator, useRoom } from '../../../../hooks';
|
||||||
|
|
||||||
export const RoomToolsWidgetView: FC<{}> = props =>
|
export const RoomToolsWidgetView: FC<{}> = props =>
|
||||||
@ -11,6 +11,9 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
const [ roomOwner, setRoomOwner ] = useState<string>(null);
|
const [ roomOwner, setRoomOwner ] = useState<string>(null);
|
||||||
const [ roomTags, setRoomTags ] = useState<string[]>(null);
|
const [ roomTags, setRoomTags ] = useState<string[]>(null);
|
||||||
const [ isOpen, setIsOpen ] = useState<boolean>(false);
|
const [ isOpen, setIsOpen ] = useState<boolean>(false);
|
||||||
|
const [ isOpenHistory, setIsOpenHistory ] = useState<boolean>(false);
|
||||||
|
const [ show, setShow ] = useState(true);
|
||||||
|
const [ roomHistory, setRoomHistory ] = useState<{ roomId: number, roomName: string }[]>([]);
|
||||||
const { navigatorData = null } = useNavigator();
|
const { navigatorData = null } = useNavigator();
|
||||||
const { roomSession = null } = useRoom();
|
const { roomSession = null } = useRoom();
|
||||||
|
|
||||||
@ -47,9 +50,32 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
CreateLinkEvent(`navigator/search/${ value }`);
|
CreateLinkEvent(`navigator/search/${ value }`);
|
||||||
SendMessageComposer(new NavigatorSearchComposer('hotel_view', `tag:${ value }`));
|
SendMessageComposer(new NavigatorSearchComposer('hotel_view', `tag:${ value }`));
|
||||||
return;
|
return;
|
||||||
|
case 'room_history':
|
||||||
|
if (roomHistory.length > 0) setIsOpenHistory(prevValue => !prevValue);
|
||||||
|
return;
|
||||||
|
case 'room_history_back':
|
||||||
|
TryVisitRoom(roomHistory[roomHistory.findIndex(room => room.roomId === navigatorData.currentRoomId) - 1].roomId);
|
||||||
|
return;
|
||||||
|
case 'room_history_next':
|
||||||
|
TryVisitRoom(roomHistory[roomHistory.findIndex(room => room.roomId === navigatorData.currentRoomId) + 1].roomId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onChangeRoomHistory = (roomId: number, roomName: string) =>
|
||||||
|
{
|
||||||
|
let newStorage = JSON.parse(window.localStorage.getItem('nitro.room.history'));
|
||||||
|
|
||||||
|
if (newStorage && newStorage.filter( (room: RoomDataParser) => room.roomId === roomId ).length > 0) return;
|
||||||
|
|
||||||
|
if (newStorage && newStorage.length >= 10) newStorage.shift();
|
||||||
|
|
||||||
|
const newData = !newStorage ? [ { roomId: roomId, roomName: roomName } ] : [ ...newStorage, { roomId: roomId, roomName: roomName } ];
|
||||||
|
|
||||||
|
setRoomHistory(newData);
|
||||||
|
return SetLocalStorage('nitro.room.history', newData );
|
||||||
|
}
|
||||||
|
|
||||||
useMessageEvent<GetGuestRoomResultEvent>(GetGuestRoomResultEvent, event =>
|
useMessageEvent<GetGuestRoomResultEvent>(GetGuestRoomResultEvent, event =>
|
||||||
{
|
{
|
||||||
const parser = event.getParser();
|
const parser = event.getParser();
|
||||||
@ -59,8 +85,25 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName);
|
if(roomName !== parser.data.roomName) setRoomName(parser.data.roomName);
|
||||||
if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName);
|
if(roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName);
|
||||||
if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags);
|
if(roomTags !== parser.data.tags) setRoomTags(parser.data.tags);
|
||||||
|
|
||||||
|
onChangeRoomHistory(parser.data.roomId, parser.data.roomName);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
const handleTabClose = () =>
|
||||||
|
{
|
||||||
|
if (JSON.parse(window.localStorage.getItem('nitro.room.history'))) window.localStorage.removeItem('nitro.room.history');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', handleTabClose);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
window.removeEventListener('beforeunload', handleTabClose);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
@ -68,33 +111,86 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
const timeout = setTimeout(() => setIsOpen(false), 5000);
|
const timeout = setTimeout(() => setIsOpen(false), 5000);
|
||||||
|
|
||||||
return () => clearTimeout(timeout);
|
return () => clearTimeout(timeout);
|
||||||
}, [ roomName, roomOwner, roomTags ]);
|
}, [ roomName, roomOwner, roomTags, show ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
setRoomHistory(JSON.parse(window.localStorage.getItem('nitro.room.history')) ?? []);
|
||||||
|
}, [ ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex className="nitro-room-tools-container" gap={ 2 }>
|
<Flex className="nitro-room-tools-container" gap={ 2 }>
|
||||||
<Column center className="nitro-room-tools p-2">
|
<div className="btn-toggle toggle-roomtool d-flex align-items-center" onClick={ () => setShow(!show) }>
|
||||||
<Base pointer title={ LocalizeText('room.settings.button.text') } className="icon icon-cog" onClick={ () => handleToolClick('settings') } />
|
<div className={ 'toggle-icon ' + (!show ? 'right' : 'left') } />
|
||||||
<Base pointer title={ LocalizeText('room.zoom.button.text') } onClick={ () => handleToolClick('zoom') } className={ classNames('icon', (!isZoomedIn && 'icon-zoom-less'), (isZoomedIn && 'icon-zoom-more')) } />
|
</div>
|
||||||
<Base pointer title={ LocalizeText('room.chathistory.button.text') } onClick={ () => handleToolClick('chat_history') } className="icon icon-chat-history" />
|
{ show && (
|
||||||
{ navigatorData.canRate &&
|
<>
|
||||||
<Base pointer title={ LocalizeText('room.like.button.text') } onClick={ () => handleToolClick('like_room') } className="icon icon-like-room" /> }
|
<Column gap={ 0 } center className="nitro-room-tools p-3 px-3">
|
||||||
</Column>
|
<Flex>
|
||||||
<Column justifyContent="center">
|
<Column center className="margin-icons p-2">
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.SLIDE_LEFT } inProp={ isOpen } timeout={ 300 }>
|
<Base pointer title={ LocalizeText('room.settings.button.text') } className="icon icon-cog" onClick={ () => handleToolClick('settings') } />
|
||||||
<Column center>
|
<Base pointer title={ LocalizeText('room.zoom.button.text') } onClick={ () => handleToolClick('zoom') } className={ classNames('icon', (!isZoomedIn && 'icon-zoom-less'), (isZoomedIn && 'icon-zoom-more')) } />
|
||||||
<Column className="nitro-room-tools-info rounded py-2 px-3">
|
<Base pointer title={ LocalizeText('room.chathistory.button.text') } onClick={ () => handleToolClick('chat_history') } className="icon icon-chat-history" />
|
||||||
<Column gap={ 1 }>
|
{ navigatorData.canRate &&
|
||||||
<Text wrap variant="white" fontSize={ 4 }>{ roomName }</Text>
|
<Base pointer title={ LocalizeText('room.like.button.text') } onClick={ () => handleToolClick('like_room') } className="icon icon-like-room" /> }
|
||||||
<Text variant="muted" fontSize={ 5 }>{ roomOwner }</Text>
|
<Base pointer onClick={ () => handleToolClick('toggle_room_link') } className="icon icon-room-link" />
|
||||||
</Column>
|
</Column>
|
||||||
{ roomTags && roomTags.length > 0 &&
|
<Column>
|
||||||
<Flex gap={ 2 }>
|
<Flex className="w-100 room-tool-item">
|
||||||
{ 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>) }
|
<Text variant="muted" underline small onClick={ () => handleToolClick('settings') }>{ LocalizeText('room.settings.button.text') }</Text>
|
||||||
</Flex> }
|
</Flex>
|
||||||
</Column>
|
<Flex className="w-100 room-tool-item">
|
||||||
|
<Text variant="muted" underline small onClick={ () => handleToolClick('zoom') }>{ LocalizeText('room.zoom.button.text') }</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex className="w-100 room-tool-item">
|
||||||
|
<Text variant="muted" underline small onClick={ () => handleToolClick('chat_history') }>{ LocalizeText('room.chathistory.button.text') }</Text></Flex>
|
||||||
|
{ navigatorData.canRate &&
|
||||||
|
<Flex className="w-100 room-tool-item">
|
||||||
|
<Text variant="muted" underline small onClick={ () => handleToolClick('like_room') }>{ LocalizeText('room.like.button.text') }</Text>
|
||||||
|
</Flex> }
|
||||||
|
<Flex className="w-100 room-tool-item">
|
||||||
|
<Text variant="muted" underline small onClick={ () => handleToolClick('toggle_room_link') }>{ LocalizeText('navigator.embed.caption') }</Text>
|
||||||
|
</Flex>
|
||||||
|
</Column>
|
||||||
|
</Flex>
|
||||||
|
<Flex justifyContent="center">
|
||||||
|
<Base pointer={ roomHistory.length > 1 && roomHistory[0]?.roomId !== navigatorData.currentRoomId } title={ LocalizeText('room.history.button.back.tooltip') } className={ `icon ${ (roomHistory?.length === 0 || roomHistory[0]?.roomId === navigatorData.currentRoomId) ? 'icon-room-history-back-disabled' : 'icon-room-history-back-enabled' }` } onClick={ () => (roomHistory?.length === 0 || roomHistory[0]?.roomId === navigatorData.currentRoomId) ? null : handleToolClick('room_history_back') } />
|
||||||
|
<Base pointer={ roomHistory?.length > 0 } title={ LocalizeText('room.history.button.tooltip') } className={ `icon ${ roomHistory?.length === 0 ? 'icon-room-history-disabled' : 'icon-room-history-enabled' } margin-button-history` } onClick={ () => roomHistory?.length === 0 ? null : handleToolClick('room_history') } />
|
||||||
|
<Base pointer={ roomHistory.length > 1 && roomHistory[roomHistory.length - 1]?.roomId !== navigatorData.currentRoomId } title={ LocalizeText('room.history.button.forward.tooltip') } className={ `icon ${ (roomHistory?.length === 0 || roomHistory[roomHistory.length - 1]?.roomId === navigatorData.currentRoomId) ? 'icon-room-history-next-disabled' : 'icon-room-history-next-enabled' }` } onClick={ () => (roomHistory?.length === 0 || roomHistory[roomHistory.length - 1]?.roomId === navigatorData.currentRoomId) ? null : handleToolClick('room_history_next') } />
|
||||||
|
</Flex>
|
||||||
</Column>
|
</Column>
|
||||||
</TransitionAnimation>
|
<Flex className="nitro-room-tools-history" style={ { bottom: !navigatorData.canRate ? '180px' : '210px' } }>
|
||||||
</Column>
|
<TransitionAnimation type={ TransitionAnimationTypes.SLIDE_LEFT } inProp={ isOpenHistory }>
|
||||||
|
<Column center>
|
||||||
|
<Column className="nitro-room-history rounded py-2 px-3">
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
{ (roomHistory.length > 0) && roomHistory.map(history =>
|
||||||
|
{
|
||||||
|
return <Text key={ history.roomId } bold={ history.roomId === navigatorData.currentRoomId } variant={ history.roomId === navigatorData.currentRoomId ? 'white' : 'muted' } pointer onClick={ () => TryVisitRoom(history.roomId) }>{ history.roomName }</Text>;
|
||||||
|
}) }
|
||||||
|
</Column>
|
||||||
|
</Column>
|
||||||
|
</Column>
|
||||||
|
</TransitionAnimation>
|
||||||
|
</Flex>
|
||||||
|
<Column justifyContent="center">
|
||||||
|
<TransitionAnimation type={ TransitionAnimationTypes.SLIDE_LEFT } inProp={ isOpen } timeout={ 300 }>
|
||||||
|
<Column center>
|
||||||
|
<Column className="nitro-room-tools-info rounded py-2 px-3">
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Text wrap variant="white" fontSize={ 4 }>{ roomName }</Text>
|
||||||
|
<Text variant="muted" fontSize={ 5 }>{ roomOwner }</Text>
|
||||||
|
</Column>
|
||||||
|
{ roomTags && roomTags.length > 0 &&
|
||||||
|
<Flex gap={ 2 }>
|
||||||
|
{ 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>
|
||||||
|
</TransitionAnimation>
|
||||||
|
</Column>
|
||||||
|
</>
|
||||||
|
) }
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|