diff --git a/README.md b/README.md index 5604a429..8c01bee4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Jellify +![Jellify App Icon](assets/icon_60pt_3x.jpg) + A music player for Jellyfin powered by React Native. ### Background diff --git a/components/Home/helpers/recently-played.tsx b/components/Home/helpers/recently-played.tsx index 6d272532..21c4c214 100644 --- a/components/Home/helpers/recently-played.tsx +++ b/components/Home/helpers/recently-played.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React from "react"; import { ScrollView, View } from "tamagui"; import { useHomeContext } from "../provider"; import { H2 } from "../../Global/helpers/text"; @@ -10,16 +10,10 @@ import { QueuingType } from "@/enums/queuing-type"; export default function RecentlyPlayed(): React.JSX.Element { - const { addToQueue, resetQueue, play } = usePlayerContext(); + const { playNewQueue } = usePlayerContext(); const { apiClient, sessionId } = useApiClientContext(); const { recentTracks } = useHomeContext(); - useEffect(() => { - console.log("Recently played", recentTracks); - }, [ - recentTracks - ]) - return (

Play it again

@@ -33,14 +27,10 @@ export default function RecentlyPlayed(): React.JSX.Element { width={150} itemId={recentlyPlayedTrack.AlbumId!} onPress={() => { - resetQueue(false) - .then(() => { - addToQueue(recentTracks.map((track) => { - return mapDtoToTrack(apiClient!, sessionId, track, QueuingType.FromSelection) - })) - .then(() => { - play(index); - }); + playNewQueue.mutate({ + track: recentlyPlayedTrack, + index: index, + tracklist: recentTracks }); }} /> diff --git a/player/hooks/index.ts b/player/hooks/index.ts index 777a596b..501c8ced 100644 --- a/player/hooks/index.ts +++ b/player/hooks/index.ts @@ -1,5 +1,6 @@ import { QueryKeys } from "@/enums/query-keys" -import { useQuery } from "@tanstack/react-query" +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; +import { useMutation, useQuery } from "@tanstack/react-query" import TrackPlayer, { Capability } from "react-native-track-player" const CAPABILITIES: Capability[] = [ diff --git a/player/interfaces.ts b/player/interfaces.ts new file mode 100644 index 00000000..b11bd185 --- /dev/null +++ b/player/interfaces.ts @@ -0,0 +1,7 @@ +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; + +export interface QueueMutation { + track: BaseItemDto; + index: number; + tracklist: BaseItemDto[]; +} \ No newline at end of file diff --git a/player/provider.tsx b/player/provider.tsx index 4985bc2f..e7cc3674 100644 --- a/player/provider.tsx +++ b/player/provider.tsx @@ -12,6 +12,10 @@ import { handlePlaybackProgressUpdated, handlePlaybackStarted, handlePlaybackSta import { useSetupPlayer } from "@/player/hooks"; import { UPDATE_INTERVAL } from "./config"; import { sleep } from "@/helpers/sleep"; +import { useMutation, UseMutationResult } from "@tanstack/react-query"; +import { QueueMutation } from "./interfaces"; +import { mapDtoToTrack } from "@/helpers/mappings"; +import { QueuingType } from "@/enums/queuing-type"; interface PlayerContext { showPlayer: boolean; @@ -24,6 +28,7 @@ interface PlayerContext { pause: () => Promise, resetQueue: (hideMiniplayer : boolean | undefined) => Promise; addToQueue: (tracks: JellifyTrack[]) => Promise; + playNewQueue: UseMutationResult; playbackState: State | undefined; progress: Progress | undefined; } @@ -80,6 +85,20 @@ const PlayerContextInitializer = () => { } //#endregion Functions + //#region Hooks + const playNewQueue = useMutation({ + mutationFn: async (mutation: QueueMutation) => { + await resetQueue(false) + await addToQueue(mutation.tracklist.map((track) => { + return mapDtoToTrack(apiClient!, sessionId, track, QueuingType.FromSelection) + })); + + await play(mutation.index); + } + }); + + //#endregion + //#region RNTP Setup const isPlayerReady = useSetupPlayer().isSuccess; @@ -145,6 +164,7 @@ const PlayerContextInitializer = () => { pause, addToQueue, resetQueue, + playNewQueue, playbackState, progress, } @@ -162,6 +182,24 @@ export const PlayerContext = createContext({ pause: async () => {}, resetQueue: async () => {}, addToQueue: async ([]) => {}, + playNewQueue: { + mutate: () => {}, + mutateAsync: async () => {}, + data: undefined, + error: null, + variables: undefined, + isError: false, + isIdle: true, + isPaused: false, + isPending: false, + isSuccess: false, + status: "idle", + reset: () => {}, + context: {}, + failureCount: 0, + failureReason: null, + submittedAt: 0 + }, playbackState: undefined, progress: undefined, }); @@ -178,6 +216,7 @@ export const PlayerProvider: ({ children }: { children: ReactNode }) => React.JS pause, resetQueue, addToQueue, + playNewQueue, playbackState, progress } = PlayerContextInitializer(); @@ -193,6 +232,7 @@ export const PlayerProvider: ({ children }: { children: ReactNode }) => React.JS pause, resetQueue, addToQueue, + playNewQueue, playbackState, progress }}>