diff --git a/packages/app/src/pages/lyrics/index.jsx b/packages/app/src/pages/lyrics/index.jsx index 96bd37e8..ac3c91dd 100644 --- a/packages/app/src/pages/lyrics/index.jsx +++ b/packages/app/src/pages/lyrics/index.jsx @@ -1,10 +1,8 @@ import React from "react" import classnames from "classnames" -import { Button } from "antd" +import Marquee from "react-fast-marquee" -import UseAnimations from "react-useanimations" -import LoadingAnimation from "react-useanimations/lib/loading" -import { Icons } from "components/Icons" +import Controls from "components/Player/Controls" import Image from "components/Image" @@ -12,6 +10,16 @@ import request from "comty.js/handlers/request" import "./index.less" +function RGBStringToValues(rgbString) { + if (!rgbString) { + return [0, 0, 0] + } + + const rgb = rgbString.replace("rgb(", "").replace(")", "").split(",").map((v) => parseInt(v)) + + return [rgb[0], rgb[1], rgb[2]] +} + function composeRgbValues(values) { let value = "" @@ -37,12 +45,33 @@ function calculateLineTime(line) { return line.endTimeMs - line.startTimeMs } +function isOverflown(element) { + if (!element) { + console.log("element is null") + return false + } + + return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth; +} + class PlayerController extends React.Component { state = { - hovering: false, colorAnalysis: null, - currentState: null, currentDragWidth: 0, + titleOverflown: false, + + currentDuration: 0, + currentTime: 0, + + currentPlaying: app.cores.player.getState("currentAudioManifest"), + loading: app.cores.player.getState("loading") ?? false, + playbackStatus: app.cores.player.getState("playbackStatus") ?? "stopped", + + audioMuted: app.cores.player.getState("audioMuted") ?? false, + volume: app.cores.player.getState("audioVolume"), + + syncModeLocked: app.cores.player.getState("syncModeLocked"), + syncMode: app.cores.player.getState("syncMode"), } events = { @@ -50,16 +79,37 @@ class PlayerController extends React.Component { this.setState({ colorAnalysis }) }, "player.seek.update": (seekTime) => { - const updatedState = this.state.currentState - - updatedState.time = seekTime - this.setState({ - currentState: updatedState, + currentTime: seekTime, }) }, + "player.status.update": (data) => { + this.setState({ playbackStatus: data }) + }, + "player.current.update": (data) => { + this.setState({ titleOverflown: false }) + + this.setState({ currentPlaying: data }) + }, + "player.syncModeLocked.update": (to) => { + this.setState({ syncModeLocked: to }) + }, + "player.syncMode.update": (to) => { + this.setState({ syncMode: to }) + }, + "player.mute.update": (data) => { + this.setState({ audioMuted: data }) + }, + "player.volume.update": (data) => { + this.setState({ audioVolume: data }) + }, + "player.loading.update": (data) => { + this.setState({ loading: data }) + }, } + titleRef = React.createRef() + startSync() { // create a interval to get state from player if (this.syncInterval) { @@ -69,7 +119,15 @@ class PlayerController extends React.Component { this.syncInterval = setInterval(() => { const currentState = app.cores.player.currentState() - this.setState({ currentState }) + this.setState({ + currentDuration: currentState.duration, + currentTime: currentState.time, + colorAnalysis: currentState.colorAnalysis, + }) + + const titleOverflown = isOverflown(this.titleRef.current) + + this.setState({ titleOverflown: titleOverflown }) }, 800) } @@ -82,13 +140,21 @@ class PlayerController extends React.Component { } onClickTooglePlayButton = () => { - if (this.state.currentState?.playbackStatus === "playing") { + if (this.state?.playbackStatus === "playing") { app.cores.player.playback.pause() } else { app.cores.player.playback.play() } } + updateVolume = (value) => { + app.cores.player.volume(value) + } + + toogleMute = () => { + app.cores.player.toogleMute() + } + componentDidMount() { for (const event in this.events) { app.eventBus.on(event, this.events[event]) @@ -99,6 +165,26 @@ class PlayerController extends React.Component { } this.startSync() + + // // create a intersection observer to check if title is overflown + // // if the entire title is not visible, we will use marquee + // this.titleObserver = new IntersectionObserver((entries) => { + // for (const entry of entries) { + // if (entry.isIntersecting) { + // this.setState({ titleOverflown: false }) + // } else { + // this.setState({ titleOverflown: true }) + // } + // } + // }, { + // root: null, + // rootMargin: "0px", + // threshold: 1.0, + // }) + + console.log(this.titleRef.current) + + //this.titleObserver.observe(this.titleRef.current) } componentWillUnmount() { @@ -121,70 +207,91 @@ class PlayerController extends React.Component { } render() { + //const bgColor = RGBStringToValues(getComputedStyle(document.documentElement).getPropertyValue("--background-color-accent-values")) + return