xref: /MusicFree/src/pages/home/components/homeBody/sheets.tsx (revision 095287552b9baf2f2ceeb9397c563c292a4f7934)
1import React, {useMemo, useState} from 'react';
2import {StyleSheet, View} from 'react-native';
3import rpx from '@/utils/rpx';
4import ThemeText from '@/components/base/themeText';
5import useColors from '@/hooks/useColors';
6import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
7import MusicSheet from '@/core/musicSheet';
8import {FlashList} from '@shopify/flash-list';
9import ListItem from '@/components/base/listItem';
10import {ROUTE_PATH, useNavigate} from '@/entry/router';
11import {ImgAsset} from '@/constants/assetsConst';
12import {showDialog} from '@/components/dialogs/useDialog';
13import Toast from '@/utils/toast';
14import Empty from '@/components/base/empty';
15import IconButton from '@/components/base/iconButton';
16import {showPanel} from '@/components/panels/usePanel';
17import {localPluginPlatform} from '@/constants/commonConst';
18
19export default function Sheets() {
20    const [index, setIndex] = useState(0);
21    const colors = useColors();
22    const navigate = useNavigate();
23
24    const allSheets = MusicSheet.useSheets();
25    const staredSheets = MusicSheet.useStarredMusicSheet();
26
27    const selectedTabTextStyle = useMemo(() => {
28        return [
29            styles.selectTabText,
30            {
31                borderBottomColor: colors.primary,
32            },
33        ];
34    }, [colors]);
35
36    return (
37        <>
38            <View style={styles.subTitleContainer}>
39                <TouchableWithoutFeedback
40                    style={styles.tabContainer}
41                    accessible
42                    accessibilityLabel={`我的歌单,共${allSheets.length}个`}
43                    onPress={() => {
44                        setIndex(0);
45                    }}>
46                    <ThemeText
47                        accessible={false}
48                        fontSize="title"
49                        style={[
50                            styles.tabText,
51                            index === 0 ? selectedTabTextStyle : null,
52                        ]}>
53                        我的歌单
54                    </ThemeText>
55                    <ThemeText
56                        accessible={false}
57                        fontColor="textSecondary"
58                        fontSize="subTitle"
59                        style={styles.tabText}>
60                        {' '}
61                        ({allSheets.length})
62                    </ThemeText>
63                </TouchableWithoutFeedback>
64                <TouchableWithoutFeedback
65                    style={styles.tabContainer}
66                    accessible
67                    accessibilityLabel={`收藏歌单,共${staredSheets.length}个`}
68                    onPress={() => {
69                        setIndex(1);
70                    }}>
71                    <ThemeText
72                        fontSize="title"
73                        accessible={false}
74                        style={[
75                            styles.tabText,
76                            index === 1 ? selectedTabTextStyle : null,
77                        ]}>
78                        收藏歌单
79                    </ThemeText>
80                    <ThemeText
81                        fontColor="textSecondary"
82                        fontSize="subTitle"
83                        accessible={false}
84                        style={styles.tabText}>
85                        {' '}
86                        ({staredSheets.length})
87                    </ThemeText>
88                </TouchableWithoutFeedback>
89                <View style={styles.more}>
90                    <IconButton
91                        name="plus"
92                        sizeType="normal"
93                        accessibilityLabel="新建歌单"
94                        onPress={() => {
95                            showPanel('NewMusicSheet');
96                        }}
97                    />
98                </View>
99            </View>
100            <FlashList
101                ListEmptyComponent={<Empty />}
102                data={(index === 0 ? allSheets : staredSheets) ?? []}
103                estimatedItemSize={ListItem.Size.big}
104                renderItem={({item: sheet}) => {
105                    const isLocalSheet = !(
106                        sheet.platform && sheet.platform !== localPluginPlatform
107                    );
108
109                    return (
110                        <ListItem
111                            key={`${sheet.id}`}
112                            heightType="big"
113                            withHorizonalPadding
114                            onPress={() => {
115                                if (isLocalSheet) {
116                                    navigate(ROUTE_PATH.LOCAL_SHEET_DETAIL, {
117                                        id: sheet.id,
118                                    });
119                                } else {
120                                    navigate(ROUTE_PATH.PLUGIN_SHEET_DETAIL, {
121                                        sheetInfo: sheet,
122                                    });
123                                }
124                            }}>
125                            <ListItem.ListItemImage
126                                uri={sheet.coverImg ?? sheet.artwork}
127                                fallbackImg={ImgAsset.albumDefault}
128                                maskIcon={
129                                    sheet.id === MusicSheet.defaultSheet.id
130                                        ? 'heart'
131                                        : null
132                                }
133                            />
134                            <ListItem.Content
135                                title={sheet.title}
136                                description={
137                                    isLocalSheet
138                                        ? `${sheet.musicList?.length ?? '-'}首`
139                                        : `${sheet.artist}`
140                                }
141                            />
142                            <ListItem.ListItemIcon
143                                position="right"
144                                icon="trash-can-outline"
145                                onPress={() => {
146                                    showDialog('SimpleDialog', {
147                                        title: '删除歌单',
148                                        content: `确定删除歌单「${sheet.title}」吗?`,
149                                        onOk: async () => {
150                                            if (isLocalSheet) {
151                                                await MusicSheet.removeSheet(
152                                                    sheet.id,
153                                                );
154                                                Toast.success('已删除');
155                                            } else {
156                                                await MusicSheet.unstarMusicSheet(
157                                                    sheet,
158                                                );
159                                                Toast.success('已取消收藏');
160                                            }
161                                        },
162                                    });
163                                }}
164                            />
165                        </ListItem>
166                    );
167                }}
168                nestedScrollEnabled
169            />
170        </>
171    );
172}
173
174const styles = StyleSheet.create({
175    subTitleContainer: {
176        paddingHorizontal: rpx(24),
177        flexDirection: 'row',
178        alignItems: 'flex-start',
179        marginBottom: rpx(12),
180    },
181    subTitleLeft: {
182        flexDirection: 'row',
183    },
184    tabContainer: {
185        flexDirection: 'row',
186        marginRight: rpx(32),
187    },
188
189    tabText: {
190        lineHeight: rpx(64),
191    },
192    selectTabText: {
193        borderBottomWidth: rpx(6),
194        fontWeight: 'bold',
195    },
196    more: {
197        height: rpx(64),
198        marginTop: rpx(3),
199        flexGrow: 1,
200        flexDirection: 'row',
201        justifyContent: 'flex-end',
202    },
203});
204