diff --git a/src/components/MusicPlayer.tsx b/src/components/MusicPlayer.tsx new file mode 100644 index 0000000..73dc4bf --- /dev/null +++ b/src/components/MusicPlayer.tsx @@ -0,0 +1,106 @@ +import { useState } from "react"; +import { useTerminal } from "~/context/TerminalContext"; +import { Text } from "./Text"; + +const formatDurationMSS = (duration: number) => { + const minutes = Math.floor(duration / 60); + const seconds = duration % 60; + + return `${minutes}:${seconds.toString().padStart(2, "0")}`; +}; + +export const MusicPlayer = (props: { + title: string; + artist: string; + album: string; + duration: number; + played: number; +}) => { + const terminal = useTerminal(); + + const [isPlaying, setIsPlaying] = useState(false); + setIsPlaying; + + const innerWidth = terminal.cols - 2; + + const timeString = `${formatDurationMSS(props.played)}/${formatDurationMSS( + props.duration, + )}`; + const barSize = Math.max( + 1, + Math.floor((props.played / props.duration) * innerWidth), + ); + + const beforeText_pos = innerWidth / 2 - timeString.length / 2; + const beforeText_filled = Math.min(barSize, beforeText_pos); + const beforeText_empty = beforeText_pos - beforeText_filled; + + const afterText_pos = innerWidth / 2 + timeString.length / 2; + const afterText_filled = Math.max( + 0, + Math.min(barSize, innerWidth - timeString.length) - afterText_pos, + ); + const afterText_empty = + innerWidth - afterText_pos - afterText_filled + 1 - (innerWidth % 2); + + return ( +
+ {/* Top bar */}
+ <>
+
+ >
+
+ <>
+
+ >
+
+ <>
+
+ >
+
+ <>
+
+ >
+
+