diff --git a/src/components/OnlineList/index.tsx b/src/components/OnlineList/index.tsx index d15bc34..23504f0 100644 --- a/src/components/OnlineList/index.tsx +++ b/src/components/OnlineList/index.tsx @@ -9,6 +9,7 @@ import MusicDownloadModal, { type MusicDownloadModalType } from '@/screens/Home/ import MultipleModeBar, { type MultipleModeBarType, type SelectMode } from './MultipleModeBar' import { handleDislikeMusic, handlePlay, handlePlayLater, handleShare } from './listAction' import { createStyle } from '@/utils/tools' +import { handelDownload } from '@/screens/Home/Views/Mylist/MusicList/listAction' export interface OnlineListProps { onRefresh: ListProps['onRefresh'] @@ -105,13 +106,15 @@ export default forwardRef(({ { hancelExitSelect() }} /> { hancelExitSelect() }} /> + { handelDownload(info.musicInfo, "128k") }} /> { handlePlay(info.musicInfo) }} onPlayLater={info => { hancelExitSelect(); handlePlayLater(info.musicInfo, info.selectedList, hancelExitSelect) }} onCopyName={info => { handleShare(info.musicInfo) }} onAdd={handleAddMusic} - onDownload={info => { handleShare(info.musicInfo) }} + onDownload={info => musicDownloadModalRef.current?.show(info)} onDislikeMusic={info => { void handleDislikeMusic(info.musicInfo) }} /> {/* */} diff --git a/src/core/music/online.ts b/src/core/music/online.ts index 26394aa..319f2c2 100644 --- a/src/core/music/online.ts +++ b/src/core/music/online.ts @@ -39,7 +39,7 @@ export const setPic = (datas: { */ -export const getMusicUrl = async({ musicInfo, quality, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: { +export const getMusicUrl = async ({ musicInfo, quality, isRefresh, allowToggleSource = true, onToggleSource = () => { } }: { musicInfo: LX.Music.MusicInfoOnline quality?: LX.Quality isRefresh: boolean @@ -63,7 +63,7 @@ export const getMusicUrl = async({ musicInfo, quality, isRefresh, allowToggleSou }) } -export const getPicUrl = async({ musicInfo, listId, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: { +export const getPicUrl = async ({ musicInfo, listId, isRefresh, allowToggleSource = true, onToggleSource = () => { } }: { musicInfo: LX.Music.MusicInfoOnline listId?: string | null isRefresh: boolean @@ -81,7 +81,7 @@ export const getPicUrl = async({ musicInfo, listId, isRefresh, allowToggleSource return url }) } -export const getLyricInfo = async({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: { +export const getLyricInfo = async ({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource = () => { } }: { musicInfo: LX.Music.MusicInfoOnline isRefresh: boolean allowToggleSource?: boolean @@ -93,7 +93,7 @@ export const getLyricInfo = async({ musicInfo, isRefresh, allowToggleSource = tr } // lrcRequest = music[musicInfo.source].getLyric(musicInfo) - return handleGetOnlineLyricInfo({ musicInfo, onToggleSource, isRefresh, allowToggleSource }).then(async({ lyricInfo, musicInfo: targetMusicInfo, isFromCache }) => { + return handleGetOnlineLyricInfo({ musicInfo, onToggleSource, isRefresh, allowToggleSource }).then(async ({ lyricInfo, musicInfo: targetMusicInfo, isFromCache }) => { // lrcRequest = null if (isFromCache) return buildLyricInfo(lyricInfo) if (targetMusicInfo.id == musicInfo.id) void saveLyric(musicInfo, lyricInfo) diff --git a/src/core/music/utils.ts b/src/core/music/utils.ts index e1c1c23..810dba7 100644 --- a/src/core/music/utils.ts +++ b/src/core/music/utils.ts @@ -16,7 +16,7 @@ import { apis } from '@/utils/musicSdk/api-source' const getOtherSourcePromises = new Map() export const existTimeExp = /\[\d{1,2}:.*\d{1,4}\]/ -export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false): Promise => { +export const getOtherSource = async (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false): Promise => { if (!isRefresh) { const cachedInfo = await getOtherSourceFromStore(musicInfo.id) if (cachedInfo.length) return cachedInfo @@ -71,7 +71,7 @@ export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download. } -export const buildLyricInfo = async(lyricInfo: MakeOptional): Promise => { +export const buildLyricInfo = async (lyricInfo: MakeOptional): Promise => { if (!settingState.setting['player.isS2t']) { // @ts-expect-error if (lyricInfo.rawlrcInfo) return lyricInfo @@ -117,7 +117,7 @@ export const buildLyricInfo = async(lyricInfo: MakeOptional => { +export const getCachedLyricInfo = async (musicInfo: LX.Music.MusicInfo): Promise => { let lrcInfo = await getStoreLyric(musicInfo) // lrcInfo = {} if (existTimeExp.test(lrcInfo.lyric) && lrcInfo.tlyric != null) { @@ -146,7 +146,7 @@ export const getCachedLyricInfo = async(musicInfo: LX.Music.MusicInfo): Promise< return null } -export const getOnlineOtherSourceMusicUrlByLocal = async(musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{ +export const getOnlineOtherSourceMusicUrlByLocal = async (musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{ url: string quality: LX.Quality isFromCache: boolean @@ -170,7 +170,7 @@ export const getOnlineOtherSourceMusicUrlByLocal = async(musicInfo: LX.Music.Mus }) } -export const getOnlineOtherSourceLyricByLocal = async(musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{ +export const getOnlineOtherSourceLyricByLocal = async (musicInfo: LX.Music.MusicInfoLocal, isRefresh: boolean): Promise<{ lyricInfo: LX.Music.LyricInfo isFromCache: boolean }> => { @@ -191,7 +191,7 @@ export const getOnlineOtherSourceLyricByLocal = async(musicInfo: LX.Music.MusicI }) } -export const getOnlineOtherSourcePicByLocal = async(musicInfo: LX.Music.MusicInfoLocal): Promise<{ +export const getOnlineOtherSourcePicByLocal = async (musicInfo: LX.Music.MusicInfoLocal): Promise<{ url: string }> => { if (!await global.lx.apiInitPromise[0]) throw new Error('source init failed') @@ -211,11 +211,11 @@ export const getOnlineOtherSourcePicByLocal = async(musicInfo: LX.Music.MusicInf export const getPlayQuality = (highQuality: boolean, musicInfo: LX.Music.MusicInfoOnline): LX.Quality => { let type: LX.Quality = '128k' let list = global.lx.qualityList[musicInfo.source] - if (highQuality && musicInfo.meta._qualitys['320k'] && list && list.includes('320k')) type = '320k' + if (highQuality && musicInfo.meta._qualitys['flac24bit'] && list && list.includes('flac24bit')) type = 'flac24bit' return type } -export const getOnlineOtherSourceMusicUrl = async({ musicInfos, quality, onToggleSource, isRefresh, retryedSource = [] }: { +export const getOnlineOtherSourceMusicUrl = async ({ musicInfos, quality, onToggleSource, isRefresh, retryedSource = [] }: { musicInfos: LX.Music.MusicInfoOnline[] quality?: LX.Quality onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void @@ -269,7 +269,7 @@ export const getOnlineOtherSourceMusicUrl = async({ musicInfos, quality, onToggl /** * 获取在线音乐URL */ -export const handleGetOnlineMusicUrl = async({ musicInfo, quality, onToggleSource, isRefresh, allowToggleSource }: { +export const handleGetOnlineMusicUrl = async ({ musicInfo, quality, onToggleSource, isRefresh, allowToggleSource }: { musicInfo: LX.Music.MusicInfoOnline quality?: LX.Quality isRefresh: boolean @@ -293,7 +293,7 @@ export const handleGetOnlineMusicUrl = async({ musicInfo, quality, onToggleSourc } return reqPromise.then(({ url, type }: { url: string, type: LX.Quality }) => { return { musicInfo, url, quality: type, isFromCache: false } - }).catch(async(err: any) => { + }).catch(async (err: any) => { console.log(err) if (!allowToggleSource || err.message == requestMsg.tooManyRequests) throw err onToggleSource() @@ -315,7 +315,7 @@ export const handleGetOnlineMusicUrl = async({ musicInfo, quality, onToggleSourc } -export const getOnlineOtherSourcePicUrl = async({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: { +export const getOnlineOtherSourcePicUrl = async ({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: { musicInfos: LX.Music.MusicInfoOnline[] onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void isRefresh: boolean @@ -358,7 +358,7 @@ export const getOnlineOtherSourcePicUrl = async({ musicInfos, onToggleSource, is /** * 获取在线歌曲封面 */ -export const handleGetOnlinePicUrl = async({ musicInfo, isRefresh, onToggleSource, allowToggleSource }: { +export const handleGetOnlinePicUrl = async ({ musicInfo, isRefresh, onToggleSource, allowToggleSource }: { musicInfo: LX.Music.MusicInfoOnline onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void isRefresh: boolean @@ -377,7 +377,7 @@ export const handleGetOnlinePicUrl = async({ musicInfo, isRefresh, onToggleSourc } return reqPromise.then((url: string) => { return { musicInfo, url, isFromCache: false } - }).catch(async(err: any) => { + }).catch(async (err: any) => { console.log(err) if (!allowToggleSource) throw err onToggleSource() @@ -398,7 +398,7 @@ export const handleGetOnlinePicUrl = async({ musicInfo, isRefresh, onToggleSourc } -export const getOnlineOtherSourceLyricInfo = async({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: { +export const getOnlineOtherSourceLyricInfo = async ({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: { musicInfos: LX.Music.MusicInfoOnline[] onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void isRefresh: boolean @@ -433,7 +433,7 @@ export const getOnlineOtherSourceLyricInfo = async({ musicInfos, onToggleSource, reqPromise = Promise.reject(err) } // retryedSource.includes(musicInfo.source) - return reqPromise.then(async(lyricInfo: LX.Music.LyricInfo) => { + return reqPromise.then(async (lyricInfo: LX.Music.LyricInfo) => { return existTimeExp.test(lyricInfo.lyric) ? { lyricInfo, musicInfo, @@ -449,7 +449,7 @@ export const getOnlineOtherSourceLyricInfo = async({ musicInfos, onToggleSource, /** * 获取在线歌词信息 */ -export const handleGetOnlineLyricInfo = async({ musicInfo, onToggleSource, isRefresh, allowToggleSource }: { +export const handleGetOnlineLyricInfo = async ({ musicInfo, onToggleSource, isRefresh, allowToggleSource }: { musicInfo: LX.Music.MusicInfoOnline onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void isRefresh: boolean @@ -467,13 +467,13 @@ export const handleGetOnlineLyricInfo = async({ musicInfo, onToggleSource, isRef } catch (err) { reqPromise = Promise.reject(err) } - return reqPromise.then(async(lyricInfo: LX.Music.LyricInfo) => { + return reqPromise.then(async (lyricInfo: LX.Music.LyricInfo) => { return existTimeExp.test(lyricInfo.lyric) ? { musicInfo, lyricInfo, isFromCache: false, } : Promise.reject(new Error('failed')) - }).catch(async(err: any) => { + }).catch(async (err: any) => { console.log(err) if (!allowToggleSource) throw err diff --git a/src/screens/Home/Views/Mylist/MusicList/MusicDownloadModal.tsx b/src/screens/Home/Views/Mylist/MusicList/MusicDownloadModal.tsx index febf193..0eada89 100644 --- a/src/screens/Home/Views/Mylist/MusicList/MusicDownloadModal.tsx +++ b/src/screens/Home/Views/Mylist/MusicList/MusicDownloadModal.tsx @@ -1,20 +1,19 @@ -import { useState, useRef, useImperativeHandle, forwardRef, useMemo } from 'react' +import { useState, useRef, useImperativeHandle, forwardRef, useMemo, useEffect } from 'react' import { View } from 'react-native' import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert' import Text from '@/components/common/Text' import { createStyle } from '@/utils/tools' import CheckBox from '@/components/common/CheckBox' -import { useSettingValue } from '@/store/setting/hook' -import { updateSetting } from '@/core/common' import { handelDownload } from './listAction' +import log from '@/plugins/sync/log' +import { getOtherSource } from '@/core/music/utils' interface TitleType { updateTitle: (musicInfo: SelectInfo['musicInfo']) => void } const Title = forwardRef((props, ref) => { const [title, setTitle] = useState('') - useImperativeHandle(ref, () => ({ updateTitle(musicInfo) { setTitle(global.i18n.t('download_music_title', { name: musicInfo.name })) @@ -46,7 +45,7 @@ interface MusicDownloadModalProps { } export interface MusicDownloadModalType { - show: (listInfo: SelectInfo) => void + show: (listInfo: any) => void } @@ -55,9 +54,108 @@ export default forwardRef(({ on const titleRef = useRef(null) const inputRef = useRef(null) const selectedInfo = useRef(initSelectInfo as SelectInfo) - const [selectedQuality, setSselectedQuality] = useState("128k"); + const [selectedQuality, setSelectedQuality] = useState("128k"); + const [playQualityList, setPlayQualityList] = useState([]); const [visible, setVisible] = useState(false) + interface QualityMap { + [key: string]: MusicOption; + } + + // const playQualityList = useMemo(() => { + // return [ + // { + // id: "128k", + // name: "标准音质(3.78MB)", + // }, { + // id: "320k", + // name: "高品音质(9.46MB)", + // }, + // { + // id: "flac", + // name: "无损音质(30.54MB)", + // }, { + // id: "flac24bit", + // name: "Hi-Res音质(49MB)", + // } + // ] as MusicOption[] + // //return ['128k', '320k', 'flac', 'flac24bit'] as LX.Quality[] + // }, []) + + // const keyMap = ; + + + const keyValueArray = [ + { key: '128k', value: '标准音质' }, + { key: '320k', value: '高品音质' }, + { key: 'flac', value: '无损音质' }, + { key: 'flac', value: 'Hi-Res音质' }, + { key: 'flac24bit', value: 'value3' }, + // 其他键值对... + ]; + + const calcQualitys = () => { + const map = new Map(); + map.set("128k", "标准音质"); + map.set("320k", "高品音质"); + map.set("flac", "无损音质"); + map.set("flac24bit", "Hi-Res音质"); + + const qualitys = selectedInfo.current?.musicInfo.meta.qualitys; + let qualityMap: QualityMap = {}; + for (let index = 0; index < qualitys.length; index++) { + const element = qualitys[index]; + const temp: MusicOption = { + id: element.type, + name: map.has(element.type) ? map.get(element.type) : "未知", + size: element.size, + key: element.type, + } + qualityMap[element.type] = temp; + } + console.log(Object.values(qualityMap)); + console.log(222); + + if (Object.values(qualityMap).length == map.size) { + console.log(333); + setPlayQualityList(Object.values(qualityMap)); + return; + } + getOtherSource(selectedInfo.current?.musicInfo, true).then(res => { + console.log(res); + if (res.length == 0) { + setPlayQualityList(Object.values(qualityMap)); + return; + } + + for (let index = 0; index < res.length; index++) { + const element = res[index]; + let qualitys = element.meta.qualitys + for (let index = 0; index < qualitys.length; index++) { + const element = qualitys[index]; + if (element.type in qualityMap) { + continue; + } + const tem: MusicOption = { + id: element.type, + name: map.has(element.type) ? map.get(element.type) : "未知", + size: element.size, + key: element.type, + } + qualityMap[element.type] = tem; + if (Object.values(qualityMap).length == map.size) { + setPlayQualityList(Object.values(qualityMap)); + return; + } + } + } + + }).catch(err => { + + }) + // setPlayQualityList(Object.values(qualityMap)); + } + const handleShow = () => { alertRef.current?.setVisible(true) requestAnimationFrame(() => { @@ -70,8 +168,7 @@ export default forwardRef(({ on useImperativeHandle(ref, () => ({ show(listInfo) { selectedInfo.current = listInfo - console.log(selectedInfo); - + calcQualitys(); if (visible) handleShow() else { setVisible(true) @@ -83,15 +180,17 @@ export default forwardRef(({ on })) const handleDownloadMusic = () => { + setSelectedQuality("128k"); alertRef.current?.setVisible(false) - // onDownloadInfo(selectedInfo.current, selectedQuality) handelDownload(selectedInfo.current?.musicInfo, selectedQuality); } - const playQualityList = useMemo(() => { - return ['128k', '320k', 'flac', 'flac24bit'] as LX.Quality[] - }, []) - + interface MusicOption { + id: LX.Quality; + name: string; + size?: string | null; + key?: string + } const useActive = (id: LX.Quality) => { const isActive = useMemo(() => selectedQuality == id, [selectedQuality, id]) @@ -103,7 +202,7 @@ export default forwardRef(({ on name: string }) => { const isActive = useActive(id) - return { setSselectedQuality(id) }} need /> + return { setSelectedQuality(id) }} need /> } return ( @@ -117,7 +216,7 @@ export default forwardRef(({ on <View style={styles.list}> { - playQualityList.map((q) => <Item name={q} id={q} key={q} />) + playQualityList.map((item) => <Item name={item.name + "" + "(" + item.size + ")"} id={item.id} key={item.key} />) } </View> </View> @@ -139,7 +238,7 @@ const styles = createStyle({ borderRadius: 4, }, list: { - flexDirection: 'row', - flexWrap: 'wrap', + flexDirection: 'column', + flexWrap: 'nowrap', }, }) \ No newline at end of file diff --git a/src/screens/Home/Views/Mylist/MusicList/index.tsx b/src/screens/Home/Views/Mylist/MusicList/index.tsx index 7b47b94..56812c3 100644 --- a/src/screens/Home/Views/Mylist/MusicList/index.tsx +++ b/src/screens/Home/Views/Mylist/MusicList/index.tsx @@ -152,7 +152,7 @@ export default () => { <MusicPositionModal ref={musicPositionModalRef} onUpdatePosition={(info, postion) => { handleUpdateMusicPosition(postion, info.listId, info.musicInfo, info.selectedList, hancelExitSelect) }} /> <MusicDownloadModal ref={musicDownloadModalRef} - onDownloadInfo={(info) => { handelDownload(info.musicInfo) }} /> + onDownloadInfo={(info) => { handelDownload(info.musicInfo, "128k") }} /> <ListMenu ref={listMenuRef} onPlay={info => { handlePlay(info.listId, info.index) }} diff --git a/src/screens/Home/Views/Mylist/MusicList/listAction.ts b/src/screens/Home/Views/Mylist/MusicList/listAction.ts index 26ecd27..f23e304 100644 --- a/src/screens/Home/Views/Mylist/MusicList/listAction.ts +++ b/src/screens/Home/Views/Mylist/MusicList/listAction.ts @@ -45,6 +45,7 @@ const diffCurrentMusicInfo = (curMusicInfo: LX.Music.MusicInfo | LX.Download.Lis // export const handelDownload = (musicInfo: LX.Music.MusicInfoOnline) => { export const handelDownload = (musicInfo: any, quality: LX.Quality) => { return requestStoragePermission().then(async () => { + console.log(quality); try { getMusicUrl({ musicInfo, quality, isRefresh: true, onToggleSource(mInfo) {