feat: updates

This commit is contained in:
qier222 2022-06-09 20:16:05 +08:00
parent d4d8dd817b
commit 4c90db789b
No known key found for this signature in database
GPG key ID: 9C85007ED905F14D
14 changed files with 144 additions and 82 deletions

View file

@ -38,19 +38,21 @@ const ArtistRow = ({
<div className={className}>
{/* Title */}
{title && (
<h4 className='mb-6 text-12 font-medium uppercase dark:text-neutral-300 lg:text-14 lg:font-bold'>
<h4
className={cx(
'text-12 font-medium uppercase dark:text-neutral-300 lg:text-14',
'mx-2.5 mb-6 lg:mx-0 lg:font-bold'
)}
>
{title}
</h4>
)}
{/* Artists */}
{artists && (
<div className='no-scrollbar -ml-2.5 flex w-screen snap-x overflow-x-scroll lg:ml-auto lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
{artists.map(artist => (
<div
className='mr-5 snap-start first-of-type:ml-2.5 last-of-type:mr-2.5 lg:mr-0'
key={artist.id}
>
<div className='snap-start px-2.5 lg:px-0' key={artist.id}>
<Artist artist={artist} key={artist.id} />
</div>
))}
@ -59,12 +61,9 @@ const ArtistRow = ({
{/* Placeholder */}
{placeholderRow && !artists && (
<div className='no-scrollbar -ml-2.5 flex w-screen overflow-x-scroll lg:ml-auto lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
<div className='no-scrollbar flex snap-x overflow-x-scroll lg:grid lg:w-auto lg:grid-cols-5 lg:gap-10'>
{[...new Array(placeholderRow * 5).keys()].map(i => (
<div
className='mr-5 first-of-type:ml-2.5 last-of-type:mr-2.5 lg:mr-0'
key={i}
>
<div className='snap-start px-2.5 lg:px-0' key={i}>
<div
className='aspect-square w-full rounded-full bg-white dark:bg-neutral-800'
style={{

View file

@ -1,9 +1,9 @@
import useBreakpoint from '@/web/hooks/useBreakpoint'
import { ReactQueryDevtools } from 'react-query/devtools'
import useIsMobile from '@/web/hooks/useIsMobile'
const Devtool = () => {
const breakpoint = useBreakpoint()
const isMobile = ['sm', 'md'].includes(breakpoint)
const isMobile = useIsMobile()
return (
<ReactQueryDevtools
initialIsOpen={false}
@ -12,7 +12,7 @@ const Devtool = () => {
position: 'fixed',
bottom: isMobile ? 'auto' : 0,
right: 0,
top: isMobile ? 0 : 1,
top: isMobile ? 0 : 'auto',
left: 'auto',
},
}}

View file

@ -14,7 +14,7 @@ const LayoutMobile = () => {
return (
<div id='layout' className='select-none bg-white pb-32 pt-3 dark:bg-black'>
<main className='min-h-screen overflow-y-auto overflow-x-hidden px-2.5 pb-16'>
<main className='min-h-screen overflow-y-auto overflow-x-hidden pb-16'>
<TopbarMobile />
<Router />
</main>
@ -47,6 +47,19 @@ const LayoutMobile = () => {
<MenuBar />
</div>
{/* Notch background */}
{isIOS && isSafari && isPWA && (
<div
className={cx(
'fixed left-0 right-0 bg-black/30 backdrop-blur-sm',
css`
top: -50px;
height: 50px;
`
)}
></div>
)}
</div>
)
}

View file

@ -67,7 +67,7 @@ const PlayLikedSongsCard = () => {
return (
<div
className={cx(
'flex flex-col justify-between rounded-24 p-8 dark:bg-night-600',
'mx-2.5 flex flex-col justify-between rounded-24 p-8 dark:bg-white/10 lg:mx-0',
css`
height: 322px;
`

View file

@ -4,6 +4,7 @@ const Tabs = ({
tabs,
value,
onChange,
className,
}: {
tabs: {
id: string
@ -11,9 +12,10 @@ const Tabs = ({
}[]
value: string
onChange: (id: string) => void
className?: string
}) => {
return (
<div className='no-scrollbar flex overflow-y-auto'>
<div className={cx('no-scrollbar flex overflow-y-auto', className)}>
{tabs.map(tab => (
<div
key={tab.id}

View file

@ -4,7 +4,7 @@ import SettingsButton from './SettingsButton'
const TopbarMobile = () => {
return (
<div className='mb-5 mt-7 flex'>
<div className='mb-5 mt-7 flex px-2.5'>
<div className='flex-grow'>
<SearchBox />
</div>

View file

@ -5,6 +5,7 @@ import { player } from '@/web/store'
import { useSnapshot } from 'valtio'
import Wave from './Wave'
import Icon from '@/web/components/Icon'
import useIsMobile from '@/web/hooks/useIsMobile'
const TrackList = ({
tracks,
@ -20,9 +21,14 @@ const TrackList = ({
() => playerSnapshot.track,
[playerSnapshot.track]
)
const isMobile = useIsMobile()
const handleClick = (e: React.MouseEvent<HTMLElement>, trackID: number) => {
if (e.detail === 2) onPlay?.(trackID)
if (isMobile) {
onPlay?.(trackID)
} else {
if (e.detail === 2) onPlay?.(trackID)
}
}
const playing = useMemo(
@ -38,7 +44,12 @@ const TrackList = ({
onClick={e => handleClick(e, track.id)}
className='group relative flex items-center py-2 text-16 font-medium text-neutral-200 transition duration-300 ease-in-out'
>
<div className='mr-6'>{String(track.no).padStart(2, '0')}</div>
{/* Track no */}
<div className='mr-3 lg:mr-6'>
{String(track.no).padStart(2, '0')}
</div>
{/* Track name */}
<div className='flex flex-grow items-center'>
{track.name}
{playingTrack?.id === track.id && (
@ -47,7 +58,9 @@ const TrackList = ({
</div>
)}
</div>
<div className='mr-12 flex opacity-0 transition-opacity group-hover:opacity-100'>
{/* Desktop context menu */}
<div className='mr-12 hidden opacity-0 transition-opacity group-hover:opacity-100 lg:flex'>
<div className='mr-3 flex h-10 w-10 items-center justify-center rounded-full bg-brand-600 text-white/80'>
{/* <Icon name='play' className='h-7 w-7' /> */}
</div>
@ -58,7 +71,14 @@ const TrackList = ({
{/* <Icon name='play' className='h-7 w-7' /> */}
</div>
</div>
<div className='text-right'>
{/* Mobile menu */}
<div className='lg:hidden'>
<div className='h-10 w-10 rounded-full bg-night-900'></div>
</div>
{/* Track duration */}
<div className='hidden text-right lg:block'>
{formatDuration(track.dt, 'en', 'hh:mm:ss')}
</div>
</div>

View file

@ -4,6 +4,7 @@ import Icon from '@/web/components/Icon'
import dayjs from 'dayjs'
import { useMemo } from 'react'
import Image from './Image'
import useIsMobile from '@/web/hooks/useIsMobile'
const TrackListHeader = ({
album,
@ -18,18 +19,22 @@ const TrackListHeader = ({
const duration = album?.songs?.reduce((acc, cur) => acc + cur.dt, 0) || 0
return formatDuration(duration, 'en', 'hh[hr] mm[min]')
}, [album?.songs])
const isMobile = useIsMobile()
const cover = album?.picUrl || playlist?.coverImgUrl || ''
return (
<div
className={cx(
'grid grid-rows-1 gap-10',
css`
grid-template-columns: 318px auto;
`
'mx-2.5 rounded-48 p-8 dark:bg-white/10',
'lg:mx-0 lg:grid lg:grid-rows-1 lg:gap-10 lg:rounded-none lg:p-0 lg:dark:bg-transparent',
!isMobile &&
css`
grid-template-columns: 318px auto;
`
)}
>
{/* Cover */}
<Image
className='z-10 aspect-square w-full rounded-24'
src={resizeImage(cover, 'lg')}
@ -37,57 +42,77 @@ const TrackListHeader = ({
/>
{/* Blur bg */}
<img
className={cx(
'absolute z-0 object-cover opacity-70',
css`
top: -400px;
left: -370px;
width: 1572px;
height: 528px;
filter: blur(256px) saturate(1.2);
`
)}
src={resizeImage(cover, 'sm')}
/>
{!isMobile && (
<img
className={cx(
'absolute z-0 object-cover opacity-70',
css`
top: -400px;
left: -370px;
width: 1572px;
height: 528px;
filter: blur(256px) saturate(1.2);
`
)}
src={resizeImage(cover, 'sm')}
/>
)}
<div className='flex flex-col justify-between'>
<div>
<div className='text-36 font-medium dark:text-neutral-100'>
{/* Name */}
<div className='mt-2.5 text-28 font-semibold dark:text-night-50 lg:mt-0 lg:text-36 lg:font-medium'>
{album?.name || playlist?.name}
</div>
<div className='mt-6 text-24 font-medium dark:text-neutral-600'>
{/* Creator */}
<div className='mt-2.5 text-24 font-medium dark:text-night-400 lg:mt-6'>
{album?.artist.name || playlist?.creator.nickname}
</div>
<div className='mt-1 flex items-center text-14 font-bold dark:text-neutral-600'>
{/* Extra info */}
<div className='mt-1 flex items-center text-12 font-medium dark:text-night-400 lg:text-14 lg:font-bold'>
{/* Album info */}
{!!album && (
<>
{album?.mark === 1056768 && (
<Icon name='explicit' className='mb-px mr-1 h-3.5 w-3.5 ' />
<Icon
name='explicit'
className='mb-px mr-1 h-3 w-3 lg:h-3.5 lg:w-3.5 '
/>
)}{' '}
{dayjs(album?.publishTime || 0).year()} · {album?.songs.length}{' '}
Tracks, {albumDuration}
tracks, {albumDuration}
</>
)}
{/* Playlist info */}
{!!playlist && (
<>
Updated at {formatDate(playlist?.updateTime || 0, 'en')} ·{' '}
{playlist.trackCount} Tracks
{playlist.trackCount} tracks
</>
)}
</div>
<div className='line-clamp-3 mt-6 whitespace-pre-wrap text-14 font-bold dark:text-neutral-600'>
{album?.description || playlist?.description}
</div>
{/* Description */}
{!isMobile && (
<div className='line-clamp-3 mt-6 whitespace-pre-wrap text-14 font-bold dark:text-night-400 '>
{album?.description || playlist?.description}
</div>
)}
</div>
<div className='z-10 flex'>
{/* Actions */}
<div className='mt-11 flex items-end justify-between lg:z-10 lg:mt-4 lg:justify-start'>
<div className='flex items-end'>
<button className='mr-2.5 h-14 w-14 rounded-full dark:bg-white/10 lg:mr-6 lg:h-[72px] lg:w-[72px]'></button>
<button className='h-14 w-14 rounded-full dark:bg-white/10 lg:mr-6 lg:h-[72px] lg:w-[72px]'></button>
</div>
<button
onClick={() => onPlay()}
className='h-[72px] w-[170px] rounded-full dark:bg-brand-700'
className='h-14 w-[125px] rounded-full dark:bg-brand-700 lg:h-[72px] lg:w-[170px]'
></button>
<button className='ml-6 h-[72px] w-[72px] rounded-full dark:bg-white/10'></button>
<button className='ml-6 h-[72px] w-[72px] rounded-full dark:bg-white/10'></button>
</div>
</div>
</div>