mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-05 08:28:54 +08:00
93 lines
2.6 KiB
TypeScript
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
|
|
)
|
|
})
|