diff --git a/src/components/Music/SpotifyPlayer.tsx b/src/components/Music/SpotifyPlayer.tsx index 3c4624b..efb5419 100644 --- a/src/components/Music/SpotifyPlayer.tsx +++ b/src/components/Music/SpotifyPlayer.tsx @@ -4,15 +4,9 @@ import { CharArray } from "../../utils/string"; import { CHAR_HEIGHT, CHAR_WIDTH } from "../Kitty"; import { type InnerKittyProps } from "~/utils/types"; import { useKitty } from "~/hooks/useKitty"; +import { type CurrentlyPlaying } from "."; -export const SpotifyPlayer = (props: { - title: string; - artist: string; - album: string; - duration: number; - played: number; - onTogglePause: (state: boolean) => void; -}) => { +export const SpotifyPlayer = (props: { playing: CurrentlyPlaying | null }) => { const kitty = useKitty(); return ( @@ -33,16 +27,60 @@ export const SpotifyPlayer = (props: { }; const InnerSpotifyPlayer = (props: InnerKittyProps) => { - const [paused, setPaused] = useState(false); + if (props.playing === null) { + return ( + <> + {/* title */} + + Playback + + + {/* border right */} + + + {"│\n".repeat(props.rows - 2)} + + + + {/* borer left */} + + + {"│\n".repeat(props.rows - 2)} + + + + {/* border top */} + + {"─".repeat(props.cols - 2 - 8)} + + + {/* border bottom */} + + {"─".repeat(props.cols - 2)} + + + {/* body */} +
+ No playback found +
+ I'm not listening to anything right now +
+ + ); + } const fillSize = Math.round( - (props.played / props.duration) * (props.cols - 2), + (props.playing.progress_ms / props.playing.item.duration_ms) * + (props.cols - 2), ); const emptySize = props.cols - 2 - fillSize; - const timeString = `${formatMMSS(props.played)}/${formatMMSS( - props.duration, - )}`; + const timeString = `${formatMMSS( + props.playing.progress_ms / 1000, + )}/${formatMMSS(props.playing.item.duration_ms / 1000)}`; const timeStringLeft = Math.round( (props.cols - 2) / 2 - timeString.length / 2, ); @@ -54,11 +92,6 @@ const InnerSpotifyPlayer = (props: InnerKittyProps) => { .write(timeStringLeft - fillSize, timeString) .toString(); - const handleTogglePause = () => { - setPaused(!paused); - props.onTogglePause(!paused); - }; - return ( <> {/* title */} @@ -96,13 +129,12 @@ const InnerSpotifyPlayer = (props: InnerKittyProps) => { {/* body */}
- - {paused ? "\udb81\udc0a " : "\udb80\udfe4 "} - - {props.title} · {props.artist} + {false ? "\udb81\udc0a " : "\udb80\udfe4 "} + {props.playing.item.name} ·{" "} + {props.playing.item.artists.map((a) => a.name).join(", ")}
- {props.album} + {props.playing.item.album.name}
{fill} diff --git a/src/components/Music/index.tsx b/src/components/Music/index.tsx index 707ef78..8e782bb 100644 --- a/src/components/Music/index.tsx +++ b/src/components/Music/index.tsx @@ -1,93 +1,79 @@ -import { useCallback, useEffect, useRef, useState } from "react"; -import { type IAudioMetadata, parseBlob } from "music-metadata-browser"; +import { useEffect, useState } from "react"; import { Kitty } from "../Kitty"; import { SpotifyPlayer } from "./SpotifyPlayer"; -import { Cava } from "./Cava"; import { useApp } from "~/hooks/useApp"; import { cn, hideIf } from "~/utils/react"; -const song = "/audio/asinine-vivement-quoi.mp3"; +export type CurrentlyPlaying = { + item: { + album: { + name: string; + }; + name: string; + artists: { name: string }[]; + duration_ms: number; + }; + progress_ms: number; +}; export const Music = () => { - const { volume, screenWidth } = useApp(); - - const audio = useRef(null); - - const [metadata, setMetadata] = useState(); - const [currentTime, setCurrentTime] = useState(0); - - const handleTimeUpdate = useCallback(() => { - setCurrentTime(audio.current?.currentTime ?? 0); - }, []); - - const handleTogglePause = useCallback((paused: boolean) => { - if (!audio.current) return; - - if (paused) { - void audio.current.pause(); - } else { - void audio.current.play(); - } - }, []); + const { screenWidth } = useApp(); + const [playing, setPlaying] = useState(null); useEffect(() => { - if (metadata) return; + const fetchCurrentlyPlaying = () => + fetch("http://213.210.20.230:3000/currently-playing?format=json") + .then((r) => r.json()) + .then((data: CurrentlyPlaying) => { + data.progress_ms = Math.max(0, data.progress_ms - 1500); + setPlaying(data); + }) + .catch(() => setPlaying(null)); - void fetch(song) - .then((r) => r.blob()) - .then((b) => parseBlob(b)) - .then((m) => { - if (!audio.current) return; + const interval = setInterval(() => { + setPlaying((prev) => { + if (prev === null) return null; - setMetadata(m); - audio.current.volume = 0.5; + if (prev.progress_ms >= prev.item.duration_ms) { + void fetchCurrentlyPlaying(); + return prev; + } + + return { + ...prev, + progress_ms: Math.min(prev.item.duration_ms, prev.progress_ms + 1000), + }; }); - }, [metadata]); + }, 1000); - useEffect(() => { - if (audio.current) { - audio.current.volume = volume / 400; - } - }, [volume]); + void fetchCurrentlyPlaying(); + + return () => { + clearInterval(interval); + }; + }, []); return (
-
); };