xref: /MusicFree/src/components/musicSheetPage/components/header.tsx (revision 2aa881935ca35b8fb1abc4206e0dc35149231456)
1import React, {useState} from 'react';
2import {Pressable, StyleSheet, View} from 'react-native';
3import rpx from '@/utils/rpx';
4import LinearGradient from 'react-native-linear-gradient';
5import {Divider, IconButton, useTheme} from 'react-native-paper';
6import MusicQueue from '@/core/musicQueue';
7import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
8import usePanel from '@/components/panels/usePanel';
9import {iconSizeConst} from '@/constants/uiConst';
10import Color from 'color';
11import ThemeText from '@/components/base/themeText';
12import {ImgAsset} from '@/constants/assetsConst';
13import FastImage from '@/components/base/fastImage';
14import {ROUTE_PATH, useNavigate} from '@/entry/router';
15
16interface IHeaderProps {
17    topListDetail: IMusic.IMusicTopListItem | null;
18
19    musicList: IMusic.IMusicItem[] | null;
20}
21export default function Header(props: IHeaderProps) {
22    const {topListDetail, musicList} = props;
23    const {showPanel} = usePanel();
24    const {colors} = useTheme();
25
26    const [maxLines, setMaxLines] = useState<number | undefined>(6);
27
28    const toggleShowMore = () => {
29        if (maxLines) {
30            setMaxLines(undefined);
31        } else {
32            setMaxLines(6);
33        }
34    };
35
36    const navigate = useNavigate();
37
38    return (
39        <>
40            <LinearGradient
41                colors={[
42                    Color(colors.primary).alpha(0.8).toString(),
43                    Color(colors.primary).alpha(0.15).toString(),
44                ]}
45                style={style.wrapper}>
46                <View style={style.content}>
47                    <FastImage
48                        style={style.coverImg}
49                        uri={topListDetail?.artwork ?? topListDetail?.coverImg}
50                        emptySrc={ImgAsset.albumDefault}
51                    />
52                    <View style={style.details}>
53                        <ThemeText>{topListDetail?.title}</ThemeText>
54                        <ThemeText fontColor="secondary" fontSize="description">
55                            共{musicList ? musicList.length ?? 0 : '-'}首{' '}
56                        </ThemeText>
57                    </View>
58                </View>
59                <Divider style={style.divider} />
60                {topListDetail?.description ? (
61                    <Pressable onPress={toggleShowMore}>
62                        <View
63                            style={style.albumDesc}
64                            onLayout={evt => {
65                                console.log(evt.nativeEvent.layout);
66                            }}>
67                            <ThemeText
68                                fontColor="secondary"
69                                fontSize="description"
70                                numberOfLines={maxLines}>
71                                {topListDetail.description}
72                            </ThemeText>
73                        </View>
74                    </Pressable>
75                ) : null}
76            </LinearGradient>
77            <View
78                style={[
79                    style.topWrapper,
80                    {
81                        backgroundColor: Color(colors.primary)
82                            .alpha(0.15)
83                            .toString(),
84                    },
85                ]}>
86                <Pressable
87                    style={style.playAll}
88                    onPress={() => {
89                        if (musicList) {
90                            MusicQueue.playWithReplaceQueue(
91                                musicList[0],
92                                musicList,
93                            );
94                        }
95                    }}>
96                    <Icon
97                        name="play-circle-outline"
98                        style={style.playAllIcon}
99                        size={iconSizeConst.normal}
100                        color={colors.text}
101                    />
102                    <ThemeText fontWeight="bold">播放全部</ThemeText>
103                </Pressable>
104                <IconButton
105                    icon={'plus-box-multiple-outline'}
106                    size={rpx(48)}
107                    onPress={async () => {
108                        showPanel('AddToMusicSheet', {
109                            musicItem: musicList ?? [],
110                        });
111                    }}
112                />
113                <IconButton
114                    icon="playlist-edit"
115                    size={rpx(48)}
116                    onPress={async () => {
117                        navigate(ROUTE_PATH.MUSIC_LIST_EDITOR, {
118                            musicList: musicList,
119                            musicSheet: {
120                                title: topListDetail?.title,
121                            },
122                        });
123                    }}
124                />
125            </View>
126        </>
127    );
128}
129
130const style = StyleSheet.create({
131    wrapper: {
132        width: rpx(750),
133        paddingVertical: rpx(24),
134        justifyContent: 'center',
135        alignItems: 'center',
136    },
137    content: {
138        width: rpx(702),
139        flexDirection: 'row',
140        justifyContent: 'space-between',
141        alignItems: 'center',
142    },
143    coverImg: {
144        width: rpx(210),
145        height: rpx(210),
146        borderRadius: rpx(24),
147    },
148    details: {
149        width: rpx(456),
150        height: rpx(140),
151        justifyContent: 'space-between',
152    },
153    divider: {
154        marginVertical: rpx(18),
155    },
156
157    albumDesc: {
158        width: rpx(702),
159    },
160    /** playall */
161    topWrapper: {
162        height: rpx(72),
163        paddingHorizontal: rpx(24),
164        flexDirection: 'row',
165        alignItems: 'center',
166    },
167    playAll: {
168        flex: 1,
169        flexDirection: 'row',
170        alignItems: 'center',
171    },
172    playAllIcon: {
173        marginRight: rpx(12),
174    },
175});
176