新增打开当前歌曲详情页菜单,可以在歌曲菜单中使用

This commit is contained in:
lyswhut 2024-07-13 11:23:54 +08:00
parent fd56d2b9b9
commit 13446c95ee
9 changed files with 47 additions and 21 deletions

View File

@ -4,5 +4,8 @@
### 新增 ### 新增
- 新增重复歌曲列表可以方便移除我的列表中的重复歌曲此列表会列出目标列表里歌曲名相同的歌曲可在“我的列表”里的列表名菜单中使用该功能与PC端的区别是可以点击歌曲名多选删除 - 新增重复歌曲列表可以方便移除我的列表中的重复歌曲此列表会列出目标列表里歌曲名相同的歌曲可在“我的列表”里的列表名菜单中使用该功能与PC端的区别是可以点击歌曲名多选删除
- 新增打开当前歌曲详情页菜单,可以在歌曲菜单中使用
### 其他
- 更新 React native 到 v0.73.9 - 更新 React native 到 v0.73.9

View File

@ -16,6 +16,7 @@ export interface ListMenuProps {
onPlayLater: (selectInfo: SelectInfo) => void onPlayLater: (selectInfo: SelectInfo) => void
onAdd: (selectInfo: SelectInfo) => void onAdd: (selectInfo: SelectInfo) => void
onCopyName: (selectInfo: SelectInfo) => void onCopyName: (selectInfo: SelectInfo) => void
onMusicSourceDetail: (selectInfo: SelectInfo) => void
onDislikeMusic: (selectInfo: SelectInfo) => void onDislikeMusic: (selectInfo: SelectInfo) => void
} }
export interface ListMenuType { export interface ListMenuType {
@ -54,6 +55,7 @@ export default forwardRef<ListMenuType, ListMenuProps>((props: ListMenuProps, re
// { action: 'download', label: '下载' }, // { action: 'download', label: '下载' },
{ action: 'add', label: t('add_to') }, { action: 'add', label: t('add_to') },
{ action: 'copyName', label: t('copy_name') }, { action: 'copyName', label: t('copy_name') },
{ action: 'musicSourceDetail', label: t('music_source_detail') },
{ action: 'dislike', label: t('dislike'), disabled: isDislikeMusic }, { action: 'dislike', label: t('dislike'), disabled: isDislikeMusic },
] as const ] as const
}, [t, isDislikeMusic]) }, [t, isDislikeMusic])
@ -73,6 +75,10 @@ export default forwardRef<ListMenuType, ListMenuProps>((props: ListMenuProps, re
case 'copyName': case 'copyName':
props.onCopyName(selectInfo) props.onCopyName(selectInfo)
break break
case 'musicSourceDetail':
props.onMusicSourceDetail(selectInfo)
// setVIsibleMusicPosition(true)
break
case 'dislike': case 'dislike':
props.onDislikeMusic(selectInfo) props.onDislikeMusic(selectInfo)
break break

View File

@ -6,7 +6,7 @@ import ListMenu, { type ListMenuType, type Position, type SelectInfo } from './L
import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal' import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal'
import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal' import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal'
import MultipleModeBar, { type MultipleModeBarType, type SelectMode } from './MultipleModeBar' import MultipleModeBar, { type MultipleModeBarType, type SelectMode } from './MultipleModeBar'
import { handleDislikeMusic, handlePlay, handlePlayLater, handleShare } from './listAction' import { handleDislikeMusic, handlePlay, handlePlayLater, handleShare, handleShowMusicSourceDetail } from './listAction'
import { createStyle } from '@/utils/tools' import { createStyle } from '@/utils/tools'
export interface OnlineListProps { export interface OnlineListProps {
@ -109,6 +109,7 @@ export default forwardRef<OnlineListType, OnlineListProps>(({
onPlayLater={info => { hancelExitSelect(); handlePlayLater(info.musicInfo, info.selectedList, hancelExitSelect) }} onPlayLater={info => { hancelExitSelect(); handlePlayLater(info.musicInfo, info.selectedList, hancelExitSelect) }}
onCopyName={info => { handleShare(info.musicInfo) }} onCopyName={info => { handleShare(info.musicInfo) }}
onAdd={handleAddMusic} onAdd={handleAddMusic}
onMusicSourceDetail={info => { void handleShowMusicSourceDetail(info.musicInfo) }}
onDislikeMusic={info => { void handleDislikeMusic(info.musicInfo) }} onDislikeMusic={info => { void handleDislikeMusic(info.musicInfo) }}
/> />
{/* <LoadingMask ref={loadingMaskRef} /> */} {/* <LoadingMask ref={loadingMaskRef} /> */}

View File

@ -4,9 +4,11 @@ import { playList, playNext } from '@/core/player/player'
import { addTempPlayList } from '@/core/player/tempPlayList' import { addTempPlayList } from '@/core/player/tempPlayList'
import settingState from '@/store/setting/state' import settingState from '@/store/setting/state'
import { getListMusicSync } from '@/utils/listManage' import { getListMusicSync } from '@/utils/listManage'
import { confirmDialog, shareMusic, toast } from '@/utils/tools' import { confirmDialog, openUrl, shareMusic, toast } from '@/utils/tools'
import { addDislikeInfo, hasDislike } from '@/core/dislikeList' import { addDislikeInfo, hasDislike } from '@/core/dislikeList'
import playerState from '@/store/player/state' import playerState from '@/store/player/state'
import musicSdk from '@/utils/musicSdk'
import { toOldMusicInfo } from '@/utils'
export const handlePlay = (musicInfo: LX.Music.MusicInfoOnline) => { export const handlePlay = (musicInfo: LX.Music.MusicInfoOnline) => {
void addListMusics(LIST_IDS.DEFAULT, [musicInfo], settingState.setting['list.addMusicLocationType']).then(() => { void addListMusics(LIST_IDS.DEFAULT, [musicInfo], settingState.setting['list.addMusicLocationType']).then(() => {
@ -29,6 +31,13 @@ export const handleShare = (musicInfo: LX.Music.MusicInfoOnline) => {
shareMusic(settingState.setting['common.shareType'], settingState.setting['download.fileName'], musicInfo) shareMusic(settingState.setting['common.shareType'], settingState.setting['download.fileName'], musicInfo)
} }
export const handleShowMusicSourceDetail = async(minfo: LX.Music.MusicInfoOnline) => {
const url = musicSdk[minfo.source as LX.OnlineSource]?.getMusicDetailPageUrl(toOldMusicInfo(minfo))
if (!url) return
void openUrl(url)
}
export const handleDislikeMusic = async(musicInfo: LX.Music.MusicInfoOnline) => { export const handleDislikeMusic = async(musicInfo: LX.Music.MusicInfoOnline) => {
const confirm = await confirmDialog({ const confirm = await confirmDialog({
message: global.i18n.t('lists_dislike_music_tip', { name: musicInfo.name }), message: global.i18n.t('lists_dislike_music_tip', { name: musicInfo.name }),

View File

@ -149,6 +149,7 @@
"metadata_edit_modal_tip": "Song name cannot be empty", "metadata_edit_modal_tip": "Song name cannot be empty",
"metadata_edit_modal_title": "Edit song tags", "metadata_edit_modal_title": "Edit song tags",
"move_to": "Move to...", "move_to": "Move to...",
"music_source_detail": "Song page",
"name": "Name: {name}", "name": "Name: {name}",
"nav_exit": "Exit application", "nav_exit": "Exit application",
"nav_love": "Collection", "nav_love": "Collection",

View File

@ -149,6 +149,7 @@
"metadata_edit_modal_tip": "歌曲名不能为空", "metadata_edit_modal_tip": "歌曲名不能为空",
"metadata_edit_modal_title": "编辑歌曲标签", "metadata_edit_modal_title": "编辑歌曲标签",
"move_to": "移动到...", "move_to": "移动到...",
"music_source_detail": "歌曲详情页",
"name": "歌曲名:{name}", "name": "歌曲名:{name}",
"nav_exit": "退出应用", "nav_exit": "退出应用",
"nav_love": "我的收藏", "nav_love": "我的收藏",

View File

@ -21,6 +21,7 @@ export interface ListMenuProps {
onEditMetadata: (selectInfo: SelectInfo) => void onEditMetadata: (selectInfo: SelectInfo) => void
onCopyName: (selectInfo: SelectInfo) => void onCopyName: (selectInfo: SelectInfo) => void
onChangePosition: (selectInfo: SelectInfo) => void onChangePosition: (selectInfo: SelectInfo) => void
onMusicSourceDetail: (selectInfo: SelectInfo) => void
onDislikeMusic: (selectInfo: SelectInfo) => void onDislikeMusic: (selectInfo: SelectInfo) => void
onRemove: (selectInfo: SelectInfo) => void onRemove: (selectInfo: SelectInfo) => void
} }
@ -65,35 +66,26 @@ export default forwardRef<ListMenuType, ListMenuProps>((props, ref) => {
// { action: 'download', label: '下载' }, // { action: 'download', label: '下载' },
{ action: 'add', label: t('add_to') }, { action: 'add', label: t('add_to') },
{ action: 'move', label: t('move_to') }, { action: 'move', label: t('move_to') },
{ action: 'copyName', label: t('copy_name') },
{ action: 'changePosition', label: t('change_position') }, { action: 'changePosition', label: t('change_position') },
{ action: 'copyName', label: t('copy_name') },
{ action: 'musicSourceDetail', disabled: musicInfo.source == 'local', label: t('music_source_detail') },
// { action: 'musicSearch', label: t('music_search') },
{ action: 'dislike', disabled: hasDislike(musicInfo), label: t('dislike') }, { action: 'dislike', disabled: hasDislike(musicInfo), label: t('dislike') },
{ action: 'remove', label: t('delete') }, { action: 'remove', label: t('delete') },
] ]
if (musicInfo.source == 'local') menu.splice(4, 0, { action: 'editMetadata', disabled: !edit_metadata, label: t('edit_metadata') }) if (musicInfo.source == 'local') menu.splice(5, 0, { action: 'editMetadata', disabled: !edit_metadata, label: t('edit_metadata') })
setMenus(menu) setMenus(menu)
void Promise.all([hasEditMetadata(musicInfo)]).then(([_edit_metadata]) => { void Promise.all([hasEditMetadata(musicInfo)]).then(([_edit_metadata]) => {
// console.log(_edit_metadata) // console.log(_edit_metadata)
let isUpdated = true let isUpdated = false
if (edit_metadata != _edit_metadata) { if (edit_metadata != _edit_metadata) {
edit_metadata = _edit_metadata edit_metadata = _edit_metadata
isUpdated ||= true isUpdated ||= true
} }
if (isUpdated) { if (isUpdated) {
const menu = [ menu[menu.findIndex(m => m.action == 'editMetadata')].disabled = !edit_metadata
{ action: 'play', label: t('play') }, setMenus([...menu])
{ action: 'playLater', label: t('play_later') },
// { action: 'download', label: '下载' },
{ action: 'add', label: t('add_to') },
{ action: 'move', label: t('move_to') },
{ action: 'copyName', label: t('copy_name') },
{ action: 'changePosition', label: t('change_position') },
{ action: 'dislike', disabled: hasDislike(musicInfo), label: t('dislike') },
{ action: 'remove', label: t('delete') },
]
if (musicInfo.source == 'local') menu.splice(4, 0, { action: 'editMetadata', disabled: !edit_metadata, label: t('edit_metadata') })
setMenus(menu)
} }
}) })
} }
@ -132,6 +124,10 @@ export default forwardRef<ListMenuType, ListMenuProps>((props, ref) => {
props.onChangePosition(selectInfo) props.onChangePosition(selectInfo)
// setVIsibleMusicPosition(true) // setVIsibleMusicPosition(true)
break break
case 'musicSourceDetail':
props.onMusicSourceDetail(selectInfo)
// setVIsibleMusicPosition(true)
break
case 'dislike': case 'dislike':
props.onDislikeMusic(selectInfo) props.onDislikeMusic(selectInfo)
break break

View File

@ -2,7 +2,7 @@ import { useCallback, useRef } from 'react'
import listState from '@/store/list/state' import listState from '@/store/list/state'
import ListMenu, { type ListMenuType, type Position, type SelectInfo } from './ListMenu' import ListMenu, { type ListMenuType, type Position, type SelectInfo } from './ListMenu'
import { handleDislikeMusic, handlePlay, handlePlayLater, handleRemove, handleShare, handleUpdateMusicInfo, handleUpdateMusicPosition } from './listAction' import { handleDislikeMusic, handlePlay, handlePlayLater, handleRemove, handleShare, handleShowMusicSourceDetail, handleUpdateMusicInfo, handleUpdateMusicPosition } from './listAction'
import List, { type ListType } from './List' import List, { type ListType } from './List'
import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal' import ListMusicAdd, { type MusicAddModalType as ListMusicAddType } from '@/components/MusicAddModal'
import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal' import ListMusicMultiAdd, { type MusicMultiAddModalType as ListAddMultiType } from '@/components/MusicMultiAddModal'
@ -156,6 +156,7 @@ export default () => {
onRemove={info => { hancelExitSelect(); handleRemove(info.listId, info.musicInfo, info.selectedList, hancelExitSelect) }} onRemove={info => { hancelExitSelect(); handleRemove(info.listId, info.musicInfo, info.selectedList, hancelExitSelect) }}
onDislikeMusic={info => { void handleDislikeMusic(info.musicInfo) }} onDislikeMusic={info => { void handleDislikeMusic(info.musicInfo) }}
onCopyName={info => { handleShare(info.musicInfo) }} onCopyName={info => { handleShare(info.musicInfo) }}
onMusicSourceDetail={info => { void handleShowMusicSourceDetail(info.musicInfo) }}
onAdd={handleAddMusic} onAdd={handleAddMusic}
onMove={handleMoveMusic} onMove={handleMoveMusic}
onEditMetadata={handleEditMetadata} onEditMetadata={handleEditMetadata}

View File

@ -2,13 +2,14 @@ import { removeListMusics, updateListMusicPosition, updateListMusics } from '@/c
import { playList, playNext } from '@/core/player/player' import { playList, playNext } from '@/core/player/player'
import { addTempPlayList } from '@/core/player/tempPlayList' import { addTempPlayList } from '@/core/player/tempPlayList'
import settingState from '@/store/setting/state' import settingState from '@/store/setting/state'
import { similar, sortInsert } from '@/utils' import { similar, sortInsert, toOldMusicInfo } from '@/utils'
import { confirmDialog, shareMusic, toast } from '@/utils/tools' import { confirmDialog, openUrl, shareMusic, toast } from '@/utils/tools'
import { addDislikeInfo, hasDislike } from '@/core/dislikeList' import { addDislikeInfo, hasDislike } from '@/core/dislikeList'
import playerState from '@/store/player/state' import playerState from '@/store/player/state'
import type { SelectInfo } from './ListMenu' import type { SelectInfo } from './ListMenu'
import { type Metadata } from '@/components/MetadataEditModal' import { type Metadata } from '@/components/MetadataEditModal'
import musicSdk from '@/utils/musicSdk'
export const handlePlay = (listId: SelectInfo['listId'], index: SelectInfo['index']) => { export const handlePlay = (listId: SelectInfo['listId'], index: SelectInfo['index']) => {
void playList(listId, index) void playList(listId, index)
@ -89,6 +90,13 @@ export const searchListMusic = (list: LX.Music.MusicInfo[], text: string) => {
return sortedList.map(item => item.data).reverse() return sortedList.map(item => item.data).reverse()
} }
export const handleShowMusicSourceDetail = async(minfo: SelectInfo['musicInfo']) => {
const url = musicSdk[minfo.source as LX.OnlineSource]?.getMusicDetailPageUrl(toOldMusicInfo(minfo))
if (!url) return
void openUrl(url)
}
export const handleDislikeMusic = async(musicInfo: SelectInfo['musicInfo']) => { export const handleDislikeMusic = async(musicInfo: SelectInfo['musicInfo']) => {
const confirm = await confirmDialog({ const confirm = await confirmDialog({
message: global.i18n.t('lists_dislike_music_tip', { name: musicInfo.name }), message: global.i18n.t('lists_dislike_music_tip', { name: musicInfo.name }),