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((props: ListMenuProps, ref) => { const t = useI18n() const [visible, setVisible] = useState(false) const menuRef = useRef(null) const selectInfoRef = useRef(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 ? : null ) })