|
|
@@ -0,0 +1,46 @@
|
|
|
+import { AxiosInstance, AxiosResponse } from 'axios';
|
|
|
+import { useCallback, useContext, useEffect } from 'react';
|
|
|
+import { stateSet } from '../actions';
|
|
|
+import { DispatchContext } from '../context/state';
|
|
|
+import { NullSong, Song, songExists } from '../types';
|
|
|
+import { getApiUrl } from '../utils/url';
|
|
|
+
|
|
|
+import { useRequestCallback } from './request';
|
|
|
+
|
|
|
+function useNextOrPrevSong(
|
|
|
+ key: 'next' | 'prev',
|
|
|
+): [(songId: number) => void, Song | NullSong | null, boolean] {
|
|
|
+ const sendRequest = useCallback(
|
|
|
+ (axios: AxiosInstance, id: number): Promise<AxiosResponse<Song | NullSong>> =>
|
|
|
+ axios.get(`${getApiUrl()}/${key}-song?id=${id}`),
|
|
|
+ [key],
|
|
|
+ );
|
|
|
+
|
|
|
+ return useRequestCallback<number, Song | NullSong>({
|
|
|
+ sendRequest,
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export function usePlayQueue(): {
|
|
|
+ onNext: (songId: number) => void;
|
|
|
+ onPrev: (songId: number) => void;
|
|
|
+ loading: boolean;
|
|
|
+} {
|
|
|
+ const dispatch = useContext(DispatchContext);
|
|
|
+
|
|
|
+ const [onRequestNext, nextSong, loadingNext] = useNextOrPrevSong('next');
|
|
|
+ const [onRequestPrev, prevSong, loadingPrev] = useNextOrPrevSong('prev');
|
|
|
+
|
|
|
+ const response = nextSong ?? prevSong;
|
|
|
+ useEffect(() => {
|
|
|
+ if (response) {
|
|
|
+ if (songExists(response)) {
|
|
|
+ dispatch(stateSet({ songId: response.id, seekTime: 0, playing: true }));
|
|
|
+ } else {
|
|
|
+ dispatch(stateSet({ songId: null, playing: false, seekTime: -1 }));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [dispatch, response]);
|
|
|
+
|
|
|
+ return { onNext: onRequestNext, onPrev: onRequestPrev, loading: loadingNext || loadingPrev };
|
|
|
+}
|