138 lines
3.7 KiB
TypeScript
Raw Normal View History

2022-05-12 02:45:43 +08:00
import ArtistInline from '@/web/components/ArtistsInline'
import Skeleton from '@/web/components/Skeleton'
import { player } from '@/web/store'
import { resizeImage } from '@/web/utils/common'
2022-05-29 17:53:27 +08:00
import Icon from './Icon'
import { cx } from '@emotion/css'
2022-05-12 02:45:43 +08:00
import { useMemo } from 'react'
import { useSnapshot } from 'valtio'
2022-03-13 14:40:38 +08:00
2022-03-23 01:21:22 +08:00
const Track = ({
2022-03-13 14:40:38 +08:00
track,
isSkeleton = false,
2022-03-23 01:21:22 +08:00
isHighlight = false,
2022-04-02 18:46:08 +08:00
onClick,
2022-03-13 14:40:38 +08:00
}: {
track: Track
2022-04-02 18:46:08 +08:00
isSkeleton?: boolean
isHighlight?: boolean
onClick: (e: React.MouseEvent<HTMLElement>, trackID: number) => void
2022-03-13 14:40:38 +08:00
}) => {
return (
<div
2022-04-02 18:46:08 +08:00
onClick={e => onClick(e, track.id)}
2022-05-12 02:45:43 +08:00
className={cx(
2022-03-23 01:21:22 +08:00
'group grid w-full rounded-xl after:scale-[.98] after:rounded-xl ',
'grid-cols-1 py-1.5 px-2',
!isSkeleton && {
'btn-hover-animation after:bg-gray-100 dark:after:bg-white/10':
!isHighlight,
'bg-brand-50 dark:bg-gray-800': isHighlight,
}
2022-03-13 14:40:38 +08:00
)}
>
2022-03-17 19:30:43 +08:00
<div className='grid grid-cols-[3rem_auto] items-center'>
2022-03-13 14:40:38 +08:00
{/* Cover */}
<div>
2022-04-02 18:46:08 +08:00
{isSkeleton ? (
<Skeleton className='mr-4 h-9 w-9 rounded-md border border-gray-100' />
) : (
2022-03-13 14:40:38 +08:00
<img
src={resizeImage(track.al.picUrl, 'xs')}
2022-03-17 19:30:43 +08:00
className='box-content h-9 w-9 rounded-md border border-black border-opacity-[.03]'
2022-03-13 14:40:38 +08:00
/>
)}
</div>
{/* Track name & Artists */}
2022-03-17 19:30:43 +08:00
<div className='flex flex-col justify-center'>
2022-04-02 18:46:08 +08:00
{isSkeleton ? (
<Skeleton className='text-base '>PLACEHOLDER12345</Skeleton>
) : (
2022-03-13 14:40:38 +08:00
<div
2022-05-12 02:45:43 +08:00
className={cx(
2022-04-02 18:46:08 +08:00
'line-clamp-1 break-all text-base font-semibold ',
isHighlight ? 'text-brand-500' : 'text-black dark:text-white'
)}
2022-03-13 14:40:38 +08:00
>
{track.name}
</div>
)}
2022-03-23 01:21:22 +08:00
<div className='text-xs text-gray-500 dark:text-gray-400'>
2022-03-24 14:23:04 +08:00
{isSkeleton ? (
2022-03-17 19:30:43 +08:00
<Skeleton className='w-2/3 translate-y-px'>PLACE</Skeleton>
2022-03-24 14:23:04 +08:00
) : (
<span className='flex items-center'>
{track.mark === 1318912 && (
2022-05-29 17:53:27 +08:00
<Icon
2022-03-24 14:23:04 +08:00
name='explicit'
2022-05-12 02:45:43 +08:00
className={cx(
2022-04-02 18:46:08 +08:00
'mr-1 h-3 w-3',
isHighlight
? 'text-brand-500'
: 'text-gray-300 dark:text-gray-500'
)}
2022-03-24 14:23:04 +08:00
/>
)}
2022-04-02 18:46:08 +08:00
<ArtistInline
artists={track.ar}
disableLink={true}
className={
isHighlight
? 'text-brand-500'
: 'text-gray-600 dark:text-gray-400'
}
/>
2022-03-24 14:23:04 +08:00
</span>
2022-03-13 14:40:38 +08:00
)}
</div>
</div>
</div>
</div>
)
}
2022-03-23 01:21:22 +08:00
const TrackGrid = ({
tracks,
isSkeleton = false,
onTrackDoubleClick,
2022-03-29 00:11:05 +08:00
cols = 2,
2022-03-23 01:21:22 +08:00
}: {
tracks: Track[]
isSkeleton?: boolean
onTrackDoubleClick?: (trackID: number) => void
2022-03-29 00:11:05 +08:00
cols?: number
2022-03-23 01:21:22 +08:00
}) => {
2022-04-02 18:46:08 +08:00
const handleClick = (e: React.MouseEvent<HTMLElement>, trackID: number) => {
if (e.detail === 2) onTrackDoubleClick?.(trackID)
}
const playerSnapshot = useSnapshot(player)
const playingTrack = useMemo(
() => playerSnapshot.track,
[playerSnapshot.track]
)
2022-03-23 01:21:22 +08:00
return (
2022-03-29 00:11:05 +08:00
<div
className='grid gap-x-2'
style={{
gridTemplateColumns: `repeat(${cols}, minmax(0, 1fr))`,
}}
>
2022-03-23 01:21:22 +08:00
{tracks.map((track, index) => (
2022-03-29 00:11:05 +08:00
<Track
2022-04-02 18:46:08 +08:00
onClick={handleClick}
2022-03-29 00:11:05 +08:00
key={track.id}
track={track}
isSkeleton={isSkeleton}
2022-04-02 18:46:08 +08:00
isHighlight={track.id === playingTrack?.id}
2022-03-29 00:11:05 +08:00
/>
2022-03-23 01:21:22 +08:00
))}
</div>
)
}
export default TrackGrid