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