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 ) : null} 62 </View> 63 64 {artistItem.fans ? ( 65 <ThemeText fontSize="subTitle" fontColor="secondary"> 66 粉丝数: {artistItem.fans} 67 </ThemeText> 68 ) : null} 69 </View> 70 </View> 71 72 <ThemeText 73 style={style.description} 74 numberOfLines={2} 75 ellipsizeMode="tail" 76 fontColor="secondary" 77 fontSize="description"> 78 {artistItem?.description ?? ''} 79 </ThemeText> 80 </Animated.View> 81 ); 82} 83 84const style = StyleSheet.create({ 85 wrapper: { 86 width: rpx(750), 87 height: headerHeight, 88 backgroundColor: 'rgba(28, 28, 28, 0.1)', 89 zIndex: 1, 90 }, 91 headerWrapper: { 92 width: rpx(750), 93 paddingTop: rpx(24), 94 paddingHorizontal: rpx(24), 95 height: rpx(240), 96 flexDirection: 'row', 97 alignItems: 'center', 98 }, 99 info: { 100 marginLeft: rpx(24), 101 justifyContent: 'space-around', 102 height: rpx(144), 103 }, 104 title: { 105 flexDirection: 'row', 106 alignItems: 'center', 107 }, 108 titleText: { 109 marginRight: rpx(18), 110 maxWidth: rpx(400), 111 }, 112 description: { 113 marginTop: rpx(24), 114 width: rpx(750), 115 paddingHorizontal: rpx(24), 116 }, 117}); 118