Преглед изворни кода

feat: hook for next / previous song

Fela Maslen пре 5 година
родитељ
комит
50f50ffa4b
2 измењених фајлова са 50 додато и 0 уклоњено
  1. 46 0
      gmus-web/src/hooks/queue.ts
  2. 4 0
      gmus-web/src/types/songs.ts

+ 46 - 0
gmus-web/src/hooks/queue.ts

@@ -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 };
+}

+ 4 - 0
gmus-web/src/types/songs.ts

@@ -6,3 +6,7 @@ export type Song = {
   album: string;
   time: number;
 };
+
+export type NullSong = { id: 0 };
+
+export const songExists = (song: Song | NullSong): song is Song => !!song.id;