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