diff --git a/packages/app/package.json b/packages/app/package.json
index d516d7ac..5ef5e841 100755
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -88,6 +88,7 @@
"react-responsive-carousel": "^3.2.23",
"react-reveal": "1.2.2",
"react-rnd": "10.3.5",
+ "react-ticker": "^1.3.2",
"remark-gfm": "^3.0.1",
"rxjs": "^7.5.5",
"store": "^2.0.12",
diff --git a/packages/app/src/pages/live/[key].jsx b/packages/app/src/pages/live/[key].jsx
index a5da124d..dbcbe953 100755
--- a/packages/app/src/pages/live/[key].jsx
+++ b/packages/app/src/pages/live/[key].jsx
@@ -2,10 +2,11 @@
import React from "react"
import * as antd from "antd"
-import Livestream from "../../models/livestream"
+import Livestream from "models/livestream"
import { FloatingPanel } from "antd-mobile"
import { UserPreview, LiveChat } from "components"
import { Icons } from "components/Icons"
+import Ticker from "react-ticker"
import Plyr from "plyr"
import Hls from "hls.js"
@@ -110,7 +111,10 @@ export default class StreamViewer extends React.Component {
console.log("Stream info", streamInfo)
- this.setState({ streamInfo: streamInfo })
+ this.setState({
+ streamInfo: streamInfo,
+ spectators: streamInfo.connectedClients,
+ })
}
componentDidMount = async () => {
@@ -142,10 +146,19 @@ export default class StreamViewer extends React.Component {
await this.loadDecoder("flv", this.state.streamInfo.sources.flv)
}
+
+ // set a interval to update the stream info
+ this.streamInfoInterval = setInterval(() => {
+ this.loadStreamInfo(requestedUsername)
+ }, 1000 * 60 * 3)
}
componentWillUnmount = () => {
this.exitPlayerAnimation()
+
+ if (this.streamInfoInterval) {
+ clearInterval(this.streamInfoInterval)
+ }
}
enterPlayerAnimation = () => {
@@ -226,24 +239,50 @@ export default class StreamViewer extends React.Component {
}
- return
-
+ return
+
+
+
+
+
+
+
}
+ >
+ {this.state.spectators}
+
+
+
+
+
+
+
{this.state.streamInfo?.info.title}
+
+
+
+ {({ index }) => {
+ return {this.state.streamInfo?.info.description}
+ }}
+
+
+
+
+
+
+
{
window.isMobile ?
:
-
-
-
-
-
-
- {this.state.spectators}
-
-
+
+
+
Live chat
+
diff --git a/packages/app/src/pages/live/index.less b/packages/app/src/pages/live/index.less
index ef876734..1bdddacc 100755
--- a/packages/app/src/pages/live/index.less
+++ b/packages/app/src/pages/live/index.less
@@ -1,3 +1,6 @@
+@panel-width: 500px;
+@chatbox-header-height: 50px;
+
.plyr__controls {
width: 100%;
display: inline-flex;
@@ -11,11 +14,11 @@
top: 0;
left: 0;
- width: 100vw;
+ width: 100%;
height: 100vh;
}
-.liveStream {
+.livestream {
display: flex;
flex-direction: row;
@@ -23,7 +26,9 @@
justify-content: center;
height: 100vh;
- width: 100vw;
+ width: 100%;
+
+ overflow: hidden;
color: var(--background-color-contrast);
@@ -37,17 +42,104 @@
color: var(--background-color-contrast);
}
- .panel {
+ .livestream_player {
+ display: flex;
+ position: relative;
+
+ width: calc(100% - @panel-width);
+
+ .livestream_player_header {
+ display: flex;
+ flex-direction: row;
+
+ position: absolute;
+ z-index: 100;
+
+ top: 0;
+ left: 0;
+
+ width: fit-content;
+ height: fit-content;
+
+ min-width: 20vw;
+ max-width: 50vw;
+
+ margin: 20px;
+ padding: 10px;
+
+ background-color: var(--background-color-accent);
+
+ border-radius: 12px;
+
+ h1,
+ h2,
+ h3,
+ h4,
+ span {
+ margin: 0;
+
+ overflow: hidden;
+
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .livestream_player_header_user {
+ display: flex;
+ flex-direction: column;
+
+ .livestream_player_header_user_spectators {
+ margin-top: 10px;
+
+ .ant-tag {
+ background-color: #eb0400;
+ border-color: #eb0400;
+ color: var(--background-color-contrast);
+ font-size: 1rem;
+ }
+ }
+ }
+
+ .livestream_player_header_info {
+ display: flex;
+ flex-direction: column;
+
+ overflow: hidden;
+
+ width: 100%;
+
+ .livestream_player_header_title {
+ font-family: "Space Grotesk", sans-serif;
+ font-size: 1rem;
+ font-weight: 700;
+
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .livestream_player_header_description {
+ font-size: 0.8rem;
+ font-weight: 300;
+ font-style: italic;
+
+ h4 {
+ margin-left: 10px;
+ }
+ }
+ }
+ }
+ }
+
+ .livestream_panel {
display: flex;
flex-direction: column;
+ position: relative;
height: 100vh;
- width: 100%;
- min-width: 400px;
- max-width: 500px;
+ width: @panel-width;
- .info {
+ .livestream_panel_info {
display: flex;
flex-direction: column;
justify-content: flex-start;
@@ -66,24 +158,61 @@
h5 {
margin: 0;
}
-
- .userPreview {
- margin-bottom: 20px;
- }
}
.chatbox {
- width: 20vw;
+ position: relative;
+
+ width: 100%;
+ height: 100%;
+
+ overflow: hidden;
+
padding: 20px;
- height: 100vh;
- }
- #spectatorCount {
- font-size: 0.8em;
- }
+ .chatbox_header {
+ position: absolute;
+ z-index: 100;
- #timeCount {
- font-size: 0.8em;
+ display: flex;
+ flex-direction: column;
+
+ justify-content: center;
+
+ z-index: 100;
+
+ top: 0;
+ left: 0;
+
+ width: 100%;
+ height: @chatbox-header-height;
+
+ padding: 20px;
+
+ backdrop-filter: blur(20px);
+ }
+
+ .liveChat {
+ .liveChat_timeline {
+ &::after {
+ position: absolute;
+ z-index: 90;
+
+ content: "";
+
+ top: 0px;
+ left: 0;
+
+ width: 100%;
+ height: @chatbox-header-height;
+
+ filter: blur(7px);
+ background-color: rgba(var(--layoutBackgroundColor), 0.7);
+ }
+
+ padding-top: @chatbox-header-height;
+ }
+ }
}
}