xref: /MusicFree/src/components/musicList/index.tsx (revision adf41771e5c3ca7c27879b461cece7e444d1dc58)
1import React from 'react';
2import {FlatListProps} from 'react-native';
3import rpx from '@/utils/rpx';
4
5import MusicItem from '../mediaItem/musicItem';
6import Empty from '../base/empty';
7import {FlashList} from '@shopify/flash-list';
8import ListLoading from '../base/listLoading';
9import ListReachEnd from '../base/listReachEnd';
10import TrackPlayer from '@/core/trackPlayer';
11
12interface IMusicListProps {
13    /** 顶部 */
14    Header?: FlatListProps<IMusic.IMusicItem>['ListHeaderComponent'];
15    /** 音乐列表 */
16    musicList?: IMusic.IMusicItem[];
17    /** 所在歌单 */
18    musicSheet?: IMusic.IMusicSheetItem;
19    /** 是否展示序号 */
20    showIndex?: boolean;
21    /** 点击 */
22    onItemPress?: (
23        musicItem: IMusic.IMusicItem,
24        musicList?: IMusic.IMusicItem[],
25    ) => void;
26    loadMore?: 'loading' | 'done' | 'idle';
27    onEndReached?: () => void;
28}
29const ITEM_HEIGHT = rpx(120);
30
31/** 音乐列表 */
32export default function MusicList(props: IMusicListProps) {
33    const {
34        Header,
35        musicList,
36        musicSheet,
37        showIndex,
38        onItemPress,
39        onEndReached,
40        loadMore = 'idle',
41    } = props;
42
43    // ! keyExtractor需要保证整个生命周期统一? 有些奇怪
44    // const keyExtractor = useCallback(
45    //     (item: any, index: number) =>
46    //         '' + index + '-' + item.platform + '-' + item.id,
47    //     [],
48    // );
49
50    return (
51        <FlashList
52            ListHeaderComponent={Header}
53            ListEmptyComponent={loadMore !== 'loading' ? Empty : null}
54            ListFooterComponent={
55                loadMore === 'done'
56                    ? ListReachEnd
57                    : loadMore === 'loading'
58                    ? ListLoading
59                    : null
60            }
61            data={musicList ?? []}
62            // keyExtractor={keyExtractor}
63            estimatedItemSize={ITEM_HEIGHT}
64            renderItem={({index, item: musicItem}) => {
65                return (
66                    <MusicItem
67                        musicItem={musicItem}
68                        index={showIndex ? index + 1 : undefined}
69                        onItemPress={() => {
70                            if (onItemPress) {
71                                onItemPress(musicItem, musicList);
72                            } else {
73                                TrackPlayer.playWithReplacePlayList(
74                                    musicItem,
75                                    musicList ?? [musicItem],
76                                );
77                            }
78                        }}
79                        musicSheet={musicSheet}
80                    />
81                );
82            }}
83            onEndReached={() => {
84                if (loadMore !== 'loading') {
85                    onEndReached?.();
86                }
87            }}
88            onEndReachedThreshold={0.1}
89        />
90    );
91}
92