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