xref: /MusicFree/src/pages/artistDetail/components/header.tsx (revision 6704747af84cebd842b258efac7143542722fac5)
1import React, {useEffect, useRef} from 'react';
2import {StyleSheet, Text, 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 Image from '@/components/base/image';
13import {fontSizeConst} from '@/constants/uiConst';
14import ThemeText from '@/components/base/themeText';
15import Tag from '@/components/base/tag';
16import { useRoute } from '@react-navigation/native';
17
18interface IHeaderProps {
19}
20
21const headerHeight = rpx(350);
22export default function Header(props: IHeaderProps) {
23  const route = useRoute<any>();
24  const artistItem: IArtist.IArtistItem = route.params?.artistItem ?? null;
25
26  const heightValue = useSharedValue(headerHeight);
27  const opacityValue = useSharedValue(1);
28  const scrollToTopState = useAtomValue(scrollToTopAtom);
29
30  const heightStyle = useAnimatedStyle(() => {
31    return {
32      height: heightValue.value,
33      opacity: opacityValue.value,
34    };
35  });
36
37  const avatar = artistItem.avatar?.startsWith('//')
38    ? `https:${artistItem.avatar}`
39    : artistItem.avatar;
40
41  /** 折叠 */
42  useEffect(() => {
43    if (scrollToTopState) {
44      heightValue.value = withTiming(headerHeight);
45      opacityValue.value = withTiming(1);
46    } else {
47      heightValue.value = withTiming(0);
48      opacityValue.value = withTiming(0);
49    }
50  }, [scrollToTopState]);
51
52  return (
53    <Animated.View style={[style.wrapper, heightStyle]}>
54      <View style={style.headerWrapper}>
55        <Avatar.Image size={rpx(144)} source={{uri: avatar}}></Avatar.Image>
56        <View style={style.info}>
57          <View style={style.title}>
58            <ThemeText
59              fontSize="title"
60              style={style.titleText}
61              numberOfLines={1}
62              ellipsizeMode="tail">
63              {artistItem.name}
64            </ThemeText>
65            {artistItem.platform && <Tag tagName={artistItem.platform}></Tag>}
66          </View>
67
68          {artistItem.fans && (
69            <ThemeText fontSize="subTitle" fontColor="secondary">
70              粉丝数: {artistItem.fans}
71            </ThemeText>
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