From b5392b67312b340f0125d575fe8552eba62bac74 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Mon, 16 Aug 2021 11:57:36 +0900 Subject: [PATCH] now playing header now shows context menu fixed now playing image gradient --- app/components/ContextMenu.tsx | 37 +++++++++++++++++++--- app/components/HeaderBar.tsx | 32 +++++++++++++------ app/components/ImageGradientBackground.tsx | 3 -- app/hooks/music.ts | 1 - app/hooks/trackplayer.ts | 8 +++-- app/models/music.ts | 2 ++ app/screens/NowPlayingView.tsx | 29 +++++++---------- app/state/music.ts | 3 +- app/state/trackplayer.ts | 2 ++ 9 files changed, 77 insertions(+), 40 deletions(-) diff --git a/app/components/ContextMenu.tsx b/app/components/ContextMenu.tsx index f63497c..9dc7b1a 100644 --- a/app/components/ContextMenu.tsx +++ b/app/components/ContextMenu.tsx @@ -1,6 +1,6 @@ import PressableOpacity from '@app/components/PressableOpacity' import { useStarred } from '@app/hooks/music' -import { AlbumListItem, Artist, Song } from '@app/models/music' +import { AlbumListItem, Artist, Song, StarrableItemType } from '@app/models/music' import { selectMusic } from '@app/state/music' import { useStore } from '@app/state/store' import colors from '@app/styles/colors' @@ -25,6 +25,7 @@ type ContextMenuProps = { triggerOuterWrapperStyle?: StyleProp triggerTouchableStyle?: StyleProp onPress?: () => any + triggerOnLongPress?: boolean } type InternalContextMenuProps = ContextMenuProps & { @@ -41,6 +42,7 @@ const ContextMenu: React.FC = ({ menuHeader, menuOptions, children, + triggerOnLongPress, }) => { menuStyle = menuStyle || { flex: 1 } triggerWrapperStyle = triggerWrapperStyle || { flex: 1 } @@ -49,7 +51,7 @@ const ContextMenu: React.FC = ({ return ( (({ id, type }) => { + type: StarrableItemType + additionalText?: string +}>(({ id, type, additionalText: text }) => { const starred = useStarred(id, type) const setStarred = useStore(selectMusic.starItem) return ( } - text={starred ? 'Unstar' : 'Star'} + text={(starred ? 'Unstar' : 'Star') + (text ? ` ${text}` : '')} onSelect={() => setStarred(id, type, starred)} /> ) @@ -277,6 +280,30 @@ export const ArtistContextPressable: React.FC = pro ) } +export type NowPlayingContextPressableProps = ContextMenuProps & { + song: Song +} + +export const NowPlayingContextPressable: React.FC = props => { + const navigation = useNavigation() + const { song, children } = props + + return ( + } + menuOptions={ + <> + + + + + }> + {children} + + ) +} + const styles = StyleSheet.create({ optionsContainer: { backgroundColor: 'rgba(45, 45, 45, 0.95)', diff --git a/app/components/HeaderBar.tsx b/app/components/HeaderBar.tsx index d24c65b..ac51ad6 100644 --- a/app/components/HeaderBar.tsx +++ b/app/components/HeaderBar.tsx @@ -8,13 +8,15 @@ import Animated from 'react-native-reanimated' import PressableOpacity from './PressableOpacity' import IconMat from 'react-native-vector-icons/MaterialIcons' import { ReactComponentLike } from 'prop-types' +import { Song } from '@app/models/music' +import { NowPlayingContextPressable } from './ContextMenu' const HeaderBar = React.memo<{ title?: string headerStyle?: Animated.AnimatedStyleProp | Animated.AnimatedStyleProp[] HeaderCenter?: ReactComponentLike - onMore?: () => void -}>(({ title, headerStyle, HeaderCenter, onMore }) => { + contextItem?: Song +}>(({ title, headerStyle, HeaderCenter, contextItem }) => { const navigation = useNavigation() const back = useCallback(() => { @@ -23,9 +25,23 @@ const HeaderBar = React.memo<{ const _headerStyle = Array.isArray(headerStyle) ? headerStyle : [headerStyle] + const moreIcon = + let more = <> + if (contextItem) { + more = ( + + {moreIcon} + + ) + } + return ( - + @@ -37,13 +53,7 @@ const HeaderBar = React.memo<{ )} - {onMore ? ( - - - - ) : ( - <> - )} + {more} ) }) @@ -62,6 +72,8 @@ const styles = StyleSheet.create({ height: 42, width: 42, marginHorizontal: 8, + alignItems: 'center', + justifyContent: 'center', }, center: { flex: 1, diff --git a/app/components/ImageGradientBackground.tsx b/app/components/ImageGradientBackground.tsx index cc0ac79..ea3e31c 100644 --- a/app/components/ImageGradientBackground.tsx +++ b/app/components/ImageGradientBackground.tsx @@ -18,7 +18,6 @@ const ImageGradientBackground: React.FC<{ useEffect(() => { async function getColors() { - console.log(`imagePath: ${imagePath}`) if (imagePath === undefined) { return } @@ -27,7 +26,6 @@ const ImageGradientBackground: React.FC<{ let res: AndroidImageColors if (cachedResult) { - console.log(`cachedResult: ${JSON.stringify(cachedResult)}`) res = cachedResult as AndroidImageColors } else { const path = `file://${imagePath}` @@ -35,7 +33,6 @@ const ImageGradientBackground: React.FC<{ cache: true, key: imagePath, })) as AndroidImageColors - console.log(`res: ${JSON.stringify(res)}`) } if (res.muted && res.muted !== '#000000') { diff --git a/app/hooks/music.ts b/app/hooks/music.ts index 462a7b0..83d59ff 100644 --- a/app/hooks/music.ts +++ b/app/hooks/music.ts @@ -116,7 +116,6 @@ export const useArtistArtFile = (artistId: string) => { useEffect(() => { if (!file && artistInfo && artistInfo.largeImageUrl) { - console.log(artistInfo.largeImageUrl) cacheItem('artistArt', artistId, artistInfo.largeImageUrl) } }, [artistId, artistInfo, artistInfo?.largeImageUrl, cacheItem, file]) diff --git a/app/hooks/trackplayer.ts b/app/hooks/trackplayer.ts index 621b82f..28dcaf6 100644 --- a/app/hooks/trackplayer.ts +++ b/app/hooks/trackplayer.ts @@ -279,11 +279,11 @@ function mapSongToTrack(song: Song, coverArtPaths: { [coverArt: string]: string album: song.album || 'Unknown Album', url: song.streamUri, artwork: - song.coverArt && coverArtPaths[song.coverArt] - ? `file://${coverArtPaths[song.coverArt]}` - : require('@res/fallback.png'), + song.coverArt && coverArtPaths[song.coverArt] ? coverArtPaths[song.coverArt] : require('@res/fallback.png'), coverArt: song.coverArt, duration: song.duration, + artistId: song.artistId, + albumId: song.albumId, } } @@ -297,5 +297,7 @@ export function mapTrackExtToSong(track: TrackExt): Song { streamUri: track.url as string, coverArt: track.coverArt, duration: track.duration, + artistId: track.artistId, + albumId: track.albumId, } } diff --git a/app/models/music.ts b/app/models/music.ts index 443c044..ccdeab8 100644 --- a/app/models/music.ts +++ b/app/models/music.ts @@ -80,6 +80,8 @@ export type ListableItem = Song | AlbumListItem | Artist | PlaylistListItem export type HomeLists = { [key: string]: AlbumListItem[] } +export type StarrableItemType = 'song' | 'album' | 'artist' + export enum CacheItemType { coverArt, artistArt, diff --git a/app/screens/NowPlayingView.tsx b/app/screens/NowPlayingView.tsx index 1ffcadd..0a38405 100644 --- a/app/screens/NowPlayingView.tsx +++ b/app/screens/NowPlayingView.tsx @@ -5,6 +5,7 @@ import PressableOpacity from '@app/components/PressableOpacity' import Star from '@app/components/Star' import { useStarred } from '@app/hooks/music' import { + mapTrackExtToSong, useNext, usePause, usePlay, @@ -15,7 +16,7 @@ import { } from '@app/hooks/trackplayer' import { selectMusic } from '@app/state/music' import { useStore } from '@app/state/store' -import { QueueContextType, selectTrackPlayer } from '@app/state/trackplayer' +import { QueueContextType, selectTrackPlayer, TrackExt } from '@app/state/trackplayer' import colors from '@app/styles/colors' import font from '@app/styles/font' import formatDuration from '@app/util/formatDuration' @@ -45,34 +46,28 @@ function getContextName(type?: QueueContextType) { } } -const NowPlayingHeader = React.memo(() => { - const navigation = useNavigation() +const NowPlayingHeader = React.memo<{ + track?: TrackExt +}>(({ track }) => { const queueName = useStore(selectTrackPlayer.name) const queueContextType = useStore(selectTrackPlayer.queueContextType) - const queueContextId = useStore(selectTrackPlayer.queueContextId) + + if (!track) { + return <> + } let contextName = getContextName(queueContextType) - const goToContext = useCallback(() => { - if (!queueContextType || !queueContextId || queueContextType === 'song') { - return - } - navigation.navigate('library') - navigation.navigate(queueContextType, { id: queueContextId, title: queueName }) - }, [navigation, queueContextId, queueContextType, queueName]) - return ( ( - {contextName ? ( + {contextName !== undefined && ( {contextName} - ) : ( - <> )} {queueName || 'Nothing playing...'} @@ -395,7 +390,7 @@ const NowPlayingView: React.FC = ({ navigation }) => { return ( - + diff --git a/app/state/music.ts b/app/state/music.ts index 7ccd650..48710ca 100644 --- a/app/state/music.ts +++ b/app/state/music.ts @@ -15,6 +15,7 @@ import { PlaylistWithSongs, SearchResults, Song, + StarrableItemType, } from '@app/models/music' import { Store } from '@app/state/store' import { GetAlbumList2Type, StarParams } from '@app/subsonic/params' @@ -65,7 +66,7 @@ export type MusicSlice = { starredSongs: { [id: string]: boolean } starredAlbums: { [id: string]: boolean } starredArtists: { [id: string]: boolean } - starItem: (id: string, type: string, unstar?: boolean) => Promise + starItem: (id: string, type: StarrableItemType, unstar?: boolean) => Promise albumIdCoverArt: { [id: string]: string | undefined } albumIdCoverArtRequests: { [id: string]: Promise } diff --git a/app/state/trackplayer.ts b/app/state/trackplayer.ts index f00f4a0..8300855 100644 --- a/app/state/trackplayer.ts +++ b/app/state/trackplayer.ts @@ -7,6 +7,8 @@ import { Store } from './store' export type TrackExt = Track & { id: string coverArt?: string + artistId?: string + albumId?: string } export type Progress = {