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