import useSWR from 'swr' import fetcher from '@/lib/fetcher' import Image from 'next/image' import Link from 'next/link' import clsx from 'clsx' import {useEffect, ReactElement, ElementType} from 'react' import {animate} from 'motion' type PlayerStateParams = { path: string options?: { refreshInterval: number } } type Status = { as?: ElementType isPlaying: boolean } type Artist = { as?: ElementType artist: string } type Title = { as?: ElementType title: string songUrl: string className?: string } type Album = { album: string albumImageUrl: string } type Song = { as?: ElementType } & Artist & Title & Album & Status function AnimatedBars() { useEffect(() => { animate( '#bar1', { transform: [ 'scaleY(1.0) translateY(0rem)', 'scaleY(1.5) translateY(-0.082rem)', 'scaleY(1.0) translateY(0rem)' ] }, { duration: 1.0, repeat: Infinity, easing: ['ease-in-out'] } ); animate( '#bar2', { transform: [ 'scaleY(1.0) translateY(0rem)', 'scaleY(3) translateY(-0.083rem)', 'scaleY(1.0) translateY(0rem)' ] }, { delay: 0.2, duration: 1.5, repeat: Infinity, easing: ['ease-in-out'] } ); animate( '#bar3', { transform: [ 'scaleY(1.0) translateY(0rem)', 'scaleY(0.5) translateY(0.37rem)', 'scaleY(1.0) translateY(0rem)' ] }, { delay: 0.3, duration: 1.5, repeat: Infinity, easing: ['ease-in-out'] } ); }, []) return (
) } function usePlayerState({path, options}: PlayerStateParams) { const {data, error, isLoading} = useSWR(`/api/spotify/${path}`, fetcher, options) return { song: data, isLoading, isError: error } } function Song({as: Component = 'div', artist, title, songUrl, album, albumImageUrl, isPlaying}: Song) { return ( {isPlaying && }
) } Song.Album = function SongAlbum({album, albumImageUrl}: Album) { return ( {album} ) } Song.Title = function SongTitle({as: Component = 'h2', title, songUrl, className}: Title) { return ( {title} ) } Song.Artist = function SongArtist({as: Component = 'p', artist}: Artist) { return ( {artist} ) } Song.Skeleton = function SongSkeleton() { return (

) } function LastPlayed(): ReactElement | null { const {song, isLoading, isError} = usePlayerState( { path: 'last-played' } ) if (isError) return null return ( <> {isLoading ? : song?.title && } ) } export function SpotifyPlayer(): ReactElement | null { const {song, isLoading, isError} = usePlayerState( { path: 'currently-playing', options: { refreshInterval: 30000 } }) if (isError) return null return (
{isLoading ? : song?.isPlaying ? : }
) }