1import React, {useState} from 'react'; 2import {Pressable, StyleSheet, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import LinearGradient from 'react-native-linear-gradient'; 5import {Divider, IconButton, useTheme} from 'react-native-paper'; 6import MusicQueue from '@/core/musicQueue'; 7import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; 8import usePanel from '@/components/panels/usePanel'; 9import {iconSizeConst} from '@/constants/uiConst'; 10import Color from 'color'; 11import ThemeText from '@/components/base/themeText'; 12import {ImgAsset} from '@/constants/assetsConst'; 13import FastImage from '@/components/base/fastImage'; 14import {ROUTE_PATH, useNavigate} from '@/entry/router'; 15 16interface IHeaderProps { 17 topListDetail: IMusic.IMusicTopListItem | null; 18 musicList: IMusic.IMusicItem[] | null; 19} 20export default function Header(props: IHeaderProps) { 21 const {topListDetail, musicList} = props; 22 const {showPanel} = usePanel(); 23 const {colors} = useTheme(); 24 25 const [maxLines, setMaxLines] = useState<number | undefined>(6); 26 27 const toggleShowMore = () => { 28 if (maxLines) { 29 setMaxLines(undefined); 30 } else { 31 setMaxLines(6); 32 } 33 }; 34 35 const navigate = useNavigate(); 36 37 return ( 38 <> 39 <LinearGradient 40 colors={[ 41 Color(colors.primary).alpha(0.8).toString(), 42 Color(colors.primary).alpha(0.15).toString(), 43 ]} 44 style={style.wrapper}> 45 <View style={style.content}> 46 <FastImage 47 style={style.coverImg} 48 uri={topListDetail?.artwork ?? topListDetail?.coverImg} 49 emptySrc={ImgAsset.albumDefault} 50 /> 51 <View style={style.details}> 52 <ThemeText>{topListDetail?.title}</ThemeText> 53 <ThemeText fontColor="secondary" fontSize="description"> 54 共 55 {topListDetail?.worksNum ?? 56 (musicList ? musicList.length ?? 0 : '-')} 57 首{' '} 58 </ThemeText> 59 </View> 60 </View> 61 <Divider style={style.divider} /> 62 {topListDetail?.description ? ( 63 <Pressable onPress={toggleShowMore}> 64 <View 65 style={style.albumDesc} 66 onLayout={evt => { 67 console.log(evt.nativeEvent.layout); 68 }}> 69 <ThemeText 70 fontColor="secondary" 71 fontSize="description" 72 numberOfLines={maxLines}> 73 {topListDetail.description} 74 </ThemeText> 75 </View> 76 </Pressable> 77 ) : null} 78 </LinearGradient> 79 <View 80 style={[ 81 style.topWrapper, 82 { 83 backgroundColor: Color(colors.primary) 84 .alpha(0.15) 85 .toString(), 86 }, 87 ]}> 88 <Pressable 89 style={style.playAll} 90 onPress={() => { 91 if (musicList) { 92 MusicQueue.playWithReplaceQueue( 93 musicList[0], 94 musicList, 95 ); 96 } 97 }}> 98 <Icon 99 name="play-circle-outline" 100 style={style.playAllIcon} 101 size={iconSizeConst.normal} 102 color={colors.text} 103 /> 104 <ThemeText fontWeight="bold">播放全部</ThemeText> 105 </Pressable> 106 <IconButton 107 icon={'plus-box-multiple-outline'} 108 size={rpx(48)} 109 onPress={async () => { 110 showPanel('AddToMusicSheet', { 111 musicItem: musicList ?? [], 112 }); 113 }} 114 /> 115 <IconButton 116 icon="playlist-edit" 117 size={rpx(48)} 118 onPress={async () => { 119 navigate(ROUTE_PATH.MUSIC_LIST_EDITOR, { 120 musicList: musicList, 121 musicSheet: { 122 title: topListDetail?.title, 123 }, 124 }); 125 }} 126 /> 127 </View> 128 </> 129 ); 130} 131 132const style = StyleSheet.create({ 133 wrapper: { 134 width: '100%', 135 padding: rpx(24), 136 justifyContent: 'center', 137 alignItems: 'center', 138 }, 139 content: { 140 flex: 1, 141 flexDirection: 'row', 142 justifyContent: 'flex-start', 143 alignItems: 'center', 144 }, 145 coverImg: { 146 width: rpx(210), 147 height: rpx(210), 148 borderRadius: rpx(24), 149 }, 150 details: { 151 flex: 1, 152 height: rpx(140), 153 paddingHorizontal: rpx(36), 154 justifyContent: 'space-between', 155 }, 156 divider: { 157 marginVertical: rpx(18), 158 }, 159 160 albumDesc: { 161 width: rpx(702), 162 }, 163 /** playall */ 164 topWrapper: { 165 height: rpx(72), 166 paddingHorizontal: rpx(24), 167 flexDirection: 'row', 168 alignItems: 'center', 169 }, 170 playAll: { 171 flex: 1, 172 flexDirection: 'row', 173 alignItems: 'center', 174 }, 175 playAllIcon: { 176 marginRight: rpx(12), 177 }, 178}); 179