Spotify container
This commit is contained in:
parent
a1300e851d
commit
1e90ecf826
30
package-lock.json
generated
30
package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"license": "GPL-3.0-only",
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"fast-average-color": "^7.1.0",
|
||||
"fast-xml-parser": "^4.0.0-beta.8",
|
||||
"gatsby": "^4.4.0",
|
||||
"gatsby-plugin-react-svg": "^3.1.0",
|
||||
@ -2767,6 +2768,11 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/offscreencanvas": {
|
||||
"version": "2019.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.6.4.tgz",
|
||||
"integrity": "sha512-u8SAgdZ8ROtkTF+mfZGOscl0or6BSj9A4g37e6nvxDc+YB/oDut0wHkK2PBBiC2bNR8TS0CPV+1gAk4fNisr1Q=="
|
||||
},
|
||||
"node_modules/@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -7475,6 +7481,17 @@
|
||||
"url": "https://github.com/sponsors/jaydenseric"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-average-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-7.1.0.tgz",
|
||||
"integrity": "sha512-eTc18sdbr2P2xZFMhvWmo+T7MJ403k4jSiapTMoOcvkptu7SWOU+TzN4tFL4B9sIKUSXA63Xu7Mpc4fmncDZ+Q==",
|
||||
"dependencies": {
|
||||
"@types/offscreencanvas": "^2019.6.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-copy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-2.1.1.tgz",
|
||||
@ -18909,6 +18926,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/offscreencanvas": {
|
||||
"version": "2019.6.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.6.4.tgz",
|
||||
"integrity": "sha512-u8SAgdZ8ROtkTF+mfZGOscl0or6BSj9A4g37e6nvxDc+YB/oDut0wHkK2PBBiC2bNR8TS0CPV+1gAk4fNisr1Q=="
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -22482,6 +22504,14 @@
|
||||
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
|
||||
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
|
||||
},
|
||||
"fast-average-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-7.1.0.tgz",
|
||||
"integrity": "sha512-eTc18sdbr2P2xZFMhvWmo+T7MJ403k4jSiapTMoOcvkptu7SWOU+TzN4tFL4B9sIKUSXA63Xu7Mpc4fmncDZ+Q==",
|
||||
"requires": {
|
||||
"@types/offscreencanvas": "^2019.6.4"
|
||||
}
|
||||
},
|
||||
"fast-copy": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-2.1.1.tgz",
|
||||
|
@ -24,6 +24,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"buffer": "^6.0.3",
|
||||
"fast-average-color": "^7.1.0",
|
||||
"fast-xml-parser": "^4.0.0-beta.8",
|
||||
"gatsby": "^4.4.0",
|
||||
"gatsby-plugin-react-svg": "^3.1.0",
|
||||
|
@ -1,16 +1,22 @@
|
||||
import * as React from "react"
|
||||
//import useWebSocket from "react-use-websocket";
|
||||
import { connect } from "mqtt"
|
||||
import FastAverageColor from 'fast-average-color';
|
||||
import type { SecretsMQTT, SongInfo } from "../lib/interfaces"
|
||||
import * as styles from "../styles/containers/Spotify.module.css"
|
||||
|
||||
const fac = new FastAverageColor();
|
||||
|
||||
const Spotify = ({ mqtt, Alternative }: { mqtt: SecretsMQTT, Alternative: any }) => {
|
||||
const [lastSongInfo, setLastSongInfo] = React.useState<SongInfo | undefined>(undefined)
|
||||
const [lastSongInfo, setLastSongInfo] = React.useState<SongInfo>({
|
||||
playbackState: "STOPPED"
|
||||
});
|
||||
const [color, setColors] = React.useState<{bg?: string; text?: string}>({});
|
||||
|
||||
const handleMessage = (_topic: string, message: string) => {
|
||||
try {
|
||||
const songInfo: SongInfo = JSON.parse(message.toString());
|
||||
setLastSongInfo(songInfo);
|
||||
setLastSongInfo((lastInfo) => {return {...lastInfo, ...songInfo}});
|
||||
} catch {
|
||||
console.warn(`Can't parse song info: ${message.toString()}`);
|
||||
}
|
||||
@ -20,7 +26,7 @@ const Spotify = ({ mqtt, Alternative }: { mqtt: SecretsMQTT, Alternative: any })
|
||||
const client = connect(mqtt.url, {
|
||||
username: mqtt.username,
|
||||
password: mqtt.password,
|
||||
protocol: "mqtt"
|
||||
protocol: "ws"
|
||||
});
|
||||
|
||||
client.on("message", handleMessage);
|
||||
@ -34,11 +40,35 @@ const Spotify = ({ mqtt, Alternative }: { mqtt: SecretsMQTT, Alternative: any })
|
||||
return () => { client.end() }
|
||||
}, [])
|
||||
|
||||
if (true || !lastSongInfo || lastSongInfo.playbackState !== "PLAYING") {
|
||||
React.useEffect(() => {
|
||||
(async () => {
|
||||
if (lastSongInfo.playbackState !== "STOPPED" && lastSongInfo.cover && lastSongInfo.cover.startsWith("http") && document) {
|
||||
const { value, isDark } = await fac.getColorAsync(lastSongInfo.cover);
|
||||
value[3] = 0.8;
|
||||
setColors({
|
||||
bg: `rgba(${value.join(",")})`,
|
||||
text: `var(--textColor${isDark ? "Light" : "Dark"})`
|
||||
});
|
||||
} else {
|
||||
setColors({});
|
||||
}
|
||||
})();
|
||||
}, [lastSongInfo]);
|
||||
|
||||
if (lastSongInfo.playbackState === "STOPPED") {
|
||||
return Alternative;
|
||||
}
|
||||
|
||||
return <div className={`container ${styles.container}`}>
|
||||
return <div className={`container ${styles.container}`} style={{
|
||||
background: color.bg,
|
||||
color: color.text
|
||||
}}>
|
||||
{lastSongInfo.cover ? <img src={lastSongInfo.cover} alt="Cover" className={styles.cover} /> : <div></div>}
|
||||
<div className={styles.meta}>
|
||||
<span className={styles.title}>{lastSongInfo.title || "Unbekannt"}</span><br/>
|
||||
<span>{lastSongInfo.artist ? lastSongInfo.artist.join(", ") || "Unbekannt" : "Unbekannt"}</span><br/>
|
||||
<span>{lastSongInfo.album || "Unbekannt"}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
@ -72,9 +72,10 @@ export interface PlantState {
|
||||
}
|
||||
}
|
||||
|
||||
export interface SongInfo {
|
||||
export type SongInfo = {
|
||||
playbackState: "PLAYING" | "PAUSE" | "STOPPED";
|
||||
title: string;
|
||||
artists: string[];
|
||||
album: string;
|
||||
title?: string;
|
||||
artist?: string[];
|
||||
album?: string;
|
||||
cover?: string;
|
||||
}
|
@ -6,16 +6,31 @@
|
||||
width:100%;
|
||||
height:100%;
|
||||
padding:5px;
|
||||
background: var(--spotifyColor);
|
||||
background: var(--containerBg);
|
||||
border-radius: 5px;
|
||||
}
|
||||
.container p {
|
||||
.meta {
|
||||
max-width: 21vw;
|
||||
color: inherit;
|
||||
word-wrap: normal;
|
||||
padding: 5px 15px;
|
||||
height:min-content;
|
||||
margin: auto 0;
|
||||
font-size: larger;
|
||||
}
|
||||
.meta span:not(:first-child) {
|
||||
margin-top: 5px;
|
||||
display: inline-block;
|
||||
}
|
||||
.title {
|
||||
font-size: 180%;
|
||||
font-size: 170%;
|
||||
font-weight: bold;
|
||||
color: inherit;
|
||||
max-height: calc((19vh - 10px) / 2);
|
||||
display: inline-block;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
.cover {
|
||||
height: calc(19vh - 10px);
|
||||
border-radius: 5px;
|
||||
}
|
@ -4,17 +4,22 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--textColorLight: #b0b0b0;
|
||||
--textColorDark: #000000;
|
||||
}
|
||||
|
||||
:root, :root[data-theme="day"] {
|
||||
--containerBg: rgba(255,255,255,0.5);
|
||||
--textColor: #000000;
|
||||
color: #000000;
|
||||
--iconColor: #000000;
|
||||
--textColor: var(--textColorDark);
|
||||
color: var(--textColorDark);
|
||||
--iconColor: var(--textColorDark);
|
||||
}
|
||||
:root[data-theme="night"] {
|
||||
--containerBg: rgba(20,20,20,0.8);
|
||||
--textColor: #b0b0b0;
|
||||
color: #b0b0b0;
|
||||
--iconColor: #b0b0b0;
|
||||
--textColor: var(--textColorLight);
|
||||
color: var(--textColorLight);
|
||||
--iconColor: var(--textColorLight);
|
||||
}
|
||||
|
||||
body, main {
|
||||
|
Loading…
Reference in New Issue
Block a user