YesPlayMusic/packages/web/components/PlayingNextMobile.tsx

87 lines
2.4 KiB
TypeScript
Raw Normal View History

2022-06-30 00:02:21 +08:00
import { css, cx } from '@emotion/css'
2022-08-03 23:48:39 +08:00
import { motion, useDragControls, AnimatePresence } from 'framer-motion'
import { useState } from 'react'
2022-06-25 13:47:07 +08:00
import { useLockBodyScroll } from 'react-use'
import PlayingNext from './PlayingNext'
2022-06-30 00:02:21 +08:00
import { ease } from '@/web/utils/const'
2022-07-11 11:06:41 +08:00
import { useSnapshot } from 'valtio'
import uiStates from '@/web/states/uiStates'
import Icon from '@/web/components/Icon'
2022-06-25 13:47:07 +08:00
const PlayingNextMobile = () => {
2022-07-11 11:06:41 +08:00
const { mobileShowPlayingNext: display } = useSnapshot(uiStates)
2022-06-30 00:02:21 +08:00
const [isDragging, setIsDragging] = useState(false)
2022-07-11 11:06:41 +08:00
useLockBodyScroll(isDragging)
2022-06-30 00:02:21 +08:00
const dragControls = useDragControls()
2022-06-25 13:47:07 +08:00
return (
2022-06-30 00:02:21 +08:00
<AnimatePresence>
2022-07-11 11:06:41 +08:00
{display && (
2022-06-30 00:02:21 +08:00
<motion.div
2022-07-11 11:06:41 +08:00
className='fixed inset-0 bg-black/80 backdrop-blur-3xl'
exit={{
y: '100%',
borderRadius: '24px',
transition: {
ease: 'easeOut',
duration: 0.4,
},
}}
animate={{ y: 0, borderRadius: 0 }}
initial={{ y: '100%', borderRadius: '24px' }}
transition={{ duration: 0.6, ease }}
dragControls={dragControls}
dragListener={false}
whileDrag={{
borderRadius: '24px',
transition: {
duration: 0.2,
ease: 'linear',
},
2022-06-30 00:02:21 +08:00
}}
dragConstraints={{ top: 0, bottom: 0 }}
2022-07-11 11:06:41 +08:00
dragDirectionLock={true}
onDragEnd={(event, info) => {
setIsDragging(false)
const offset = info.offset.y
if (offset > 150) {
uiStates.mobileShowPlayingNext = false
}
}}
drag='y'
2022-06-30 00:02:21 +08:00
>
2022-07-11 11:06:41 +08:00
{/* Indictor */}
2022-06-30 00:02:21 +08:00
<motion.div
2022-07-11 11:06:41 +08:00
onPointerDown={e => {
setIsDragging(true)
dragControls.start(e)
}}
onClick={() => {
uiStates.mobileShowPlayingNext = false
}}
className={cx(
'flex flex-col justify-end',
css`
height: 108px;
`
)}
>
<Icon
name='player-handler'
className='mb-5 h-2.5 rotate-180 text-brand-700'
/>
</motion.div>
2022-06-30 00:02:21 +08:00
2022-07-11 11:06:41 +08:00
{/* List */}
<div className='relative h-full px-7'>
<PlayingNext />
</div>
</motion.div>
)}
2022-06-30 00:02:21 +08:00
</AnimatePresence>
2022-06-25 13:47:07 +08:00
)
}
export default PlayingNextMobile