From 9705a95aaa26a4c04f0ac06410ac2573df4f11b6 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Tue, 10 Aug 2021 12:17:36 +0900 Subject: [PATCH] added queue context jump --- app/components/ListPlayerControls.tsx | 12 +++- app/hooks/trackplayer.ts | 14 ++++- app/screens/ArtistView.tsx | 11 +++- app/screens/NowPlayingView.tsx | 81 +++++++++++++++++++++------ app/screens/Search.tsx | 2 +- app/screens/SongListView.tsx | 16 ++++-- app/state/trackplayer.ts | 22 ++++++++ 7 files changed, 130 insertions(+), 28 deletions(-) diff --git a/app/components/ListPlayerControls.tsx b/app/components/ListPlayerControls.tsx index bc833d0..75f2009 100644 --- a/app/components/ListPlayerControls.tsx +++ b/app/components/ListPlayerControls.tsx @@ -1,6 +1,7 @@ import Button from '@app/components/Button' import { useSetQueue } from '@app/hooks/trackplayer' import { Song } from '@app/models/music' +import { QueueContextType } from '@app/state/trackplayer' import colors from '@app/styles/colors' import React, { useState } from 'react' import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native' @@ -11,8 +12,10 @@ const ListPlayerControls = React.memo<{ songs: Song[] typeName: string queueName: string + queueContextType: QueueContextType + queueContextId: string style?: StyleProp -}>(({ songs, typeName, queueName, style }) => { +}>(({ songs, typeName, queueName, queueContextType, queueContextId, style }) => { const [downloaded, setDownloaded] = useState(false) const setQueue = useSetQueue() @@ -28,10 +31,13 @@ const ListPlayerControls = React.memo<{ - diff --git a/app/hooks/trackplayer.ts b/app/hooks/trackplayer.ts index f4c2f50..face3fe 100644 --- a/app/hooks/trackplayer.ts +++ b/app/hooks/trackplayer.ts @@ -5,6 +5,7 @@ import { getCurrentTrack, getQueue, getRepeatMode, + QueueContextType, selectTrackPlayer, TrackExt, trackPlayerCommands, @@ -179,9 +180,18 @@ export const useSetQueue = () => { const setShuffleOrder = useStore(selectTrackPlayer.setShuffleOrder) const setQueueName = useStore(selectTrackPlayer.setName) const getQueueShuffled = useCallback(() => !!useStore.getState().shuffleOrder, []) + const setQueueContextType = useStore(selectTrackPlayer.setQueueContextType) + const setQueueContextId = useStore(selectTrackPlayer.setQueueContextId) const coverArtUri = useCoverArtUri() - return async (songs: Song[], name: string, playTrack?: number, shuffle?: boolean) => + return async ( + songs: Song[], + name: string, + contextType: QueueContextType, + contextId: string, + playTrack?: number, + shuffle?: boolean, + ) => trackPlayerCommands.enqueue(async () => { const shuffled = shuffle !== undefined ? shuffle : getQueueShuffled() @@ -208,6 +218,8 @@ export const useSetQueue = () => { setQueue(queue) setCurrentTrackIdx(playTrack) setQueueName(name) + setQueueContextType(contextType) + setQueueContextId(contextId) if (playTrack === 0) { await TrackPlayer.add(queue) diff --git a/app/screens/ArtistView.tsx b/app/screens/ArtistView.tsx index ecd0fa7..d337b1f 100644 --- a/app/screens/ArtistView.tsx +++ b/app/screens/ArtistView.tsx @@ -42,7 +42,8 @@ const AlbumItem = React.memo<{ const TopSongs = React.memo<{ songs: Song[] name: string -}>(({ songs, name }) => { + artistId: string +}>(({ songs, name, artistId }) => { const setQueue = useSetQueue() return ( @@ -54,7 +55,7 @@ const TopSongs = React.memo<{ item={s} showArt={true} subtitle={s.album} - onPress={() => setQueue(songs, `Top Songs: ${name}`, i)} + onPress={() => setQueue(songs, name, 'artist', artistId, i)} /> ))} @@ -99,7 +100,11 @@ const ArtistDetails: React.FC<{ id: string }> = ({ id }) => { {artist.name} - {artist.topSongs.length > 0 ? : <>} + {artist.topSongs.length > 0 ? ( + + ) : ( + <> + )}
Albums
{_albums.map(a => ( diff --git a/app/screens/NowPlayingView.tsx b/app/screens/NowPlayingView.tsx index 097c641..1c311b3 100644 --- a/app/screens/NowPlayingView.tsx +++ b/app/screens/NowPlayingView.tsx @@ -6,7 +6,7 @@ import { useStarred } from '@app/hooks/music' import { useNext, usePause, usePlay, usePrevious, useToggleRepeat, useToggleShuffle } from '@app/hooks/trackplayer' import { selectMusic } from '@app/state/music' import { useStore } from '@app/state/store' -import { selectTrackPlayer } from '@app/state/trackplayer' +import { QueueContextType, selectTrackPlayer } from '@app/state/trackplayer' import colors from '@app/styles/colors' import dimensions from '@app/styles/dimensions' import font from '@app/styles/font' @@ -22,20 +22,63 @@ import Icon from 'react-native-vector-icons/Ionicons' import IconMatCom from 'react-native-vector-icons/MaterialCommunityIcons' import IconMat from 'react-native-vector-icons/MaterialIcons' -const NowPlayingHeader = React.memo<{ - backHandler: () => void -}>(({ backHandler }) => { +function getContextName(type?: QueueContextType) { + switch (type) { + case 'album': + return 'Album' + case 'artist': + return 'Top Songs' + case 'playlist': + return 'Playlist' + case 'song': + return 'Search Results' + default: + return undefined + } +} + +const NowPlayingHeader = React.memo(() => { + const navigation = useNavigation() const queueName = useStore(selectTrackPlayer.name) + const queueContextType = useStore(selectTrackPlayer.queueContextType) + const queueContextId = useStore(selectTrackPlayer.queueContextId) + + let contextName = getContextName(queueContextType) + + const back = useCallback(() => { + navigation.navigate('top') + }, [navigation]) + + const goToContext = useCallback(() => { + if (!queueContextType || !queueContextId || queueContextType === 'song') { + return + } + navigation.navigate('library') + navigation.navigate(queueContextType, { id: queueContextId, title: queueName }) + }, [navigation, queueContextId, queueContextType, queueName]) return ( - + - - {queueName || 'Nothing playing...'} - - + + {contextName ? ( + + {contextName} + + ) : ( + <> + )} + + {queueName || 'Nothing playing...'} + + + @@ -55,11 +98,21 @@ const headerStyles = StyleSheet.create({ width: 42, marginHorizontal: 8, }, + center: { + flex: 1, + }, + queueType: { + fontFamily: font.regular, + fontSize: 14, + color: colors.text.primary, + // flex: 1, + textAlign: 'center', + }, queueName: { fontFamily: font.bold, fontSize: 16, color: colors.text.primary, - flex: 1, + // flex: 1, textAlign: 'center', }, }) @@ -315,20 +368,16 @@ type NowPlayingProps = NativeStackScreenProps const NowPlayingView: React.FC = ({ navigation }) => { const track = useStore(selectTrackPlayer.currentTrack) - const back = useCallback(() => { - navigation.navigate('top') - }, [navigation]) - useEffect(() => { if (!track) { - back() + navigation.navigate('top') } }) return ( - + diff --git a/app/screens/Search.tsx b/app/screens/Search.tsx index 256bf91..74b58bc 100644 --- a/app/screens/Search.tsx +++ b/app/screens/Search.tsx @@ -21,7 +21,7 @@ const SongItem = React.memo<{ item: Song }>(({ item }) => { item={item} showArt={true} showStar={false} - onPress={() => setQueue([item], `Search: ${item.title}`, 0)} + onPress={() => setQueue([item], item.title, 'song', item.id, 0)} /> ) }) diff --git a/app/screens/SongListView.tsx b/app/screens/SongListView.tsx index f532426..a86ceef 100644 --- a/app/screens/SongListView.tsx +++ b/app/screens/SongListView.tsx @@ -25,7 +25,8 @@ const Songs = React.memo<{ songs: Song[] name: string type: SongListType -}>(({ songs, name, type }) => { + itemId: string +}>(({ songs, name, type, itemId }) => { const setQueue = useSetQueue() const _songs = [...songs] @@ -42,14 +43,21 @@ const Songs = React.memo<{ return ( <> - + {_songs.map((s, i) => ( setQueue(songs, name, i)} + onPress={() => setQueue(songs, name, type, itemId, i)} showArt={type === 'playlist'} /> ))} @@ -76,7 +84,7 @@ const SongListDetails = React.memo<{ {songList.name} {subtitle ? {subtitle} : <>} {songList.songs.length > 0 ? ( - + ) : ( )} diff --git a/app/state/trackplayer.ts b/app/state/trackplayer.ts index 66c5ab5..f00f4a0 100644 --- a/app/state/trackplayer.ts +++ b/app/state/trackplayer.ts @@ -15,10 +15,18 @@ export type Progress = { buffered: number } +export type QueueContextType = 'album' | 'playlist' | 'song' | 'artist' + export type TrackPlayerSlice = { name?: string setName: (name?: string) => void + queueContextType?: QueueContextType + setQueueContextType: (queueContextType?: QueueContextType) => void + + queueContextId?: string + setQueueContextId: (queueContextId?: string) => void + shuffleOrder?: number[] setShuffleOrder: (shuffleOrder?: number[]) => void @@ -47,6 +55,12 @@ export const selectTrackPlayer = { name: (store: TrackPlayerSlice) => store.name, setName: (store: TrackPlayerSlice) => store.setName, + queueContextType: (store: TrackPlayerSlice) => store.queueContextType, + setQueueContextType: (store: TrackPlayerSlice) => store.setQueueContextType, + + queueContextId: (store: TrackPlayerSlice) => store.queueContextId, + setQueueContextId: (store: TrackPlayerSlice) => store.setQueueContextId, + shuffleOrder: (store: TrackPlayerSlice) => store.shuffleOrder, setShuffleOrder: (store: TrackPlayerSlice) => store.setShuffleOrder, shuffled: (store: TrackPlayerSlice) => !!store.shuffleOrder, @@ -78,6 +92,12 @@ export const createTrackPlayerSlice = (set: SetState, get: GetState set({ name }), + queueContextType: undefined, + setQueueContextType: queueContextType => set({ queueContextType }), + + queueContextId: undefined, + setQueueContextId: queueContextId => set({ queueContextId }), + shuffleOrder: undefined, setShuffleOrder: shuffleOrder => set({ shuffleOrder }), @@ -122,6 +142,8 @@ export const createTrackPlayerSlice = (set: SetState, get: GetState { set({ name: undefined, + queueContextType: undefined, + queueContextId: undefined, shuffleOrder: undefined, repeatMode: RepeatMode.Off, playerState: State.None,