1import React, {useEffect} from 'react'; 2import {StyleSheet, View} from 'react-native'; 3import rpx from '@/utils/rpx'; 4import Animated, { 5 useAnimatedStyle, 6 useSharedValue, 7 withTiming, 8} from 'react-native-reanimated'; 9import {useAtomValue} from 'jotai'; 10import {scrollToTopAtom} from '../store/atoms'; 11import ThemeText from '@/components/base/themeText'; 12import Tag from '@/components/base/tag'; 13import {useParams} from '@/entry/router'; 14import Image from '@/components/base/image'; 15import {ImgAsset} from '@/constants/assetsConst'; 16 17const headerHeight = rpx(350); 18 19interface IHeaderProps { 20 neverFold?: boolean; 21} 22 23export default function Header(props: IHeaderProps) { 24 const {neverFold} = props; 25 26 const {artistItem} = useParams<'artist-detail'>(); 27 28 const heightValue = useSharedValue(headerHeight); 29 const opacityValue = useSharedValue(1); 30 const scrollToTopState = useAtomValue(scrollToTopAtom); 31 32 const heightStyle = useAnimatedStyle(() => { 33 return { 34 height: heightValue.value, 35 opacity: opacityValue.value, 36 }; 37 }); 38 39 const avatar = artistItem.avatar?.startsWith('//') 40 ? `https:${artistItem.avatar}` 41 : artistItem.avatar; 42 43 /** 折叠 */ 44 useEffect(() => { 45 if (neverFold) { 46 heightValue.value = withTiming(headerHeight); 47 opacityValue.value = withTiming(1); 48 return; 49 } 50 if (scrollToTopState) { 51 heightValue.value = withTiming(headerHeight); 52 opacityValue.value = withTiming(1); 53 } else { 54 heightValue.value = withTiming(0); 55 opacityValue.value = withTiming(0); 56 } 57 }, [scrollToTopState, neverFold]); 58 59 return ( 60 <Animated.View style={[styles.wrapper, heightStyle]}> 61 <View style={styles.headerWrapper}> 62 <Image 63 emptySrc={ImgAsset.albumDefault} 64 uri={avatar} 65 style={styles.artist} 66 /> 67 <View style={styles.info}> 68 <View style={styles.title}> 69 <ThemeText 70 fontSize="title" 71 style={styles.titleText} 72 numberOfLines={1} 73 ellipsizeMode="tail"> 74 {artistItem?.name ?? ''} 75 </ThemeText> 76 {artistItem.platform ? ( 77 <Tag tagName={artistItem.platform} /> 78 ) : null} 79 </View> 80 81 {artistItem.fans ? ( 82 <ThemeText fontSize="subTitle" fontColor="secondary"> 83 粉丝数: {artistItem.fans} 84 </ThemeText> 85 ) : null} 86 </View> 87 </View> 88 89 <ThemeText 90 style={styles.description} 91 numberOfLines={2} 92 ellipsizeMode="tail" 93 fontColor="secondary" 94 fontSize="description"> 95 {artistItem?.description ?? ''} 96 </ThemeText> 97 </Animated.View> 98 ); 99} 100 101const styles = StyleSheet.create({ 102 wrapper: { 103 width: rpx(750), 104 height: headerHeight, 105 backgroundColor: 'rgba(28, 28, 28, 0.1)', 106 zIndex: 1, 107 }, 108 artist: { 109 width: rpx(144), 110 height: rpx(144), 111 borderRadius: rpx(16), 112 }, 113 headerWrapper: { 114 width: rpx(750), 115 paddingTop: rpx(24), 116 paddingHorizontal: rpx(24), 117 height: rpx(240), 118 flexDirection: 'row', 119 alignItems: 'center', 120 }, 121 info: { 122 marginLeft: rpx(24), 123 justifyContent: 'space-around', 124 height: rpx(144), 125 }, 126 title: { 127 flexDirection: 'row', 128 alignItems: 'center', 129 }, 130 titleText: { 131 marginRight: rpx(18), 132 maxWidth: rpx(400), 133 }, 134 description: { 135 marginTop: rpx(24), 136 width: rpx(750), 137 paddingHorizontal: rpx(24), 138 }, 139}); 140