xref: /MusicFree/src/pages/home/components/homeBody/sheets.tsx (revision f511aee942b46704ba24f02b787187ad201f6c10)
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';
17
18export default function Sheets() {
19    const [index, setIndex] = useState(0);
20    const colors = useColors();
21    const navigate = useNavigate();
22
23    const allSheets = MusicSheet.useUserSheets();
24    const staredSheets: IMusic.IMusicSheet = [];
25
26    const selectedTabTextStyle = useMemo(() => {
27        return [
28            styles.selectTabText,
29            {
30                borderBottomColor: colors.primary,
31            },
32        ];
33    }, [colors]);
34
35    return (
36        <>
37            <View style={styles.subTitleContainer}>
38                <TouchableWithoutFeedback
39                    style={styles.tabContainer}
40                    onPress={() => {
41                        setIndex(0);
42                    }}>
43                    <ThemeText
44                        fontSize="title"
45                        style={[
46                            styles.tabText,
47                            index === 0 ? selectedTabTextStyle : null,
48                        ]}>
49                        我的歌单
50                    </ThemeText>
51                    <ThemeText
52                        fontColor="textSecondary"
53                        fontSize="subTitle"
54                        style={styles.tabText}>
55                        {' '}
56                        ({allSheets.length})
57                    </ThemeText>
58                </TouchableWithoutFeedback>
59                <TouchableWithoutFeedback
60                    style={styles.tabContainer}
61                    onPress={() => {
62                        setIndex(1);
63                    }}>
64                    <ThemeText
65                        fontSize="title"
66                        style={[
67                            styles.tabText,
68                            index === 1 ? selectedTabTextStyle : null,
69                        ]}>
70                        收藏歌单
71                    </ThemeText>
72                    <ThemeText
73                        fontColor="textSecondary"
74                        fontSize="subTitle"
75                        style={styles.tabText}>
76                        {' '}
77                        ({staredSheets.length})
78                    </ThemeText>
79                </TouchableWithoutFeedback>
80                <View style={styles.more}>
81                    <IconButton
82                        name="plus"
83                        sizeType="normal"
84                        accessibilityLabel="新建歌单"
85                        onPress={() => {
86                            showPanel('NewMusicSheet');
87                        }}
88                    />
89                </View>
90            </View>
91            <FlashList
92                ListEmptyComponent={<Empty />}
93                data={(index === 0 ? allSheets : staredSheets) ?? []}
94                estimatedItemSize={ListItem.Size.big}
95                renderItem={({item: sheet}) => (
96                    <ListItem
97                        key={`${sheet.id}`}
98                        heightType="big"
99                        withHorizonalPadding
100                        onPress={() => {
101                            navigate(ROUTE_PATH.LOCAL_SHEET_DETAIL, {
102                                id: sheet.id,
103                            });
104                        }}>
105                        <ListItem.ListItemImage
106                            uri={sheet.coverImg}
107                            fallbackImg={ImgAsset.albumDefault}
108                        />
109                        <ListItem.Content
110                            title={sheet.title}
111                            description={`${sheet.musicList.length ?? '-'}首`}
112                        />
113                        <ListItem.ListItemIcon
114                            position="right"
115                            icon="trash-can-outline"
116                            onPress={() => {
117                                showDialog('SimpleDialog', {
118                                    title: '删除歌单',
119                                    content: `确定删除歌单「${sheet.title}」吗?`,
120                                    onOk: async () => {
121                                        await MusicSheet.removeSheet(sheet.id);
122                                        Toast.success('已删除');
123                                    },
124                                });
125                            }}
126                        />
127                    </ListItem>
128                )}
129                nestedScrollEnabled
130            />
131        </>
132    );
133}
134
135const styles = StyleSheet.create({
136    subTitleContainer: {
137        paddingHorizontal: rpx(24),
138        flexDirection: 'row',
139        alignItems: 'flex-start',
140        marginBottom: rpx(12),
141    },
142    subTitleLeft: {
143        flexDirection: 'row',
144    },
145    tabContainer: {
146        flexDirection: 'row',
147        marginRight: rpx(32),
148    },
149
150    tabText: {
151        lineHeight: rpx(64),
152    },
153    selectTabText: {
154        borderBottomWidth: rpx(6),
155        fontWeight: 'bold',
156    },
157    more: {
158        height: rpx(64),
159        marginTop: rpx(3),
160        flexGrow: 1,
161        flexDirection: 'row',
162        justifyContent: 'flex-end',
163    },
164});
165