import { formatDate, formatDuration, isIOS, isSafari, resizeImage, } from '@/web/utils/common' import { css, cx } from '@emotion/css' import Icon from '@/web/components/Icon' import dayjs from 'dayjs' import Image from './Image' import useIsMobile from '@/web/hooks/useIsMobile' import { memo, useEffect, useMemo, useRef } from 'react' import Hls from 'hls.js' import Plyr, { APITypes, PlyrProps, PlyrInstance } from 'plyr-react' import useVideoCover from '@/web/hooks/useVideoCover' import { motion } from 'framer-motion' import { ease } from '@/web/utils/const' import { injectGlobal } from '@emotion/css' injectGlobal` .plyr__video-wrapper, .plyr--video { background-color: transparent !important; } ` const VideoCover = ({ source }: { source?: string }) => { const ref = useRef(null) useEffect(() => { const loadVideo = async () => { if (!source || !Hls.isSupported()) return const video = document.getElementById('plyr') as HTMLVideoElement const hls = new Hls() hls.loadSource(source) hls.attachMedia(video) // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ref.current!.plyr.media = video hls.on(Hls.Events.MANIFEST_PARSED, () => { // eslint-disable-next-line @typescript-eslint/no-extra-semi ;(ref.current!.plyr as PlyrInstance).play() }) } loadVideo() }) return (
) } const Cover = memo( ({ album, playlist }: { album?: Album; playlist?: Playlist }) => { const isMobile = useIsMobile() const { data: videoCover } = useVideoCover({ id: album?.id, name: album?.name, artist: album?.artist.name, }) const cover = album?.picUrl || playlist?.coverImgUrl || '' return ( <>
Cover {videoCover && ( {isSafari ? ( ) : ( )} )}
{/* Blur bg */} {!isMobile && ( )} ) } ) Cover.displayName = 'Cover' const TrackListHeader = ({ album, playlist, onPlay, }: { album?: Album playlist?: Playlist onPlay: () => void }) => { const isMobile = useIsMobile() const albumDuration = useMemo(() => { const duration = album?.songs?.reduce((acc, cur) => acc + cur.dt, 0) || 0 return formatDuration(duration, 'en', 'hh[hr] mm[min]') }, [album?.songs]) return (
{/* Name */}
{album?.name || playlist?.name}
{/* Creator */}
{album?.artist.name || playlist?.creator.nickname}
{/* Extra info */}
{/* Album info */} {!!album && ( <> {album?.mark === 1056768 && ( )}{' '} {dayjs(album?.publishTime || 0).year()} · {album?.songs.length}{' '} tracks, {albumDuration} )} {/* Playlist info */} {!!playlist && ( <> Updated at {formatDate(playlist?.updateTime || 0, 'en')} ·{' '} {playlist.trackCount} tracks )}
{/* Description */} {!isMobile && (
{album?.description || playlist?.description}
)}
{/* Actions */}
) } export default TrackListHeader