mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
added SyncRoomCard
component
This commit is contained in:
parent
9e4c8a8607
commit
53200388d6
200
packages/app/src/components/SyncRoomCard/index.jsx
Normal file
200
packages/app/src/components/SyncRoomCard/index.jsx
Normal 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>
|
||||
</>
|
||||
}
|
||||
}
|
191
packages/app/src/components/SyncRoomCard/index.less
Normal file
191
packages/app/src/components/SyncRoomCard/index.less
Normal 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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user