xref: /MusicFree/src/components/mediaItem/musicItem.tsx (revision 15900d057ad4df766b2f9ea5b48f92a8ce2664db)
1import React, {ReactNode} from 'react';
2import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
3import rpx from '@/utils/rpx';
4import ListItem from '../base/listItem';
5import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
6
7import LocalMusicSheet from '@/core/localMusicSheet';
8import {showPanel} from '../panels/usePanel';
9import TitleAndTag from './titleAndTag';
10import ThemeText from '../base/themeText';
11import TrackPlayer from '@/core/trackPlayer';
12
13interface IMusicItemProps {
14    index?: string | number;
15    showMoreIcon?: boolean;
16    musicItem: IMusic.IMusicItem;
17    musicSheet?: IMusic.IMusicSheetItem;
18    onItemPress?: (musicItem: IMusic.IMusicItem) => void;
19    onItemLongPress?: () => void;
20    itemPaddingRight?: number;
21    left?: () => ReactNode;
22    containerStyle?: StyleProp<ViewStyle>;
23}
24export default function MusicItem(props: IMusicItemProps) {
25    const {
26        musicItem,
27        index,
28        onItemPress,
29        onItemLongPress,
30        musicSheet,
31        itemPaddingRight,
32        showMoreIcon = true,
33        left: Left,
34        containerStyle,
35    } = props;
36
37    return (
38        <ListItem
39            heightType="big"
40            style={containerStyle}
41            withHorizonalPadding
42            leftPadding={index !== undefined ? 0 : undefined}
43            rightPadding={itemPaddingRight}
44            onLongPress={onItemLongPress}
45            onPress={() => {
46                if (onItemPress) {
47                    onItemPress(musicItem);
48                } else {
49                    TrackPlayer.play(musicItem);
50                }
51            }}>
52            {Left ? <Left /> : null}
53            {index !== undefined ? (
54                <ListItem.ListItemText
55                    width={rpx(82)}
56                    position="none"
57                    fixedWidth
58                    contentStyle={styles.indexText}>
59                    {index}
60                </ListItem.ListItemText>
61            ) : null}
62            <ListItem.Content
63                title={
64                    <TitleAndTag
65                        title={musicItem.title}
66                        tag={musicItem.platform}
67                    />
68                }
69                description={
70                    <View style={styles.descContainer}>
71                        {LocalMusicSheet.isLocalMusic(musicItem) && (
72                            <Icon
73                                style={styles.icon}
74                                color="#11659a"
75                                name="check-circle"
76                                size={rpx(22)}
77                            />
78                        )}
79                        <ThemeText
80                            numberOfLines={1}
81                            fontSize="description"
82                            fontColor="textSecondary">
83                            {musicItem.artist}
84                            {musicItem.album ? ` - ${musicItem.album}` : ''}
85                        </ThemeText>
86                    </View>
87                }
88            />
89            {showMoreIcon ? (
90                <ListItem.ListItemIcon
91                    width={rpx(48)}
92                    position="none"
93                    icon="dots-vertical"
94                    onPress={() => {
95                        showPanel('MusicItemOptions', {
96                            musicItem,
97                            musicSheet,
98                        });
99                    }}
100                />
101            ) : null}
102        </ListItem>
103    );
104}
105
106const styles = StyleSheet.create({
107    icon: {
108        marginRight: rpx(6),
109    },
110    descContainer: {
111        flexDirection: 'row',
112        marginTop: rpx(16),
113    },
114
115    indexText: {
116        fontStyle: 'italic',
117        textAlign: 'center',
118    },
119});
120