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 {Avatar} from 'react-native-paper'; 12import ThemeText from '@/components/base/themeText'; 13import Tag from '@/components/base/tag'; 14import {useRoute} from '@react-navigation/native'; 15 16const headerHeight = rpx(350); 17export default function Header() { 18 const route = useRoute<any>(); 19 const artistItem: IArtist.IArtistItem = route.params?.artistItem ?? null; 20 21 const heightValue = useSharedValue(headerHeight); 22 const opacityValue = useSharedValue(1); 23 const scrollToTopState = useAtomValue(scrollToTopAtom); 24 25 const heightStyle = useAnimatedStyle(() => { 26 return { 27 height: heightValue.value, 28 opacity: opacityValue.value, 29 }; 30 }); 31 32 const avatar = artistItem.avatar?.startsWith('//') 33 ? `https:${artistItem.avatar}` 34 : artistItem.avatar; 35 36 /** 折叠 */ 37 useEffect(() => { 38 if (scrollToTopState) { 39 heightValue.value = withTiming(headerHeight); 40 opacityValue.value = withTiming(1); 41 } else { 42 heightValue.value = withTiming(0); 43 opacityValue.value = withTiming(0); 44 } 45 }, [scrollToTopState]); 46 47 return ( 48 <Animated.View style={[style.wrapper, heightStyle]}> 49 <View style={style.headerWrapper}> 50 <Avatar.Image size={rpx(144)} source={{uri: avatar}} /> 51 <View style={style.info}> 52 <View style={style.title}> 53 <ThemeText 54 fontSize="title" 55 style={style.titleText} 56 numberOfLines={1} 57 ellipsizeMode="tail"> 58 {artistItem.name} 59 </ThemeText> 60 {artistItem.platform && ( 61 <Tag tagName={artistItem.platform} /> 62 )} 63 </View> 64 65 {artistItem.fans && ( 66 <ThemeText fontSize="subTitle" fontColor="secondary"> 67 粉丝数: {artistItem.fans} 68 </ThemeText> 69 )} 70 </View> 71 </View> 72 73 <ThemeText 74 style={style.description} 75 numberOfLines={2} 76 ellipsizeMode="tail" 77 fontColor="secondary" 78 fontSize="description"> 79 {artistItem.description} 80 </ThemeText> 81 </Animated.View> 82 ); 83} 84 85const style = StyleSheet.create({ 86 wrapper: { 87 width: rpx(750), 88 height: headerHeight, 89 backgroundColor: 'rgba(28, 28, 28, 0.1)', 90 zIndex: 1, 91 }, 92 headerWrapper: { 93 width: rpx(750), 94 paddingTop: rpx(24), 95 paddingHorizontal: rpx(24), 96 height: rpx(240), 97 flexDirection: 'row', 98 alignItems: 'center', 99 }, 100 info: { 101 marginLeft: rpx(24), 102 justifyContent: 'space-around', 103 height: rpx(144), 104 }, 105 title: { 106 flexDirection: 'row', 107 alignItems: 'center', 108 }, 109 titleText: { 110 marginRight: rpx(18), 111 maxWidth: rpx(400), 112 }, 113 description: { 114 marginTop: rpx(24), 115 width: rpx(750), 116 paddingHorizontal: rpx(24), 117 }, 118}); 119