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 83 fontSize="subTitle" 84 fontColor="textSecondary"> 85 粉丝数: {artistItem.fans} 86 </ThemeText> 87 ) : null} 88 </View> 89 </View> 90 91 <ThemeText 92 style={styles.description} 93 numberOfLines={2} 94 ellipsizeMode="tail" 95 fontColor="textSecondary" 96 fontSize="description"> 97 {artistItem?.description ?? ''} 98 </ThemeText> 99 </Animated.View> 100 ); 101} 102 103const styles = StyleSheet.create({ 104 wrapper: { 105 width: rpx(750), 106 height: headerHeight, 107 backgroundColor: 'rgba(28, 28, 28, 0.1)', 108 zIndex: 1, 109 }, 110 artist: { 111 width: rpx(144), 112 height: rpx(144), 113 borderRadius: rpx(16), 114 }, 115 headerWrapper: { 116 width: rpx(750), 117 paddingTop: rpx(24), 118 paddingHorizontal: rpx(24), 119 height: rpx(240), 120 flexDirection: 'row', 121 alignItems: 'center', 122 }, 123 info: { 124 marginLeft: rpx(24), 125 justifyContent: 'space-around', 126 height: rpx(144), 127 }, 128 title: { 129 flexDirection: 'row', 130 alignItems: 'center', 131 }, 132 titleText: { 133 marginRight: rpx(18), 134 maxWidth: rpx(400), 135 }, 136 description: { 137 marginTop: rpx(24), 138 width: rpx(750), 139 paddingHorizontal: rpx(24), 140 }, 141}); 142