'use client' import useSWR, {useSWRConfig} from 'swr' import fetcher from '@/lib/fetcher' import Image from 'next/image' import Link from 'next/link' import clsx from 'clsx' import {ElementType, ReactElement, useEffect} from 'react' import {animate} from 'motion' 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 (
) } type PlayerStateResponse = { data: Song error: string isLoading: boolean } function usePlayerState(path: string) { const {mutate} = useSWRConfig() const {data, error, isLoading} = useSWR(`/api/spotify/${path}`, fetcher) as PlayerStateResponse mutate(`/api/spotify/${path}`, data).then(r => r) 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 (

) } export function SpotifyPlayer(): ReactElement | null { const currentlyPlaying = usePlayerState('currently-playing') const lastPlayed = usePlayerState('last-played') if (currentlyPlaying.isError || lastPlayed.isError) return null return (
{currentlyPlaying.isLoading ? : currentlyPlaying.song?.isPlaying ? : lastPlayed.isLoading ? : }
) }