import { useStarred } from '@app/hooks/music' import { useIsPlaying } from '@app/hooks/trackplayer' import { AlbumListItem, Artist, ListableItem, Song } from '@app/models/music' import { selectMusic } from '@app/state/music' import { useStore } from '@app/state/store' import colors from '@app/styles/colors' import font from '@app/styles/font' import { useNavigation } from '@react-navigation/native' import React, { useCallback } from 'react' import { StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native' import IconFA5 from 'react-native-vector-icons/FontAwesome5' import IconMat from 'react-native-vector-icons/MaterialIcons' import { AlbumContextPressable, ArtistContextPressable, SongContextPressable } from './ContextMenu' import CoverArt from './CoverArt' import PressableOpacity from './PressableOpacity' import Star from './Star' const TitleTextSong = React.memo<{ contextId?: string queueId: number title?: string }>(({ contextId, queueId, title }) => { const playing = useIsPlaying(contextId, queueId) return ( {playing && ( )} {title} ) }) const TitleText = React.memo<{ title?: string }>(({ title }) => { return ( {title} ) }) const ListItem: React.FC<{ item: ListableItem contextId?: string queueId?: number onPress?: () => void showArt?: boolean showStar?: boolean listStyle?: 'big' | 'small' subtitle?: string style?: StyleProp }> = ({ item, contextId, queueId, onPress, showArt, showStar, subtitle, listStyle, style }) => { const navigation = useNavigation() const starred = useStarred(item.id, item.itemType) showStar = showStar === undefined ? true : showStar listStyle = listStyle || 'small' const sizeStyle = listStyle === 'big' ? bigStyles : smallStyles if (!onPress) { switch (item.itemType) { case 'album': onPress = () => navigation.navigate('album', { id: item.id, title: item.name }) break case 'artist': onPress = () => navigation.navigate('artist', { id: item.id, title: item.name }) break case 'playlist': onPress = () => navigation.navigate('playlist', { id: item.id, title: item.name }) break } } if (!subtitle) { switch (item.itemType) { case 'song': case 'album': subtitle = item.artist break case 'playlist': subtitle = item.comment break } } const itemPressable = useCallback( ({ children }) => ( {children} ), [onPress], ) const albumPressable = useCallback( ({ children }) => ( {children} ), [item, onPress], ) const songPressable = useCallback( ({ children }) => ( {children} ), [item, onPress], ) const artistPressable = useCallback( ({ children }) => ( {children} ), [item, onPress], ) let PressableComponent = itemPressable if (item.itemType === 'album') { PressableComponent = albumPressable } else if (item.itemType === 'song') { PressableComponent = songPressable } else if (item.itemType === 'artist') { PressableComponent = artistPressable } const starItem = useStore(selectMusic.starItem) const toggleStarred = useCallback(() => { if (item.itemType !== 'playlist') { starItem(item.id, item.itemType, starred) } }, [item.id, item.itemType, starItem, starred]) let title = <> if (item.itemType === 'song' && queueId !== undefined) { title = } else if (item.itemType !== 'song') { title = } const artStyle = { ...styles.art, ...sizeStyle.art } const resizeMode = 'cover' let coverArt = <> if (item.itemType === 'artist') { coverArt = } else { coverArt = } return ( {showArt && coverArt} {title} {subtitle !== undefined && ( {false && ( )} {subtitle} )} {showStar && ( )} ) } const styles = StyleSheet.create({ container: { marginBottom: 14, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, item: { flex: 1, flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', }, art: { marginRight: 10, }, text: { flex: 1, }, textLine: { flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', }, title: { fontSize: 16, fontFamily: font.semiBold, color: colors.text.primary, }, playingIcon: { paddingRight: 4, paddingBottom: 1, }, downloadedIcon: { marginRight: 2, marginLeft: -3, }, subtitle: { fontSize: 14, fontFamily: font.regular, color: colors.text.secondary, }, controls: { flexDirection: 'row', alignItems: 'center', }, controlItem: { marginLeft: 16, }, }) const smallStyles = StyleSheet.create({ container: { minHeight: 50, }, art: { height: 50, width: 50, }, }) const bigStyles = StyleSheet.create({ container: { minHeight: 70, }, art: { height: 70, width: 70, }, }) export default React.memo(ListItem)