From 68a1cb9aaa04d34ba37766da0f8ef8ba9ad7d20a Mon Sep 17 00:00:00 2001 From: jeffvli Date: Thu, 27 Apr 2023 21:44:25 -0700 Subject: [PATCH] Refactor all mutation hooks --- .../player/mutations/scrobble-mutation.ts | 12 +- .../mutations/add-to-playlist-mutation.ts | 34 +++--- .../mutations/create-playlist-mutation.ts | 25 +++-- .../mutations/delete-playlist-mutation.ts | 19 ++-- .../remove-from-playlist-mutation.ts | 26 ++--- .../mutations/update-playlist-mutation.ts | 32 +++--- .../mutations/create-favorite-mutation.ts | 102 ++++++----------- .../mutations/delete-favorite-mutation.ts | 103 +++++++----------- ...ing-mutation.ts => set-rating-mutation.ts} | 27 ++--- 9 files changed, 166 insertions(+), 214 deletions(-) rename src/renderer/features/shared/mutations/{update-rating-mutation.ts => set-rating-mutation.ts} (87%) diff --git a/src/renderer/features/player/mutations/scrobble-mutation.ts b/src/renderer/features/player/mutations/scrobble-mutation.ts index d38b5f41..c6232570 100644 --- a/src/renderer/features/player/mutations/scrobble-mutation.ts +++ b/src/renderer/features/player/mutations/scrobble-mutation.ts @@ -1,18 +1,18 @@ import { useMutation } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; -import { RawScrobbleResponse, ScrobbleArgs } from '/@/renderer/api/types'; +import { ScrobbleResponse, ScrobbleArgs } from '/@/renderer/api/types'; import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useAuthStore, useCurrentServer, useIncrementQueuePlayCount } from '/@/renderer/store'; +import { getServerById, useIncrementQueuePlayCount } from '/@/renderer/store'; export const useSendScrobble = (options?: MutationOptions) => { - const currentServer = useCurrentServer(); const incrementPlayCount = useIncrementQueuePlayCount(); - return useMutation, null>({ + return useMutation, null>({ mutationFn: (args) => { - const server = useAuthStore.getState().actions.getServer(args._serverId) || currentServer; - return api.controller.scrobble({ ...args, server }); + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.scrobble({ ...args, apiClientProps: { server } }); }, onSuccess: (_data, variables) => { // Manually increment the play count for the song in the queue if scrobble was submitted diff --git a/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts b/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts index a68e1730..e991bac9 100644 --- a/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts @@ -2,25 +2,31 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { AddToPlaylistArgs, RawAddToPlaylistResponse } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useCurrentServer } from '/@/renderer/store'; +import { AddToPlaylistArgs, AddToPlaylistResponse } from '/@/renderer/api/types'; +import { MutationHookArgs } from '/@/renderer/lib/react-query'; +import { getServerById } from '/@/renderer/store'; -export const useAddToPlaylist = (options?: MutationOptions) => { +export const useAddToPlaylist = (args: MutationHookArgs) => { + const { options } = args || {}; const queryClient = useQueryClient(); - const server = useCurrentServer(); - return useMutation, null>({ - mutationFn: (args) => api.controller.addToPlaylist({ ...args, server }), + return useMutation< + AddToPlaylistResponse, + HTTPError, + Omit, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.addToPlaylist({ ...args, apiClientProps: { server } }); + }, onSuccess: (_data, variables) => { - queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || ''), { exact: false }); - + const { serverId } = variables; + queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); queryClient.invalidateQueries( - queryKeys.playlists.detail(server?.id || '', variables.query.id), - ); - - queryClient.invalidateQueries( - queryKeys.playlists.detailSongList(server?.id || '', variables.query.id), + queryKeys.playlists.detailSongList(serverId, variables.query.id), ); }, ...options, diff --git a/src/renderer/features/playlists/mutations/create-playlist-mutation.ts b/src/renderer/features/playlists/mutations/create-playlist-mutation.ts index 06a96481..d7aac6e7 100644 --- a/src/renderer/features/playlists/mutations/create-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/create-playlist-mutation.ts @@ -2,23 +2,28 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { CreatePlaylistArgs, RawCreatePlaylistResponse } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useCurrentServer } from '/@/renderer/store'; +import { CreatePlaylistArgs, CreatePlaylistResponse } from '/@/renderer/api/types'; +import { MutationHookArgs } from '/@/renderer/lib/react-query'; +import { getServerById } from '/@/renderer/store'; -export const useCreatePlaylist = (options?: MutationOptions) => { +export const useCreatePlaylist = (args: MutationHookArgs) => { + const { options } = args || {}; const queryClient = useQueryClient(); - const server = useCurrentServer(); return useMutation< - RawCreatePlaylistResponse, + CreatePlaylistResponse, HTTPError, - Omit, + Omit, null >({ - mutationFn: (args) => api.controller.createPlaylist({ ...args, server }), - onSuccess: () => { - queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || ''), { exact: false }); + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.createPlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const serverId = variables.serverId; + queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); }, ...options, }); diff --git a/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts b/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts index 9aca7ca9..eebde576 100644 --- a/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts @@ -2,21 +2,26 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { DeletePlaylistArgs, RawDeletePlaylistResponse } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useCurrentServer } from '/@/renderer/store'; +import { DeletePlaylistArgs, DeletePlaylistResponse } from '/@/renderer/api/types'; +import { MutationHookArgs } from '/@/renderer/lib/react-query'; +import { getServerById, useCurrentServer } from '/@/renderer/store'; -export const useDeletePlaylist = (options?: MutationOptions) => { +export const useDeletePlaylist = (args: MutationHookArgs) => { + const { options } = args || {}; const queryClient = useQueryClient(); const server = useCurrentServer(); return useMutation< - RawDeletePlaylistResponse, + DeletePlaylistResponse, HTTPError, - Omit, + Omit, null >({ - mutationFn: (args) => api.controller.deletePlaylist({ ...args, server }), + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.deletePlaylist({ ...args, apiClientProps: { server } }); + }, onMutate: () => { queryClient.cancelQueries(queryKeys.playlists.list(server?.id || '')); return null; diff --git a/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts b/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts index e78dd2c6..76e373ea 100644 --- a/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts @@ -2,30 +2,30 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { RawRemoveFromPlaylistResponse, RemoveFromPlaylistArgs } from '/@/renderer/api/types'; +import { RemoveFromPlaylistResponse, RemoveFromPlaylistArgs } from '/@/renderer/api/types'; import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useCurrentServer } from '/@/renderer/store'; +import { getServerById } from '/@/renderer/store'; export const useRemoveFromPlaylist = (options?: MutationOptions) => { const queryClient = useQueryClient(); - const server = useCurrentServer(); return useMutation< - RawRemoveFromPlaylistResponse, + RemoveFromPlaylistResponse, HTTPError, - Omit, + Omit, null >({ - mutationFn: (args) => api.controller.removeFromPlaylist({ ...args, server }), + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.removeFromPlaylist({ ...args, apiClientProps: { server } }); + }, onSuccess: (_data, variables) => { - queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || ''), { exact: false }); - + const { serverId } = variables; + queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); queryClient.invalidateQueries( - queryKeys.playlists.detail(server?.id || '', variables.query.id), - ); - - queryClient.invalidateQueries( - queryKeys.playlists.detailSongList(server?.id || '', variables.query.id), + queryKeys.playlists.detailSongList(serverId, variables.query.id), ); }, ...options, diff --git a/src/renderer/features/playlists/mutations/update-playlist-mutation.ts b/src/renderer/features/playlists/mutations/update-playlist-mutation.ts index 18abf810..f6af55a1 100644 --- a/src/renderer/features/playlists/mutations/update-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/update-playlist-mutation.ts @@ -2,26 +2,26 @@ import { useMutation, useQueryClient } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { RawUpdatePlaylistResponse, UpdatePlaylistArgs } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; -import { useCurrentServer } from '/@/renderer/store'; +import { UpdatePlaylistArgs, UpdatePlaylistResponse } from '/@/renderer/api/types'; +import { MutationHookArgs } from '/@/renderer/lib/react-query'; +import { getServerById } from '/@/renderer/store'; -export const useUpdatePlaylist = (options?: MutationOptions) => { +export const useUpdatePlaylist = (args: MutationHookArgs) => { + const { options } = args || {}; const queryClient = useQueryClient(); - const server = useCurrentServer(); - return useMutation< - RawUpdatePlaylistResponse, - HTTPError, - Omit, - null - >({ - mutationFn: (args) => api.controller.updatePlaylist({ ...args, server }), - onSuccess: (data) => { - queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || '')); + return useMutation, null>({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.updatePlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { query, serverId } = variables; + queryClient.invalidateQueries(queryKeys.playlists.list(serverId)); - if (data?.id) { - queryClient.invalidateQueries(queryKeys.playlists.detail(server?.id || '', data.id)); + if (query?.id) { + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, query.id)); } }, ...options, diff --git a/src/renderer/features/shared/mutations/create-favorite-mutation.ts b/src/renderer/features/shared/mutations/create-favorite-mutation.ts index 38958031..33957bf0 100644 --- a/src/renderer/features/shared/mutations/create-favorite-mutation.ts +++ b/src/renderer/features/shared/mutations/create-favorite-mutation.ts @@ -1,27 +1,35 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; -import { JFAlbumArtistDetail, JFAlbumDetail } from '/@/renderer/api/jellyfin.types'; -import { NDAlbumArtistDetail, NDAlbumDetail } from '/@/renderer/api/navidrome.types'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { SSAlbumArtistDetail, SSAlbumDetail } from '/@/renderer/api/subsonic.types'; -import { FavoriteArgs, LibraryItem, RawFavoriteResponse, ServerType } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; import { - useCurrentServer, - useSetAlbumListItemDataById, - useSetQueueFavorite, -} from '/@/renderer/store'; + AlbumArtistDetailResponse, + AlbumDetailResponse, + FavoriteArgs, + FavoriteResponse, + LibraryItem, +} from '/@/renderer/api/types'; +import { MutationHookArgs, queryClient } from '/@/renderer/lib/react-query'; +import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store'; -export const useCreateFavorite = (options?: MutationOptions) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); +export const useCreateFavorite = (args?: MutationHookArgs) => { + const { options } = args || {}; const setAlbumListData = useSetAlbumListItemDataById(); const setQueueFavorite = useSetQueueFavorite(); - return useMutation, null>({ - mutationFn: (args) => api.controller.createFavorite({ ...args, server }), + return useMutation< + FavoriteResponse, + HTTPError, + Omit, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.createFavorite({ ...args, apiClientProps: { server } }); + }, onSuccess: (_data, variables) => { + const { serverId } = variables; for (const id of variables.query.id) { // Set the userFavorite property to true for the album in the album list data store if (variables.query.type === LibraryItem.ALBUM) { @@ -35,71 +43,33 @@ export const useCreateFavorite = (options?: MutationOptions) => { // We only need to set if we're already on the album detail page if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { - const queryKey = queryKeys.albums.detail(server?.id || '', { id: variables.query.id[0] }); - const previous = queryClient.getQueryData(queryKey); + const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); + const previous = queryClient.getQueryData(queryKey); if (previous) { - switch (server?.type) { - case ServerType.NAVIDROME: - queryClient.setQueryData(queryKey, { - ...previous, - starred: true, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData(queryKey, { - ...previous, - starred: true, - }); - break; - case ServerType.JELLYFIN: - queryClient.setQueryData(queryKey, { - ...previous, - UserData: { - ...previous.UserData, - IsFavorite: true, - }, - }); - break; - } + queryClient.setQueryData(queryKey, { + ...previous, + userFavorite: true, + }); } } // We only need to set if we're already on the album detail page if (variables.query.type === LibraryItem.ALBUM_ARTIST && variables.query.id.length === 1) { - const queryKey = queryKeys.albumArtists.detail(server?.id || '', { + const queryKey = queryKeys.albumArtists.detail(serverId, { id: variables.query.id[0], }); - const previous = queryClient.getQueryData(queryKey); + + const previous = queryClient.getQueryData(queryKey); if (previous) { - switch (server?.type) { - case ServerType.NAVIDROME: - queryClient.setQueryData(queryKey, { - ...previous, - starred: true, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData(queryKey, { - ...previous, - starred: true, - }); - break; - case ServerType.JELLYFIN: - queryClient.setQueryData(queryKey, { - ...previous, - UserData: { - ...previous.UserData, - IsFavorite: true, - }, - }); - break; - } + queryClient.setQueryData(queryKey, { + ...previous, + userFavorite: true, + }); } } }, - ...options, }); }; diff --git a/src/renderer/features/shared/mutations/delete-favorite-mutation.ts b/src/renderer/features/shared/mutations/delete-favorite-mutation.ts index 3706353e..b4e6b780 100644 --- a/src/renderer/features/shared/mutations/delete-favorite-mutation.ts +++ b/src/renderer/features/shared/mutations/delete-favorite-mutation.ts @@ -1,27 +1,36 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { HTTPError } from 'ky'; import { api } from '/@/renderer/api'; -import { JFAlbumArtistDetail, JFAlbumDetail } from '/@/renderer/api/jellyfin.types'; -import { NDAlbumArtistDetail, NDAlbumDetail } from '/@/renderer/api/navidrome.types'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { SSAlbumArtistDetail, SSAlbumDetail } from '/@/renderer/api/subsonic.types'; -import { FavoriteArgs, LibraryItem, RawFavoriteResponse, ServerType } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; import { - useCurrentServer, - useSetAlbumListItemDataById, - useSetQueueFavorite, -} from '/@/renderer/store'; + AlbumArtistDetailResponse, + AlbumDetailResponse, + FavoriteArgs, + FavoriteResponse, + LibraryItem, +} from '/@/renderer/api/types'; +import { MutationHookArgs, queryClient } from '/@/renderer/lib/react-query'; +import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store'; -export const useDeleteFavorite = (options?: MutationOptions) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); +export const useDeleteFavorite = (args: MutationHookArgs) => { + const { options } = args || {}; + // const queryClient = useQueryClient(); const setAlbumListData = useSetAlbumListItemDataById(); const setQueueFavorite = useSetQueueFavorite(); - return useMutation, null>({ - mutationFn: (args) => api.controller.deleteFavorite({ ...args, server }), + return useMutation< + FavoriteResponse, + HTTPError, + Omit, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.deleteFavorite({ ...args, apiClientProps: { server } }); + }, onSuccess: (_data, variables) => { + const { serverId } = variables; for (const id of variables.query.id) { // Set the userFavorite property to false for the album in the album list data store if (variables.query.type === LibraryItem.ALBUM) { @@ -35,67 +44,29 @@ export const useDeleteFavorite = (options?: MutationOptions) => { // We only need to set if we're already on the album detail page if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { - const queryKey = queryKeys.albums.detail(server?.id || '', { id: variables.query.id[0] }); - const previous = queryClient.getQueryData(queryKey); + const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); + const previous = queryClient.getQueryData(queryKey); if (previous) { - switch (server?.type) { - case ServerType.NAVIDROME: - queryClient.setQueryData(queryKey, { - ...previous, - starred: false, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData(queryKey, { - ...previous, - starred: false, - }); - break; - case ServerType.JELLYFIN: - queryClient.setQueryData(queryKey, { - ...previous, - UserData: { - ...previous.UserData, - IsFavorite: false, - }, - }); - break; - } + queryClient.setQueryData(queryKey, { + ...previous, + userFavorite: false, + }); } } - // We only need to set if we're already on the album detail page + // We only need to set if we're already on the album artist detail page if (variables.query.type === LibraryItem.ALBUM_ARTIST && variables.query.id.length === 1) { - const queryKey = queryKeys.albumArtists.detail(server?.id || '', { + const queryKey = queryKeys.albumArtists.detail(serverId, { id: variables.query.id[0], }); - const previous = queryClient.getQueryData(queryKey); + const previous = queryClient.getQueryData(queryKey); if (previous) { - switch (server?.type) { - case ServerType.NAVIDROME: - queryClient.setQueryData(queryKey, { - ...previous, - starred: false, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData(queryKey, { - ...previous, - starred: false, - }); - break; - case ServerType.JELLYFIN: - queryClient.setQueryData(queryKey, { - ...previous, - UserData: { - ...previous.UserData, - IsFavorite: false, - }, - }); - break; - } + queryClient.setQueryData(queryKey, { + ...previous, + userFavorite: false, + }); } } }, diff --git a/src/renderer/features/shared/mutations/update-rating-mutation.ts b/src/renderer/features/shared/mutations/set-rating-mutation.ts similarity index 87% rename from src/renderer/features/shared/mutations/update-rating-mutation.ts rename to src/renderer/features/shared/mutations/set-rating-mutation.ts index d2ef0565..372a96f5 100644 --- a/src/renderer/features/shared/mutations/update-rating-mutation.ts +++ b/src/renderer/features/shared/mutations/set-rating-mutation.ts @@ -9,33 +9,29 @@ import { AlbumArtist, AnyLibraryItems, LibraryItem, - RatingArgs, - RawRatingResponse, + SetRatingArgs, + RatingResponse, ServerType, } from '/@/renderer/api/types'; -import { MutationOptions } from '/@/renderer/lib/react-query'; -import { - useAuthStore, - useCurrentServer, - useSetAlbumListItemDataById, - useSetQueueRating, -} from '/@/renderer/store'; +import { MutationHookArgs } from '/@/renderer/lib/react-query'; +import { getServerById, useSetAlbumListItemDataById, useSetQueueRating } from '/@/renderer/store'; -export const useUpdateRating = (options?: MutationOptions) => { +export const useSetRating = (args: MutationHookArgs) => { + const { options } = args || {}; const queryClient = useQueryClient(); - const currentServer = useCurrentServer(); const setAlbumListData = useSetAlbumListItemDataById(); const setQueueRating = useSetQueueRating(); return useMutation< - RawRatingResponse, + RatingResponse, HTTPError, - Omit, + Omit, { previous: { items: AnyLibraryItems } | undefined } >({ mutationFn: (args) => { - const server = useAuthStore.getState().actions.getServer(args._serverId) || currentServer; - return api.controller.updateRating({ ...args, server }); + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.updateRating({ ...args, apiClientProps: { server } }); }, onError: (_error, _variables, context) => { for (const item of context?.previous?.items || []) { @@ -127,7 +123,6 @@ export const useUpdateRating = (options?: MutationOptions) => { } } }, - ...options, }); };