xref: /MusicFree/src/pages/home/components/homeBody/sheets.tsx (revision 6f57784c275163ac8a27e94966ab9905b104d753)
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                    onPress={() => {
42                        setIndex(0);
43                    }}>
44                    <ThemeText
45                        fontSize="title"
46                        style={[
47                            styles.tabText,
48                            index === 0 ? selectedTabTextStyle : null,
49                        ]}>
50                        我的歌单
51                    </ThemeText>
52                    <ThemeText
53                        fontColor="textSecondary"
54                        fontSize="subTitle"
55                        style={styles.tabText}>
56                        {' '}
57                        ({allSheets.length})
58                    </ThemeText>
59                </TouchableWithoutFeedback>
60                <TouchableWithoutFeedback
61                    style={styles.tabContainer}
62                    onPress={() => {
63                        setIndex(1);
64                    }}>
65                    <ThemeText
66                        fontSize="title"
67                        style={[
68                            styles.tabText,
69                            index === 1 ? selectedTabTextStyle : null,
70                        ]}>
71                        收藏歌单
72                    </ThemeText>
73                    <ThemeText
74                        fontColor="textSecondary"
75                        fontSize="subTitle"
76                        style={styles.tabText}>
77                        {' '}
78                        ({staredSheets.length})
79                    </ThemeText>
80                </TouchableWithoutFeedback>
81                <View style={styles.more}>
82                    <IconButton
83                        name="plus"
84                        sizeType="normal"
85                        accessibilityLabel="新建歌单"
86                        onPress={() => {
87                            showPanel('NewMusicSheet');
88                        }}
89                    />
90                </View>
91            </View>
92            <FlashList
93                ListEmptyComponent={<Empty />}
94                data={(index === 0 ? allSheets : staredSheets) ?? []}
95                estimatedItemSize={ListItem.Size.big}
96                renderItem={({item: sheet}) => {
97                    const isLocalSheet = !(
98                        sheet.platform && sheet.platform !== localPluginPlatform
99                    );
100
101                    return (
102                        <ListItem
103                            key={`${sheet.id}`}
104                            heightType="big"
105                            withHorizonalPadding
106                            onPress={() => {
107                                if (isLocalSheet) {
108                                    navigate(ROUTE_PATH.LOCAL_SHEET_DETAIL, {
109                                        id: sheet.id,
110                                    });
111                                } else {
112                                    navigate(ROUTE_PATH.PLUGIN_SHEET_DETAIL, {
113                                        sheetInfo: sheet,
114                                    });
115                                }
116                            }}>
117                            <ListItem.ListItemImage
118                                uri={sheet.coverImg ?? sheet.artwork}
119                                fallbackImg={ImgAsset.albumDefault}
120                                maskIcon={
121                                    sheet.id === MusicSheet.defaultSheet.id
122                                        ? 'heart'
123                                        : null
124                                }
125                            />
126                            <ListItem.Content
127                                title={sheet.title}
128                                description={
129                                    isLocalSheet
130                                        ? `${sheet.musicList?.length ?? '-'}首`
131                                        : `${sheet.artist}`
132                                }
133                            />
134                            <ListItem.ListItemIcon
135                                position="right"
136                                icon="trash-can-outline"
137                                onPress={() => {
138                                    showDialog('SimpleDialog', {
139                                        title: '删除歌单',
140                                        content: `确定删除歌单「${sheet.title}」吗?`,
141                                        onOk: async () => {
142                                            if (isLocalSheet) {
143                                                await MusicSheet.removeSheet(
144                                                    sheet.id,
145                                                );
146                                                Toast.success('已删除');
147                                            } else {
148                                                await MusicSheet.unstarMusicSheet(
149                                                    sheet,
150                                                );
151                                                Toast.success('已取消收藏');
152                                            }
153                                        },
154                                    });
155                                }}
156                            />
157                        </ListItem>
158                    );
159                }}
160                nestedScrollEnabled
161            />
162        </>
163    );
164}
165
166const styles = StyleSheet.create({
167    subTitleContainer: {
168        paddingHorizontal: rpx(24),
169        flexDirection: 'row',
170        alignItems: 'flex-start',
171        marginBottom: rpx(12),
172    },
173    subTitleLeft: {
174        flexDirection: 'row',
175    },
176    tabContainer: {
177        flexDirection: 'row',
178        marginRight: rpx(32),
179    },
180
181    tabText: {
182        lineHeight: rpx(64),
183    },
184    selectTabText: {
185        borderBottomWidth: rpx(6),
186        fontWeight: 'bold',
187    },
188    more: {
189        height: rpx(64),
190        marginTop: rpx(3),
191        flexGrow: 1,
192        flexDirection: 'row',
193        justifyContent: 'flex-end',
194    },
195});
196