2020-06-21 10:30:41 +02:00
|
|
|
import { useCallback } from 'react';
|
|
|
|
|
import TrackPlayer from 'react-native-track-player';
|
|
|
|
|
import { useTypedSelector } from 'store';
|
|
|
|
|
import { generateTrack } from './JellyfinApi';
|
|
|
|
|
import useQueue from './useQueue';
|
2020-08-28 16:28:49 +02:00
|
|
|
import { useDispatch } from 'react-redux';
|
|
|
|
|
import player from 'store/player';
|
2020-06-21 10:30:41 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A hook that generates a callback that can setup and start playing a
|
|
|
|
|
* particular trackId in the player.
|
|
|
|
|
*/
|
|
|
|
|
export default function usePlayTrack() {
|
2020-08-28 16:28:49 +02:00
|
|
|
const dispatch = useDispatch();
|
2020-06-21 10:30:41 +02:00
|
|
|
const credentials = useTypedSelector(state => state.settings.jellyfin);
|
|
|
|
|
const tracks = useTypedSelector(state => state.music.tracks.entities);
|
|
|
|
|
const queue = useQueue();
|
|
|
|
|
|
2020-08-28 16:28:49 +02:00
|
|
|
return useCallback(async function playTrack(trackId: string, play = true, addToEnd = true) {
|
2020-06-21 10:30:41 +02:00
|
|
|
// Get the relevant track
|
|
|
|
|
const track = tracks[trackId];
|
|
|
|
|
|
|
|
|
|
// GUARD: Check if the track actually exists in the store
|
|
|
|
|
if (!track) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GUARD: Check if the track is already in the queue
|
2020-07-10 15:47:03 +02:00
|
|
|
const trackInstances = queue.filter((t) => t.id.startsWith(trackId));
|
|
|
|
|
|
|
|
|
|
// Generate the new track for the queue
|
|
|
|
|
const newTrack = {
|
|
|
|
|
...(trackInstances.length ? trackInstances[0] : generateTrack(track, credentials)),
|
|
|
|
|
id: `${trackId}_${trackInstances.length}`
|
|
|
|
|
};
|
2020-08-28 16:28:49 +02:00
|
|
|
|
|
|
|
|
// Then, we'll need to check where to add the track
|
|
|
|
|
if (addToEnd) {
|
|
|
|
|
await TrackPlayer.add([ newTrack ]);
|
|
|
|
|
} else {
|
|
|
|
|
// Try and locate the current track
|
|
|
|
|
const currentTrackId = await TrackPlayer.getCurrentTrack();
|
|
|
|
|
const currentTrackIndex = queue.findIndex(track => track.id === currentTrackId);
|
|
|
|
|
|
|
|
|
|
// Since the argument is the id to insert the track BEFORE, we need
|
|
|
|
|
// to get the current track + 1
|
|
|
|
|
const targetTrack = currentTrackIndex >= 0 && queue.length > 1
|
|
|
|
|
? queue[currentTrackIndex + 1].id
|
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
|
|
// Depending on whether this track exists, we either add it there,
|
|
|
|
|
// or at the end of the queue.
|
|
|
|
|
await TrackPlayer.add([ newTrack ], targetTrack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then, we'll dispatch the added track event
|
|
|
|
|
dispatch(player.actions.addNewTrackToPlayer());
|
2020-06-21 10:30:41 +02:00
|
|
|
|
|
|
|
|
// Then we'll skip to it and play it
|
2020-08-28 16:28:49 +02:00
|
|
|
if (play) {
|
|
|
|
|
await TrackPlayer.skip(newTrack.id);
|
|
|
|
|
await TrackPlayer.play();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newTrack;
|
|
|
|
|
}, [credentials, tracks, queue, dispatch]);
|
2020-06-21 10:30:41 +02:00
|
|
|
}
|