1import React, {Fragment, useEffect, useState} from 'react'; 2import {Keyboard, Pressable, StyleSheet, Text, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; 5import MusicQueue from '@/core/musicQueue'; 6import {Avatar, IconButton, useTheme} from 'react-native-paper'; 7import {CircularProgressBase} from 'react-native-circular-progress-indicator'; 8import {useNavigation} from '@react-navigation/native'; 9import {ROUTE_PATH} from '@/entry/router'; 10 11import musicIsPaused from '@/utils/musicIsPaused'; 12import usePanel from '../panels/usePanel'; 13import Color from 'color'; 14import ThemeText from '../base/themeText'; 15import {ImgAsset} from '@/constants/assetsConst'; 16 17export default function () { 18 // const currentMusicState = useAtomValue(loadableCurrentMusicStateAtom); 19 const musicItem = MusicQueue.useCurrentMusicItem(); 20 const musicState = MusicQueue.usePlaybackState(); 21 const [showKeyboard, setKeyboardStatus] = useState(false); 22 const {showPanel} = usePanel(); 23 const navigation = useNavigation<any>(); 24 const progress = MusicQueue.useProgress(); 25 const {colors} = useTheme(); 26 27 useEffect(() => { 28 const showSubscription = Keyboard.addListener('keyboardDidShow', () => { 29 setKeyboardStatus(true); 30 }); 31 const hideSubscription = Keyboard.addListener('keyboardDidHide', () => { 32 setKeyboardStatus(false); 33 }); 34 35 return () => { 36 showSubscription.remove(); 37 hideSubscription.remove(); 38 }; 39 }, []); 40 41 return ( 42 <Fragment> 43 {musicItem && !showKeyboard && ( 44 <Pressable 45 style={[ 46 style.wrapper, 47 { 48 backgroundColor: Color(colors.primary) 49 .alpha(0.66) 50 .toString(), 51 }, 52 ]} 53 onPress={() => { 54 navigation.navigate(ROUTE_PATH.MUSIC_DETAIL); 55 }}> 56 <View style={style.artworkWrapper}> 57 <Avatar.Image 58 size={rpx(96)} 59 source={ 60 musicItem.artwork 61 ? { 62 uri: musicItem.artwork, 63 } 64 : ImgAsset.albumDefault 65 } 66 /> 67 </View> 68 <Text 69 ellipsizeMode="tail" 70 style={style.textWrapper} 71 numberOfLines={1}> 72 <ThemeText fontSize="content"> 73 {musicItem.title} 74 </ThemeText> 75 {musicItem?.artist && ( 76 <ThemeText 77 fontSize="description" 78 fontColor="secondary"> 79 {' '} 80 -{musicItem.artist} 81 </ThemeText> 82 )} 83 </Text> 84 <View style={style.actionGroup}> 85 <CircularProgressBase 86 activeStrokeWidth={rpx(4)} 87 inActiveStrokeWidth={rpx(2)} 88 inActiveStrokeOpacity={0.2} 89 value={ 90 progress?.duration 91 ? (100 * progress.position) / 92 progress.duration 93 : 0 94 } 95 duration={100} 96 radius={rpx(36)} 97 activeStrokeColor={colors.text} 98 inActiveStrokeColor={Color(colors.text) 99 .alpha(0.5) 100 .toString()}> 101 {musicIsPaused(musicState) ? ( 102 <IconButton 103 icon="play" 104 size={rpx(48)} 105 onPress={async () => { 106 await MusicQueue.play(); 107 }} 108 /> 109 ) : ( 110 <IconButton 111 icon="pause" 112 size={rpx(48)} 113 onPress={async () => { 114 await MusicQueue.pause(); 115 }} 116 /> 117 )} 118 </CircularProgressBase> 119 120 <Icon 121 name="playlist-music" 122 size={rpx(56)} 123 onPress={() => { 124 showPanel('PlayList'); 125 }} 126 style={[style.actionIcon, {color: colors.text}]} 127 /> 128 </View> 129 </Pressable> 130 )} 131 </Fragment> 132 ); 133} 134 135const style = StyleSheet.create({ 136 wrapper: { 137 width: rpx(750), 138 height: rpx(120), 139 flexDirection: 'row', 140 alignItems: 'center', 141 paddingHorizontal: rpx(24), 142 }, 143 artworkWrapper: { 144 height: rpx(120), 145 width: rpx(120), 146 }, 147 textWrapper: { 148 flexGrow: 1, 149 maxWidth: rpx(382), 150 }, 151 actionGroup: { 152 width: rpx(200), 153 justifyContent: 'flex-end', 154 flexDirection: 'row', 155 alignItems: 'center', 156 }, 157 actionIcon: { 158 marginLeft: rpx(36), 159 }, 160}); 161