added SyncRoomCard component

This commit is contained in:
SrGooglo 2023-05-24 17:36:51 +00:00
parent 9e4c8a8607
commit 53200388d6
2 changed files with 391 additions and 0 deletions

View File

@ -0,0 +1,200 @@
import React from "react"
import { Button, Tooltip, Badge } from "antd"
import { Icons } from "components/Icons"
import LiveChat from "components/LiveChat"
import classnames from "classnames"
import "./index.less"
export default class SyncRoomCard extends React.Component {
state = {
roomData: {},
socketLatency: null,
owner: false,
chatVisible: false,
notReadedMessages: false,
}
latencyInterval = null
roomEvents = {
"room:joined": (data) => {
this.setState({
roomData: data,
})
},
"room:current-data": (data) => {
console.log(data)
this.setState({
roomData: data
})
}
}
chatEvents = {
"room:recive:message": (data) => {
if (!this.state.chatVisible) {
this.setState({
notReadedMessages: true
})
}
}
}
checkLatency = () => {
const instance = app.cores.api.instance().wsInstances.music
if (instance) {
this.setState({
socketLatency: instance.latency
})
}
}
componentDidMount = () => {
Object.keys(this.roomEvents).forEach((event) => {
app.cores.sync.music.eventBus.on(event, this.roomEvents[event])
})
// chat instance
const chatInstance = app.cores.api.instance().wsInstances.chat
if (chatInstance) {
Object.keys(this.chatEvents).forEach((event) => {
chatInstance.on(event, this.chatEvents[event])
})
}
this.checkLatency()
this.latencyInterval = setInterval(() => {
this.checkLatency()
}, 1000)
}
componentWillUnmount = () => {
Object.keys(this.roomEvents).forEach((event) => {
app.cores.sync.music.eventBus.off(event, this.roomEvents[event])
})
if (this.latencyInterval) {
clearInterval(this.latencyInterval)
}
// chat instance
const chatInstance = app.cores.api.instance().wsInstances.chat
if (chatInstance) {
Object.keys(this.chatEvents).forEach((event) => {
chatInstance.off(event, this.chatEvents[event])
})
}
}
leaveRoom = () => {
app.cores.sync.music.leaveRoom()
}
toogleChatVisibility = (to) => {
if (typeof to !== "boolean") {
to = !this.state.chatVisible
}
this.setState({
chatVisible: to
})
if (this.state.notReadedMessages && to) {
this.setState({
notReadedMessages: false
})
}
}
render() {
return <>
<div className="sync-room_subcard top">
<div className="sync-room_name">
<span>
<Icons.MdSync /> {this.state.roomData?.options?.title ?? "Untitled room"}
</span>
</div>
<div className="sync-room_share_btns">
<Button
size="small"
icon={<Icons.MdShare />}
onClick={app.cores.sync.music.createInviteUserModal}
/>
<Badge
dot={this.state.notReadedMessages}
>
<Button
size="small"
icon={<Icons.MdChat />}
onClick={this.toogleChatVisibility}
/>
</Badge>
</div>
</div>
<div className="sync-room_card">
<div className="sync-room_users">
{
Array.isArray(this.state.roomData?.connectedUsers) && this.state.roomData?.connectedUsers.map((user, index) => {
return <Tooltip
title={user.username}
key={index}
>
<div className="sync-room_user" key={index}>
{
user.user_id === this.state.roomData.ownerUserId && <div className="ownerIcon">
<Icons.Crown />
</div>
}
<div className="sync-room_user_avatar">
<img src={user.avatar} alt={user.username} />
</div>
</div>
</Tooltip>
})
}
</div>
<div className="sync-room_actions">
<Button
type="primary"
onClick={this.leaveRoom}
size="small"
icon={<Icons.MdLogout />}
danger
/>
</div>
<div className="latency_display">
<span>
{
app.cores.api.instance().wsInstances.music.latency ?? "..."
}ms
</span>
</div>
</div>
<div
className={classnames(
"sync-room_subcard bottom",
{
"hidden": !this.state.chatVisible
}
)}
>
<LiveChat
room={this.state.roomData?.roomId}
compact
/>
</div>
</>
}
}

View File

@ -0,0 +1,191 @@
.sync-room_card {
position: relative;
z-index: 300;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 20px;
width: 100%;
min-width: 270px;
background-color: var(--background-color-accent);
border-radius: 8px;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
overflow-x: overlay;
.sync-room_actions {
position: sticky;
right: 0;
bottom: 0;
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
}
.sync-room_users {
display: flex;
flex-direction: row;
align-items: center;
gap: 6px;
// width: 100%;
// height: 100%;
// overflow-y: visible;
// overflow-x: overlay;
.sync-room_user {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
gap: 5px;
animation: user-join 500ms ease-out forwards;
.sync-room_user_avatar {
width: 30px;
height: 30px;
img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
border-radius: 12px;
background-color: black;
}
}
.ownerIcon {
position: absolute;
top: 0;
right: 0;
transform: translate(0, -100%);
// make gold color
color: #FFD700;
}
}
}
.latency_display {
position: absolute;
bottom: 0;
right: 0;
display: flex;
flex-direction: row;
align-items: center;
gap: 5px;
padding: 5px 10px;
border-radius: 0 8px 0 8px;
font-size: 8px;
font-weight: 500;
color: var(--text-color-accent);
}
}
.sync-room_subcard {
position: relative;
z-index: 295;
top: 0;
left: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
max-height: 350px;
overflow-y: overlay;
padding: 10px;
background-color: var(--background-color-accent);
border-radius: 8px 8px 0 0;
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
transition: all 250ms ease-in-out;
&.top {
transform: translateY(10px);
padding-bottom: 20px;
border-radius: 8px 8px 0 0;
}
&.bottom {
transform: translateY(-10px);
padding-top: 20px;
border-radius: 0 0 8px 8px;
}
&.hidden {
opacity: 0;
max-height: 0px;
}
.sync-room_share_btns {
display: flex;
flex-direction: row;
gap: 8px;
}
}
// animate a bounce in
@keyframes user-join {
0% {
transform: translateY(10px);
opacity: 0;
}
50% {
transform: translateY(-10px);
opacity: 1;
}
100% {
transform: translateY(0px);
}
}