feat: Rooms history
by @oobjectt https://github.com/billsonnn/nitro-react/pull/148
After Width: | Height: | Size: 267 B |
After Width: | Height: | Size: 280 B |
After Width: | Height: | Size: 393 B |
After Width: | Height: | Size: 402 B |
After Width: | Height: | Size: 260 B |
After Width: | Height: | Size: 267 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.6 KiB |
|
@ -104,6 +104,27 @@
|
|||
// 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 {
|
||||
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-border-radius-lg);
|
||||
}
|
||||
|
@ -111,3 +132,4 @@
|
|||
.btn-sm {
|
||||
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-border-radius-sm);
|
||||
}
|
||||
|
||||
|
|
|
@ -613,6 +613,42 @@
|
|||
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 {
|
||||
animation: rotating 1s linear infinite;
|
||||
}
|
||||
|
@ -627,3 +663,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
border-bottom-right-radius: $border-radius;
|
||||
transition: all 0.2s ease;
|
||||
z-index: 2;
|
||||
margin-left: -20px;
|
||||
|
||||
.list-group-item {
|
||||
background: transparent;
|
||||
|
@ -45,6 +46,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.nitro-room-history {
|
||||
background: rgba($dark, 0.95);
|
||||
box-shadow: inset 0px 5px lighten(rgba($dark, 0.6), 2.5), inset 0 -4px darken(rgba($dark, 0.6), 4);
|
||||
transition: all 0.2s ease;
|
||||
width: 150px;
|
||||
overflow: hidden;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.nitro-room-tools-info {
|
||||
background: rgba($dark, 0.95);
|
||||
box-shadow: inset 0px 5px lighten(rgba($dark, 0.6), 2.5), inset 0 -4px darken(rgba($dark, 0.6), 4);
|
||||
|
@ -53,6 +63,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.nitro-room-tools-history {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.wordquiz-question {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
|
@ -99,6 +115,28 @@
|
|||
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 "./chat/ChatWidgetView";
|
||||
@import "./chat-input/ChatInputView";
|
||||
|
@ -108,3 +146,4 @@
|
|||
@import "./furniture/FurnitureWidgets";
|
||||
@import "./mysterybox/MysteryBoxExtensionView";
|
||||
@import "./pet-package/PetPackageWidgetView";
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {GetGuestRoomResultEvent, NavigatorSearchComposer, RateFlatMessageComposer} from "@nitro/renderer";
|
||||
import {GetGuestRoomResultEvent, NavigatorSearchComposer, RateFlatMessageComposer, RoomDataParser} from "@nitro/renderer";
|
||||
import {FC, useEffect, useState} from "react";
|
||||
|
||||
import {CreateLinkEvent, GetRoomEngine, LocalizeText, SendMessageComposer} from "../../../../api";
|
||||
import {CreateLinkEvent, GetRoomEngine, LocalizeText, SendMessageComposer, SetLocalStorage, TryVisitRoom} from "../../../../api";
|
||||
import {Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes, classNames} from "../../../../common";
|
||||
import {useMessageEvent, useNavigator, useRoom} from "../../../../hooks";
|
||||
|
||||
|
@ -11,6 +11,9 @@ export const RoomToolsWidgetView: FC<{}> = props => {
|
|||
const [roomOwner, setRoomOwner] = useState<string>(null);
|
||||
const [roomTags, setRoomTags] = useState<string[]>(null);
|
||||
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 {roomSession = null} = useRoom();
|
||||
|
||||
|
@ -44,9 +47,28 @@ export const RoomToolsWidgetView: FC<{}> = props => {
|
|||
CreateLinkEvent(`navigator/search/${value}`);
|
||||
SendMessageComposer(new NavigatorSearchComposer("hotel_view", `tag:${value}`));
|
||||
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 => {
|
||||
const parser = event.getParser();
|
||||
|
||||
|
@ -55,63 +77,183 @@ export const RoomToolsWidgetView: FC<{}> = props => {
|
|||
if (roomName !== parser.data.roomName) setRoomName(parser.data.roomName);
|
||||
if (roomOwner !== parser.data.ownerName) setRoomOwner(parser.data.ownerName);
|
||||
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(() => {
|
||||
setIsOpen(true);
|
||||
|
||||
const timeout = setTimeout(() => setIsOpen(false), 5000);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, [roomName, roomOwner, roomTags]);
|
||||
}, [roomName, roomOwner, roomTags, show]);
|
||||
|
||||
useEffect(() => {
|
||||
setRoomHistory(JSON.parse(window.localStorage.getItem("nitro.room.history")) ?? []);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex className="nitro-room-tools-container" gap={2}>
|
||||
<Column center className="nitro-room-tools p-2">
|
||||
<Base pointer title={LocalizeText("room.settings.button.text")} className="icon icon-cog" onClick={() => handleToolClick("settings")} />
|
||||
<Base
|
||||
pointer
|
||||
title={LocalizeText("room.zoom.button.text")}
|
||||
onClick={() => handleToolClick("zoom")}
|
||||
className={classNames("icon", !isZoomedIn && "icon-zoom-less", isZoomedIn && "icon-zoom-more")}
|
||||
/>
|
||||
<Base pointer title={LocalizeText("room.chathistory.button.text")} onClick={() => handleToolClick("chat_history")} className="icon icon-chat-history" />
|
||||
{navigatorData.canRate && (
|
||||
<Base pointer title={LocalizeText("room.like.button.text")} onClick={() => handleToolClick("like_room")} className="icon icon-like-room" />
|
||||
)}
|
||||
</Column>
|
||||
<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>
|
||||
<div className="btn-toggle toggle-roomtool d-flex align-items-center" onClick={() => setShow(!show)}>
|
||||
<div className={"toggle-icon " + (!show ? "right" : "left")} />
|
||||
</div>
|
||||
{show && (
|
||||
<>
|
||||
<Column gap={0} center className="nitro-room-tools p-3 px-3">
|
||||
<Flex>
|
||||
<Column center className="margin-icons p-2">
|
||||
<Base pointer title={LocalizeText("room.settings.button.text")} className="icon icon-cog" onClick={() => handleToolClick("settings")} />
|
||||
<Base
|
||||
pointer
|
||||
title={LocalizeText("room.zoom.button.text")}
|
||||
onClick={() => handleToolClick("zoom")}
|
||||
className={classNames("icon", !isZoomedIn && "icon-zoom-less", isZoomedIn && "icon-zoom-more")}
|
||||
/>
|
||||
<Base
|
||||
pointer
|
||||
title={LocalizeText("room.chathistory.button.text")}
|
||||
onClick={() => handleToolClick("chat_history")}
|
||||
className="icon icon-chat-history"
|
||||
/>
|
||||
{navigatorData.canRate && (
|
||||
<Base pointer title={LocalizeText("room.like.button.text")} onClick={() => handleToolClick("like_room")} className="icon icon-like-room" />
|
||||
)}
|
||||
<Base pointer onClick={() => handleToolClick("toggle_room_link")} className="icon icon-room-link" />
|
||||
</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>
|
||||
))}
|
||||
<Column>
|
||||
<Flex className="w-100 room-tool-item">
|
||||
<Text variant="muted" underline small onClick={() => handleToolClick("settings")}>
|
||||
{LocalizeText("room.settings.button.text")}
|
||||
</Text>
|
||||
</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>
|
||||
</TransitionAnimation>
|
||||
</Column>
|
||||
<Flex className="nitro-room-tools-history" style={{bottom: !navigatorData.canRate ? "180px" : "210px"}}>
|
||||
<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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|