From dedbe3d368307137e17e13ce4ee16844fcc99803 Mon Sep 17 00:00:00 2001 From: SrGooglo Date: Tue, 4 Apr 2023 23:51:31 +0000 Subject: [PATCH] improve `BackgroundMediaPlayer` --- .../BackgroundMediaPlayer/index.jsx | 250 +++++++++--------- .../BackgroundMediaPlayer/index.less | 213 ++++++++++++++- 2 files changed, 326 insertions(+), 137 deletions(-) diff --git a/packages/app/src/components/BackgroundMediaPlayer/index.jsx b/packages/app/src/components/BackgroundMediaPlayer/index.jsx index b237af17..136f60f5 100644 --- a/packages/app/src/components/BackgroundMediaPlayer/index.jsx +++ b/packages/app/src/components/BackgroundMediaPlayer/index.jsx @@ -1,123 +1,49 @@ import React from "react" -import Ticker from "react-ticker" -import { FastAverageColor } from "fast-average-color" +import * as antd from "antd" import classnames from "classnames" import { Icons } from "components/Icons" +import Marquee from "react-fast-marquee" import "./index.less" -const useEventBus = (events) => { - const registerEvents = () => { - for (const [event, handler] of Object.entries(events)) { - app.eventBus.on(event, handler) - } +function RGBStringToValues(rgbString) { + if (!rgbString) { + return [0, 0, 0] } - const unregisterEvents = () => { - for (const [event, handler] of Object.entries(events)) { - app.eventBus.off(event, handler) - } - } + const rgb = rgbString.replace("rgb(", "").replace(")", "").split(",").map((v) => parseInt(v)) - React.useEffect(() => { - registerEvents() - - return () => { - unregisterEvents() - } - }, []) -} - -const fac = new FastAverageColor() - -const bruh = (props) => { - const [thumbnailAnalysis, setThumbnailAnalysis] = React.useState("#000000") - const [currentPlaying, setCurrentPlaying] = React.useState(app.cores.player.getState("currentAudioManifest")) - const [plabackState, setPlaybackState] = React.useState(app.cores.player.getState("playbackStatus") ?? "stopped") - - const onClickMinimize = () => { - app.cores.player.minimize() - } - - const calculateAverageCoverColor = async () => { - if (currentPlaying) { - const color = await fac.getColorAsync(currentPlaying.thumbnail) - setThumbnailAnalysis(color) - updateBackgroundItem(color) - } - } - - const updateBackgroundItem = () => { - app.SidebarController.updateBackgroundItem(undefined, { - icon: , - style: { - backgroundColor: thumbnailAnalysis?.hex - } - }) - } - - useEventBus({ - "player.current.update": (data) => { - console.log("player.current.update", data) - setCurrentPlaying(data) - updateBackgroundItem() - }, - "player.playback.update": (data) => { - setPlaybackState(data) - updateBackgroundItem() - } - }) - - React.useEffect(() => { - calculateAverageCoverColor() - }, [currentPlaying]) - - React.useEffect(() => { - - }, []) - - return
- { - currentPlaying &&
-

- {currentPlaying.title} - {currentPlaying.artist} -

-
- } -
+ return [rgb[0], rgb[1], rgb[2]] } export default class BackgroundMediaPlayer extends React.Component { state = { - thumbnailAnalysis: null, + thumbnailAnalysis: app.cores.player.getState("coverColorAnalysis"), currentPlaying: app.cores.player.getState("currentAudioManifest"), plabackState: app.cores.player.getState("playbackStatus") ?? "stopped", + expanded: false, } events = { + "player.coverColorAnalysis.update": (data) => { + this.setState({ + thumbnailAnalysis: data + }) + }, "player.current.update": (data) => { - this.calculateAverageCoverColor() - this.setState({ currentPlaying: data }) }, - "player.playback.update": (data) => { - this.updateBackgroundItem() - + "player.status.update": (data) => { this.setState({ plabackState: data }) + }, + "sidebar.expanded": (to) => { + if (!to) { + this.toogleExpand(false) + } } } @@ -125,30 +51,17 @@ export default class BackgroundMediaPlayer extends React.Component { app.cores.player.minimize() } - calculateAverageCoverColor = async () => { - if (this.state.currentPlaying) { - const color = await fac.getColorAsync(this.state.currentPlaying.thumbnail) - - this.setState({ - thumbnailAnalysis: color - }) - - this.updateBackgroundItem(color) + toogleExpand = (to) => { + if (typeof to !== "boolean") { + to = !this.state.expanded } - } - updateBackgroundItem = (analysis) => { - app.SidebarController.updateBackgroundItem(undefined, { - icon: , - style: { - backgroundColor: analysis?.hex ?? this.state.thumbnailAnalysis?.hex, - } + this.setState({ + expanded: to }) } componentDidMount = async () => { - this.calculateAverageCoverColor() - for (const [event, handler] of Object.entries(this.events)) { app.eventBus.on(event, handler) } @@ -161,24 +74,113 @@ export default class BackgroundMediaPlayer extends React.Component { } render() { - return
- { - this.state.currentPlaying &&
+ +
+ - } -
+ + +
+
+ } + onClick={app.cores.player.playback.previous} + /> + + : } + onClick={app.cores.player.playback.toogle} + /> + + } + onClick={app.cores.player.playback.next} + /> + + } + onClick={this.onClickMinimize} + /> +
+ } } \ No newline at end of file diff --git a/packages/app/src/components/BackgroundMediaPlayer/index.less b/packages/app/src/components/BackgroundMediaPlayer/index.less index cca0649c..0c7341c1 100644 --- a/packages/app/src/components/BackgroundMediaPlayer/index.less +++ b/packages/app/src/components/BackgroundMediaPlayer/index.less @@ -1,36 +1,223 @@ .background_media_player { - overflow: hidden; + position: relative; + + display: flex; + flex-direction: column; + + align-items: center; + justify-content: center; width: 100%; + height: 40px; + + padding: 10px; + + overflow: hidden; + + border-radius: 12px; transition: all 150ms ease-in-out; - .background_media_player__title { - overflow: hidden; + line-height: 40px; - white-space: nowrap; + color: var(--text-color-white); - width: 100%; + background-repeat: no-repeat; + + background-size: cover; + + &.expanded { + height: 120px; + + .background_media_player__background { + opacity: 0.4; + } + + .background_media_player__icon { + width: 0; + opacity: 0; + } + + .background_media_player__title { + padding: 10px 0; + + h4 { + word-break: break-all; + word-wrap: break-word; + white-space: break-spaces; + + font-size: 1rem; + } + } + + .background_media_player__controls { + margin-top: 10px; + background-color: var(--text-color-white); + } + } + + &.lightBackground { + color: var(--text-color-black); + + .background_media_player__icon { + svg { + color: var(--text-color-black); + } + } + + .background_media_player__title { + color: var(--text-color-black); - &.lightBackground { h4 { color: var(--text-color-black); } } - h4 { - font-size: 1rem; - font-weight: 600; + .background_media_player__controls { + color: var(--text-color-black); - overflow: hidden; + .ant-btn { + color: var(--text-color-black); - text-overflow: ellipsis; - white-space: nowrap; + svg { + color: var(--text-color-black); + } + } + } + } - font-family: "Space Grotesk", sans-serif; + .background_media_player__background { + pointer-events: none; + position: absolute; + top: 0; + left: 0; + + width: 100%; + height: 100%; + + border-radius: 12px; + + background-position: center; + background-size: cover; + background-repeat: no-repeat; + + transition: all 150ms ease-in-out; + + opacity: 0; + } + + .background_media_player__row { + display: flex; + flex-direction: row; + + align-items: center; + justify-content: center; + + z-index: 350; + + width: 100%; + + &.hidden { + pointer-events: none; + opacity: 0; + height: 0; + } + } + + .background_media_player__icon { + svg { + margin-right: 0 !important; color: var(--text-color-white); } + &.bounce { + animation: bounce 1s infinite; + } + } + + .background_media_player__title { + max-height: 67px; + + transition: all 150ms ease-in-out; + + color: var(--text-color-white); + + width: 100%; + + overflow: hidden; + + h4 { + line-height: 20px; + + font-size: 0.8rem; + font-weight: 600; + + margin: 0 0 0 10px; + + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; + + font-family: "Space Grotesk", sans-serif; + color: var(--text-color-white); + } + + .marquee-container { + width: 100%; + + .overlay { + width: 100%; + } + } + } + + .background_media_player__controls { + display: flex; + flex-direction: row; + + align-self: flex-end; + align-items: center; + justify-content: space-evenly; + + width: 100%; + + color: var(--text-color-white); + + background-color: var(--text-color-black); + + border-radius: 12px; + + opacity: 0.5; + + .ant-btn { + color: var(--text-color-black); + + background-color: transparent; + + svg { + color: var(--text-color-black); + } + } + } +} + +@keyframes bounce { + + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + + 40% { + transform: translateY(-5px); + } + + 60% { + transform: translateY(-3px); } } \ No newline at end of file