xref: /MusicFree/src/pages/artistDetail/components/header.tsx (revision b882a19d884fffa32f7c8cef31652b909dceaa0f)
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