import PressableOpacity from '@app/components/PressableOpacity' import { AlbumListItem, Artist, Song } from '@app/models/music' import colors from '@app/styles/colors' import font from '@app/styles/font' import { NavigationProp, useNavigation } from '@react-navigation/native' import { ReactComponentLike } from 'prop-types' import React from 'react' import { ScrollView, StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native' import FastImage from 'react-native-fast-image' import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from 'react-native-popup-menu' import IconFA from 'react-native-vector-icons/FontAwesome' import IconFA5 from 'react-native-vector-icons/FontAwesome5' import IconMat from 'react-native-vector-icons/MaterialIcons' import CoverArt from './CoverArt' const { SlideInMenu } = renderers type ContextMenuProps = { menuStyle?: StyleProp triggerWrapperStyle?: StyleProp triggerOuterWrapperStyle?: StyleProp triggerTouchableStyle?: StyleProp onPress?: () => void } type InternalContextMenuProps = ContextMenuProps & { menuHeader: React.ReactNode menuOptions: React.ReactNode } const ContextMenu: React.FC = ({ menuStyle, triggerWrapperStyle, triggerOuterWrapperStyle, triggerTouchableStyle, onPress, menuHeader, menuOptions, children, }) => { menuStyle = menuStyle || { flex: 1 } triggerWrapperStyle = triggerWrapperStyle || { flex: 1 } triggerOuterWrapperStyle = triggerOuterWrapperStyle || { flex: 1 } triggerTouchableStyle = triggerTouchableStyle || { flex: 1 } return ( {children} ( {menuHeader} {options} )}> {menuOptions} ) } type ContextMenuOptionProps = { onSelect?: () => void } const ContextMenuOption: React.FC = ({ onSelect, children }) => ( {children} ) type ContextMenuIconTextOptionProps = ContextMenuOptionProps & { IconComponent: ReactComponentLike name: string size: number color?: string text: string } const ContextMenuIconTextOption = React.memo( ({ onSelect, IconComponent, name, color, size, text }) => ( {text} ), ) const MenuHeader = React.memo<{ coverArt?: string artistId?: string title: string subtitle?: string }>(({ coverArt, artistId, title, subtitle }) => ( {title} {subtitle ? ( {subtitle} ) : ( <> )} )) const OptionStar = React.memo(() => ( )) const OptionViewArtist = React.memo<{ navigation: NavigationProp artist?: string artistId?: string }>(({ navigation, artist, artistId }) => { if (!artist || !artistId) { return <> } return ( navigation.navigate('artist', { id: artistId, title: artist })} /> ) }) const OptionViewAlbum = React.memo<{ navigation: NavigationProp album?: string albumId?: string }>(({ navigation, album, albumId }) => { if (!album || !albumId) { return <> } return ( navigation.navigate('album', { id: albumId, title: album })} /> ) }) const OptionDownload = React.memo<{ itemType: string }>(({ itemType }) => ( )) export type AlbumContextPressableProps = ContextMenuProps & { album: AlbumListItem } export const AlbumContextPressable: React.FC = props => { const navigation = useNavigation() const { album, children } = props return ( } menuOptions={ <> }> {children} ) } export type SongContextPressableProps = ContextMenuProps & { song: Song } export const SongContextPressable: React.FC = props => { const navigation = useNavigation() const { song, children } = props return ( } menuOptions={ <> }> {children} ) } export type ArtistContextPressableProps = ContextMenuProps & { artist: Artist } export const ArtistContextPressable: React.FC = props => { const { artist, children } = props return ( } menuOptions={ <> }> {children} ) } const styles = StyleSheet.create({ optionsContainer: { backgroundColor: 'rgba(45, 45, 45, 0.95)', maxHeight: 365, }, optionsWrapper: { // marginBottom: 10, }, menuHeader: { paddingTop: 14, paddingBottom: 10, paddingHorizontal: 20, flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, coverArt: { width: 42, height: 42, }, menuHeaderText: { flex: 1, marginLeft: 10, }, menuTitle: { fontFamily: font.semiBold, fontSize: 16, color: colors.text.primary, }, menuSubtitle: { fontFamily: font.regular, fontSize: 14, color: colors.text.secondary, }, option: { paddingVertical: 8, paddingHorizontal: 20, flexDirection: 'row', alignItems: 'center', }, icon: { marginRight: 10, width: 32, height: 32, justifyContent: 'center', alignItems: 'center', // backgroundColor: 'red', }, optionText: { fontFamily: font.semiBold, fontSize: 16, color: colors.text.primary, // backgroundColor: 'green', }, })