1import React from 'react'; 2import {Image, Pressable, StyleSheet, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; 5import MusicSheet from '@/core/musicSheet'; 6 7import Download from '@/core/download'; 8import {isSameMediaItem} from '@/utils/mediaItem'; 9import LocalMusicSheet from '@/core/localMusicSheet'; 10import {ROUTE_PATH} from '@/entry/router'; 11import {ImgAsset} from '@/constants/assetsConst'; 12import Toast from '@/utils/toast'; 13import useOrientation from '@/hooks/useOrientation'; 14import {showPanel} from '@/components/panels/usePanel'; 15import TrackPlayer from '@/core/trackPlayer'; 16import {iconSizeConst} from '@/constants/uiConst'; 17import PersistStatus from '@/core/persistStatus'; 18 19export default function Operations() { 20 //briefcase-download-outline briefcase-check-outline checkbox-marked-circle-outline 21 const favoriteMusicSheet = MusicSheet.useSheets('favorite'); 22 const musicItem = TrackPlayer.useCurrentMusic(); 23 const currentQuality = TrackPlayer.useCurrentQuality(); 24 const isDownloaded = LocalMusicSheet.useIsLocal(musicItem); 25 26 const rate = PersistStatus.useValue('music.rate', 100); 27 const orientation = useOrientation(); 28 29 const musicIndexInFav = 30 favoriteMusicSheet?.musicList.findIndex(_ => 31 isSameMediaItem(_, musicItem), 32 ) ?? -1; 33 34 return ( 35 <View 36 style={[ 37 style.wrapper, 38 orientation === 'horizonal' 39 ? { 40 marginBottom: 0, 41 } 42 : null, 43 ]}> 44 {musicIndexInFav !== -1 ? ( 45 <Icon 46 name="heart" 47 size={iconSizeConst.normal} 48 color="red" 49 onPress={() => { 50 MusicSheet.removeMusicByIndex( 51 'favorite', 52 musicIndexInFav, 53 ); 54 }} 55 /> 56 ) : ( 57 <Icon 58 name="heart-outline" 59 size={iconSizeConst.normal} 60 color="white" 61 onPress={() => { 62 if (musicItem) { 63 MusicSheet.addMusic('favorite', musicItem); 64 } 65 }} 66 /> 67 )} 68 <Pressable 69 onPress={() => { 70 if (!musicItem) { 71 return; 72 } 73 showPanel('MusicQuality', { 74 musicItem, 75 async onQualityPress(quality) { 76 const changeResult = 77 await TrackPlayer.changeQuality(quality); 78 if (!changeResult) { 79 Toast.warn('当前暂无此音质音乐'); 80 } 81 }, 82 }); 83 }}> 84 <Image 85 source={ImgAsset.quality[currentQuality]} 86 style={style.quality} 87 /> 88 </Pressable> 89 <Icon 90 name={isDownloaded ? 'check-circle-outline' : 'download'} 91 size={iconSizeConst.normal} 92 color="white" 93 onPress={() => { 94 if (musicItem && !isDownloaded) { 95 showPanel('MusicQuality', { 96 musicItem, 97 async onQualityPress(quality) { 98 Download.downloadMusic(musicItem, quality); 99 }, 100 }); 101 } 102 }} 103 /> 104 <Pressable 105 onPress={() => { 106 if (!musicItem) { 107 return; 108 } 109 showPanel('PlayRate', { 110 async onRatePress(newRate) { 111 if (rate !== newRate) { 112 try { 113 await TrackPlayer.setRate(newRate / 100); 114 PersistStatus.set('music.rate', newRate); 115 } catch {} 116 } 117 }, 118 }); 119 }}> 120 <Image source={ImgAsset.rate[rate!]} style={style.quality} /> 121 </Pressable> 122 <Icon 123 name="dots-vertical" 124 size={iconSizeConst.normal} 125 color="white" 126 onPress={() => { 127 if (musicItem) { 128 showPanel('MusicItemOptions', { 129 musicItem: musicItem, 130 from: ROUTE_PATH.MUSIC_DETAIL, 131 }); 132 } 133 }} 134 /> 135 </View> 136 ); 137} 138 139const style = StyleSheet.create({ 140 wrapper: { 141 width: '100%', 142 height: rpx(80), 143 marginBottom: rpx(24), 144 flexDirection: 'row', 145 alignItems: 'center', 146 justifyContent: 'space-around', 147 }, 148 quality: { 149 width: rpx(52), 150 height: rpx(52), 151 }, 152}); 153