2024-03-23 17:04:11 +08:00

93 lines
2.6 KiB
TypeScript

import { useMemo, useRef, useImperativeHandle, forwardRef, useState } from 'react'
import { useI18n } from '@/lang'
import Menu, { type MenuType, type Position } from '@/components/common/Menu'
import { hasDislike } from '@/core/dislikeList'
export interface SelectInfo {
musicInfo: LX.Music.MusicInfoOnline
selectedList: LX.Music.MusicInfoOnline[]
index: number
single: boolean
}
const initSelectInfo = {}
export interface ListMenuProps {
onPlay: (selectInfo: SelectInfo) => void
onPlayLater: (selectInfo: SelectInfo) => void
onAdd: (selectInfo: SelectInfo) => void
onCopyName: (selectInfo: SelectInfo) => void
onDislikeMusic: (selectInfo: SelectInfo) => void
onDownload: (selectInfo: SelectInfo) => void
}
export interface ListMenuType {
show: (selectInfo: SelectInfo, position: Position) => void
}
export type {
Position,
}
export default forwardRef<ListMenuType, ListMenuProps>((props: ListMenuProps, ref) => {
const t = useI18n()
const [visible, setVisible] = useState(false)
const menuRef = useRef<MenuType>(null)
const selectInfoRef = useRef<SelectInfo>(initSelectInfo as SelectInfo)
const [isDislikeMusic, setDislikeMusic] = useState(false)
useImperativeHandle(ref, () => ({
show(selectInfo, position) {
selectInfoRef.current = selectInfo
setDislikeMusic(hasDislike(selectInfo.musicInfo))
if (visible) menuRef.current?.show(position)
else {
setVisible(true)
requestAnimationFrame(() => {
menuRef.current?.show(position)
})
}
},
}))
const menus = useMemo(() => {
return [
{ action: 'play', label: t('play') },
{ action: 'playLater', label: t('play_later') },
{ action: 'download', label: '下载' },
{ action: 'add', label: t('add_to') },
{ action: 'copyName', label: t('copy_name') },
{ action: 'dislike', label: t('dislike'), disabled: isDislikeMusic },
] as const
}, [t, isDislikeMusic])
const handleMenuPress = ({ action }: typeof menus[number]) => {
const selectInfo = selectInfoRef.current
switch (action) {
case 'play':
props.onPlay(selectInfo)
break
case 'playLater':
props.onPlayLater(selectInfo)
break
case 'add':
props.onAdd(selectInfo)
break
case 'copyName':
props.onCopyName(selectInfo)
break
case 'dislike':
props.onDislikeMusic(selectInfo)
break
case 'download':
props.onDownload(selectInfo)
default:
break
}
}
return (
visible
? <Menu ref={menuRef} menus={menus} onPress={handleMenuPress} />
: null
)
})