xref: /MusicFree/src/components/musicSheetPage/components/header.tsx (revision 734113be9d256a2b4d36bb272d6d3565beaeb236)
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                        >
70                            <ThemeText
71                                fontColor="secondary"
72                                fontSize="description"
73                                numberOfLines={maxLines}>
74                                {topListDetail.description}
75                            </ThemeText>
76                        </View>
77                    </Pressable>
78                ) : null}
79            </LinearGradient>
80            <View
81                style={[
82                    style.topWrapper,
83                    {
84                        backgroundColor: Color(colors.primary)
85                            .alpha(0.15)
86                            .toString(),
87                    },
88                ]}>
89                <Pressable
90                    style={style.playAll}
91                    onPress={() => {
92                        if (musicList) {
93                            MusicQueue.playWithReplaceQueue(
94                                musicList[0],
95                                musicList,
96                            );
97                        }
98                    }}>
99                    <Icon
100                        name="play-circle-outline"
101                        style={style.playAllIcon}
102                        size={iconSizeConst.normal}
103                        color={colors.text}
104                    />
105                    <ThemeText fontWeight="bold">播放全部</ThemeText>
106                </Pressable>
107                <IconButton
108                    icon={'plus-box-multiple-outline'}
109                    size={rpx(48)}
110                    onPress={async () => {
111                        showPanel('AddToMusicSheet', {
112                            musicItem: musicList ?? [],
113                            newSheetDefaultName: topListDetail?.title,
114                        });
115                    }}
116                />
117                <IconButton
118                    icon="playlist-edit"
119                    size={rpx(48)}
120                    onPress={async () => {
121                        navigate(ROUTE_PATH.MUSIC_LIST_EDITOR, {
122                            musicList: musicList,
123                            musicSheet: {
124                                title: topListDetail?.title,
125                            },
126                        });
127                    }}
128                />
129            </View>
130        </>
131    );
132}
133
134const style = StyleSheet.create({
135    wrapper: {
136        width: '100%',
137        padding: rpx(24),
138        justifyContent: 'center',
139        alignItems: 'flex-start',
140    },
141    content: {
142        flex: 1,
143        flexDirection: 'row',
144        justifyContent: 'flex-start',
145        alignItems: 'center',
146    },
147    coverImg: {
148        width: rpx(210),
149        height: rpx(210),
150        borderRadius: rpx(24),
151    },
152    details: {
153        flex: 1,
154        height: rpx(140),
155        paddingHorizontal: rpx(36),
156        justifyContent: 'space-between',
157    },
158    divider: {
159        marginVertical: rpx(18),
160    },
161
162    albumDesc: {
163        width: '100%',
164        paddingHorizontal: rpx(24),
165    },
166    /** playall */
167    topWrapper: {
168        height: rpx(72),
169        paddingHorizontal: rpx(24),
170        flexDirection: 'row',
171        alignItems: 'center',
172    },
173    playAll: {
174        flex: 1,
175        flexDirection: 'row',
176        alignItems: 'center',
177    },
178    playAllIcon: {
179        marginRight: rpx(12),
180    },
181});
182