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