xref: /MusicFree/src/components/musicList/index.tsx (revision 410a159129b1f6a7a1f44fde7bfad9a46f91e161)
1import React, {useCallback} 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    const keyExtractor = useCallback(
44        (item: any, i: number) => `${i}-${item.platform}-${item.id}`,
45        [],
46    );
47
48    return (
49        <FlashList
50            ListHeaderComponent={Header}
51            ListEmptyComponent={loadMore !== 'loading' ? Empty : null}
52            ListFooterComponent={
53                loadMore === 'done'
54                    ? ListReachEnd
55                    : loadMore === 'loading'
56                    ? ListLoading
57                    : null
58            }
59            data={musicList ?? []}
60            keyExtractor={keyExtractor}
61            estimatedItemSize={ITEM_HEIGHT}
62            renderItem={({index, item: musicItem}) => {
63                return (
64                    <MusicItem
65                        musicItem={musicItem}
66                        index={showIndex ? index + 1 : undefined}
67                        onItemPress={() => {
68                            if (onItemPress) {
69                                onItemPress(musicItem, musicList);
70                            } else {
71                                TrackPlayer.playWithReplacePlayList(
72                                    musicItem,
73                                    musicList ?? [musicItem],
74                                );
75                            }
76                        }}
77                        musicSheet={musicSheet}
78                    />
79                );
80            }}
81            onEndReached={() => {
82                if (loadMore !== 'loading') {
83                    onEndReached?.();
84                }
85            }}
86            onEndReachedThreshold={0.1}
87        />
88    );
89}
90