xref: /MusicFree/src/pages/home/components/homeBody/sheets.tsx (revision ed067386d74ad02ad6f817b5bcbae7b589b9e81f)
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 {FlashList} from '@shopify/flash-list';
8import ListItem from '@/components/base/listItem';
9import {ROUTE_PATH, useNavigate} from '@/core/router';
10import {ImgAsset} from '@/constants/assetsConst';
11import {showDialog} from '@/components/dialogs/useDialog';
12import Toast from '@/utils/toast';
13import Empty from '@/components/base/empty';
14import IconButton from '@/components/base/iconButton';
15import {showPanel} from '@/components/panels/usePanel';
16import {localPluginPlatform} from '@/constants/commonConst';
17import MusicSheet from '@/core/musicSheet';
18
19export default function Sheets() {
20    const [index, setIndex] = useState(0);
21    const colors = useColors();
22    const navigate = useNavigate();
23
24    const allSheets = MusicSheet.useSheetsBase();
25    const staredSheets = MusicSheet.useStarredSheets();
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                        style={styles.newSheetButton}
93                        sizeType="normal"
94                        accessibilityLabel="新建歌单"
95                        onPress={() => {
96                            showPanel('CreateMusicSheet');
97                        }}
98                    />
99                    <IconButton
100                        name="inbox-arrow-down"
101                        sizeType="normal"
102                        accessibilityLabel="导入歌单"
103                        onPress={() => {
104                            showPanel('ImportMusicSheet');
105                        }}
106                    />
107                </View>
108            </View>
109            <FlashList
110                ListEmptyComponent={<Empty />}
111                data={(index === 0 ? allSheets : staredSheets) ?? []}
112                estimatedItemSize={ListItem.Size.big}
113                renderItem={({item: sheet}) => {
114                    const isLocalSheet = !(
115                        sheet.platform && sheet.platform !== localPluginPlatform
116                    );
117
118                    return (
119                        <ListItem
120                            key={`${sheet.id}`}
121                            heightType="big"
122                            withHorizontalPadding
123                            onPress={() => {
124                                if (isLocalSheet) {
125                                    navigate(ROUTE_PATH.LOCAL_SHEET_DETAIL, {
126                                        id: sheet.id,
127                                    });
128                                } else {
129                                    navigate(ROUTE_PATH.PLUGIN_SHEET_DETAIL, {
130                                        sheetInfo: sheet,
131                                    });
132                                }
133                            }}>
134                            <ListItem.ListItemImage
135                                uri={sheet.coverImg ?? sheet.artwork}
136                                fallbackImg={ImgAsset.albumDefault}
137                                maskIcon={
138                                    sheet.id === MusicSheet.defaultSheet.id
139                                        ? 'heart'
140                                        : null
141                                }
142                            />
143                            <ListItem.Content
144                                title={sheet.title}
145                                description={
146                                    isLocalSheet
147                                        ? `${sheet.worksNum}首`
148                                        : `${sheet.artist}`
149                                }
150                            />
151                            {sheet.id !== MusicSheet.defaultSheet.id ? (
152                                <ListItem.ListItemIcon
153                                    position="right"
154                                    icon="trash-outline"
155                                    onPress={() => {
156                                        showDialog('SimpleDialog', {
157                                            title: '删除歌单',
158                                            content: `确定删除歌单「${sheet.title}」吗?`,
159                                            onOk: async () => {
160                                                if (isLocalSheet) {
161                                                    await MusicSheet.removeSheet(
162                                                        sheet.id,
163                                                    );
164                                                    Toast.success('已删除');
165                                                } else {
166                                                    await MusicSheet.unstarMusicSheet(
167                                                        sheet,
168                                                    );
169                                                    Toast.success('已取消收藏');
170                                                }
171                                            },
172                                        });
173                                    }}
174                                />
175                            ) : null}
176                        </ListItem>
177                    );
178                }}
179                nestedScrollEnabled
180            />
181        </>
182    );
183}
184
185const styles = StyleSheet.create({
186    subTitleContainer: {
187        paddingHorizontal: rpx(24),
188        flexDirection: 'row',
189        alignItems: 'flex-start',
190        marginBottom: rpx(12),
191    },
192    subTitleLeft: {
193        flexDirection: 'row',
194    },
195    tabContainer: {
196        flexDirection: 'row',
197        marginRight: rpx(32),
198    },
199
200    tabText: {
201        lineHeight: rpx(64),
202    },
203    selectTabText: {
204        borderBottomWidth: rpx(6),
205        fontWeight: 'bold',
206    },
207    more: {
208        height: rpx(64),
209        marginTop: rpx(3),
210        flexGrow: 1,
211        flexDirection: 'row',
212        justifyContent: 'flex-end',
213    },
214    newSheetButton: {
215        marginRight: rpx(24),
216    },
217});
218