import React, { useEffect, useMemo, useRef, useState } from 'react' import { css, cx } from '@emotion/css' import Icon from '../Icon' import { formatDuration, resizeImage } from '@/web/utils/common' import player from '@/web/states/player' import { useSnapshot } from 'valtio' import { State as PlayerState, Mode as PlayerMode } from '@/web/utils/player' import Slider from './Slider' import { animate, motion, useAnimation } from 'framer-motion' import { ease } from '@/web/utils/const' import useUserLikedTracksIDs, { useMutationLikeATrack, } from '@/web/api/hooks/useUserLikedTracksIDs' import ArtistInline from './ArtistsInLine' const Progress = () => { const { track, progress } = useSnapshot(player) return (
{ player.progress = value }} onlyCallOnChangeAfterDragEnded={true} />
{formatDuration(progress * 1000, 'en', 'hh:mm:ss')} {formatDuration(track?.dt || 0, 'en', 'hh:mm:ss')}
) } const Cover = () => { const playerSnapshot = useSnapshot(player) const [cover, setCover] = useState('') const animationStartTime = useRef(0) const controls = useAnimation() const duration = 150 // ms useEffect(() => { const resizedCover = resizeImage( playerSnapshot.track?.al.picUrl || '', 'lg' ) const animate = async () => { animationStartTime.current = Date.now() await controls.start({ opacity: 0 }) setCover(resizedCover) } animate() }, [controls, playerSnapshot.track?.al.picUrl]) // 防止狂点下一首或上一首造成封面与歌曲不匹配的问题 useEffect(() => { const realCover = resizeImage(playerSnapshot.track?.al.picUrl ?? '', 'lg') if (cover !== realCover) setCover(realCover) }, [cover, playerSnapshot.track?.al.picUrl]) const onLoad = () => { const passedTime = Date.now() - animationStartTime.current controls.start({ opacity: 1, transition: { delay: passedTime > duration ? 0 : (duration - passedTime) / 1000, }, }) } return ( ) } const LikeButton = () => { const { track } = useSnapshot(player) const { data: likedIDs } = useUserLikedTracksIDs() const isLiked = !!likedIDs?.ids?.find(id => id === track?.id) const likeATrack = useMutationLikeATrack() return ( ) } const NowPlaying = () => { const { state, track } = useSnapshot(player) return (
{/* Cover */} {/* Info & Controls */}
{/* Track Info */}
{track?.name}
{/* Dividing line */}
{/* Progress */} {/* Controls */}
) } export default NowPlaying