From 53200388d6d4a3259ca0ebd4f67013d42e3dad95 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Wed, 24 May 2023 17:36:51 +0000 Subject: [PATCH] added `SyncRoomCard` component --- .../app/src/components/SyncRoomCard/index.jsx | 200 ++++++++++++++++++ .../src/components/SyncRoomCard/index.less | 191 +++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 packages/app/src/components/SyncRoomCard/index.jsx create mode 100644 packages/app/src/components/SyncRoomCard/index.less diff --git a/packages/app/src/components/SyncRoomCard/index.jsx b/packages/app/src/components/SyncRoomCard/index.jsx new file mode 100644 index 00000000..e6e81db0 --- /dev/null +++ b/packages/app/src/components/SyncRoomCard/index.jsx @@ -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 <> +
+
+ + {this.state.roomData?.options?.title ?? "Untitled room"} + +
+ +
+
+
+ +
+
+ { + Array.isArray(this.state.roomData?.connectedUsers) && this.state.roomData?.connectedUsers.map((user, index) => { + return +
+ { + user.user_id === this.state.roomData.ownerUserId &&
+ +
+ } +
+ {user.username} +
+
+
+ }) + } +
+ +
+
+ +
+ + { + app.cores.api.instance().wsInstances.music.latency ?? "..." + }ms + +
+
+ +
+ +
+ + } +} \ No newline at end of file diff --git a/packages/app/src/components/SyncRoomCard/index.less b/packages/app/src/components/SyncRoomCard/index.less new file mode 100644 index 00000000..22917b8a --- /dev/null +++ b/packages/app/src/components/SyncRoomCard/index.less @@ -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); + } +} \ No newline at end of file