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 > 70 <ThemeText 71 fontColor="secondary" 72 fontSize="description" 73 numberOfLines={maxLines}> 74 {topListDetail.description} 75 </ThemeText> 76 </View> 77 </Pressable> 78 ) : null} 79 </LinearGradient> 80 <View 81 style={[ 82 style.topWrapper, 83 { 84 backgroundColor: Color(colors.primary) 85 .alpha(0.15) 86 .toString(), 87 }, 88 ]}> 89 <Pressable 90 style={style.playAll} 91 onPress={() => { 92 if (musicList) { 93 MusicQueue.playWithReplaceQueue( 94 musicList[0], 95 musicList, 96 ); 97 } 98 }}> 99 <Icon 100 name="play-circle-outline" 101 style={style.playAllIcon} 102 size={iconSizeConst.normal} 103 color={colors.text} 104 /> 105 <ThemeText fontWeight="bold">播放全部</ThemeText> 106 </Pressable> 107 <IconButton 108 icon={'plus-box-multiple-outline'} 109 size={rpx(48)} 110 onPress={async () => { 111 showPanel('AddToMusicSheet', { 112 musicItem: musicList ?? [], 113 newSheetDefaultName: topListDetail?.title, 114 }); 115 }} 116 /> 117 <IconButton 118 icon="playlist-edit" 119 size={rpx(48)} 120 onPress={async () => { 121 navigate(ROUTE_PATH.MUSIC_LIST_EDITOR, { 122 musicList: musicList, 123 musicSheet: { 124 title: topListDetail?.title, 125 }, 126 }); 127 }} 128 /> 129 </View> 130 </> 131 ); 132} 133 134const style = StyleSheet.create({ 135 wrapper: { 136 width: '100%', 137 padding: rpx(24), 138 justifyContent: 'center', 139 alignItems: 'flex-start', 140 }, 141 content: { 142 flex: 1, 143 flexDirection: 'row', 144 justifyContent: 'flex-start', 145 alignItems: 'center', 146 }, 147 coverImg: { 148 width: rpx(210), 149 height: rpx(210), 150 borderRadius: rpx(24), 151 }, 152 details: { 153 flex: 1, 154 height: rpx(140), 155 paddingHorizontal: rpx(36), 156 justifyContent: 'space-between', 157 }, 158 divider: { 159 marginVertical: rpx(18), 160 }, 161 162 albumDesc: { 163 width: '100%', 164 paddingHorizontal: rpx(24), 165 }, 166 /** playall */ 167 topWrapper: { 168 height: rpx(72), 169 paddingHorizontal: rpx(24), 170 flexDirection: 'row', 171 alignItems: 'center', 172 }, 173 playAll: { 174 flex: 1, 175 flexDirection: 'row', 176 alignItems: 'center', 177 }, 178 playAllIcon: { 179 marginRight: rpx(12), 180 }, 181}); 182