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