refactor api controller to internalize server fetch

This commit is contained in:
jeffvli
2025-11-02 21:56:35 -08:00
parent 8dbaec3943
commit c7a473d864
79 changed files with 904 additions and 399 deletions
@@ -3,7 +3,6 @@ import { queryOptions } from '@tanstack/react-query';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { QueryHookArgs } from '/@/renderer/lib/react-query';
import { getServerById } from '/@/renderer/store';
import {
PlaylistDetailQuery,
PlaylistListQuery,
@@ -14,14 +13,12 @@ export const playlistsQueries = {
detail: (args: QueryHookArgs<PlaylistDetailQuery>) => {
return queryOptions({
queryFn: ({ signal }) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.getPlaylistDetail({
apiClientProps: { server, signal },
apiClientProps: { serverId: args.serverId, signal },
query: args.query,
});
},
queryKey: queryKeys.playlists.detail(args.serverId || '', args.query.id, args.query),
queryKey: queryKeys.playlists.detail(args.serverId, args.query.id, args.query),
...args.options,
});
},
@@ -29,10 +26,8 @@ export const playlistsQueries = {
return queryOptions({
gcTime: 1000 * 60 * 60,
queryFn: ({ signal }) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.getPlaylistList({
apiClientProps: { server, signal },
apiClientProps: { serverId: args.serverId, signal },
query: args.query,
});
},
@@ -43,10 +38,8 @@ export const playlistsQueries = {
songList: (args: QueryHookArgs<PlaylistSongListQuery>) => {
return queryOptions({
queryFn: ({ signal }) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.getPlaylistSongList({
apiClientProps: { server, signal },
apiClientProps: { serverId: args.serverId, signal },
query: args.query,
});
},
@@ -120,7 +120,7 @@ export const AddToPlaylistContextModal = ({
queryFn: ({ signal }) => {
if (!server) throw new Error('No server');
return api.controller.getSongList({
apiClientProps: { server, signal },
apiClientProps: { serverId: server?.id || '', signal },
query,
});
},
@@ -147,7 +147,7 @@ export const AddToPlaylistContextModal = ({
queryFn: ({ signal }) => {
if (!server) throw new Error('No server');
return api.controller.getSongList({
apiClientProps: { server, signal },
apiClientProps: { serverId: server?.id || '', signal },
query,
});
},
@@ -203,7 +203,7 @@ export const AddToPlaylistContextModal = ({
for (const playlist of values.newPlaylists) {
try {
const response = await api.controller.createPlaylist({
apiClientProps: { server },
apiClientProps: { serverId: server?.id || '' },
body: {
name: playlist,
public: false,
@@ -238,7 +238,7 @@ export const AddToPlaylistContextModal = ({
);
return api.controller.getPlaylistSongList({
apiClientProps: {
server,
serverId: server?.id || '',
signal,
},
query: {
@@ -266,9 +266,9 @@ export const AddToPlaylistContextModal = ({
}
addToPlaylistMutation.mutate(
{
apiClientProps: { serverId: server.id },
body: { songId: values.skipDuplicates ? uniqueSongIds : allSongIds },
query: { id: playlistId },
serverId: server?.id,
},
{
onError: (err) => {
@@ -58,6 +58,7 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
mutation.mutate(
{
apiClientProps: { serverId: server.id },
body: {
...values,
_custom: {
@@ -75,7 +76,6 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
},
},
},
serverId: server.id,
},
{
onError: (err) => {
@@ -111,7 +111,7 @@ export const PlaylistDetailSongListContent = ({ songs, tableRef }: PlaylistDetai
try {
await api.controller.movePlaylistItem({
apiClientProps: {
server,
serverId: server?.id || '',
},
query: {
endingIndex: e.overIndex,
@@ -376,7 +376,10 @@ export const PlaylistDetailSongListHeaderFilters = ({
const handleDeletePlaylist = useCallback(() => {
if (!detailQuery.data) return;
deletePlaylistMutation?.mutate(
{ query: { id: detailQuery.data.id }, serverId: detailQuery.data.serverId },
{
apiClientProps: { serverId: detailQuery.data.serverId },
query: { id: detailQuery.data.id },
},
{
onError: (err) => {
toast.error({
@@ -38,7 +38,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
const handlePlayQueueAdd = usePlayQueueAdd();
const { display, filter, grid } = useListStoreByKey<PlaylistListQuery>({ key: pageKey });
const { setGrid } = useListStoreActions();
const handleFavorite = useHandleFavorite({ gridRef, server });
const handleFavorite = useHandleFavorite({ gridRef });
const cardRows = useMemo(() => {
const rows: CardRow<Playlist>[] = [PLAYLIST_CARD_ROWS.nameFull];
@@ -126,7 +126,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
queryFn: async ({ signal }) =>
controller.getPlaylistList({
apiClientProps: {
server,
serverId: server?.id || '',
signal,
},
query,
@@ -174,7 +174,7 @@ export const PlaylistListHeaderFilters = ({
queryFn: async ({ signal }) =>
api.controller.getPlaylistList({
apiClientProps: {
server,
serverId: server?.id || '',
signal,
},
query,
@@ -213,7 +213,7 @@ export const PlaylistListHeaderFilters = ({
queryFn: async ({ signal }) =>
api.controller.getPlaylistList({
apiClientProps: {
server,
serverId: server?.id || '',
signal,
},
query: {
@@ -21,7 +21,7 @@ interface SaveAsPlaylistFormProps {
body: Partial<CreatePlaylistBody>;
onCancel: () => void;
onSuccess: (data: CreatePlaylistResponse) => void;
serverId: string | undefined;
serverId?: string;
}
export const SaveAsPlaylistForm = ({
@@ -50,7 +50,7 @@ export const SaveAsPlaylistForm = ({
const handleSubmit = form.onSubmit((values) => {
mutation.mutate(
{ body: values, serverId },
{ apiClientProps: { serverId: serverId || '' }, body: values },
{
onError: (err) => {
toast.error({
@@ -65,9 +65,9 @@ export const UpdatePlaylistForm = ({ body, onCancel, query, users }: UpdatePlayl
const handleSubmit = form.onSubmit((values) => {
mutation.mutate(
{
apiClientProps: { serverId: server?.id || '' },
body: values,
query,
serverId: server?.id,
},
{
onError: (err) => {
@@ -174,7 +174,10 @@ export const openUpdatePlaylistModal = async (args: {
? await queryClient
.fetchQuery({
queryFn: ({ signal }) =>
api.controller.getUserList({ apiClientProps: { server, signal }, query }),
api.controller.getUserList({
apiClientProps: { serverId: server?.id || '', signal },
query,
}),
queryKey: queryKeys.users.list(server?.id || '', query),
})
.catch((error) => {
@@ -4,26 +4,22 @@ import { AxiosError } from 'axios';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { MutationHookArgs } from '/@/renderer/lib/react-query';
import { getServerById } from '/@/renderer/store';
import { AddToPlaylistArgs, AddToPlaylistResponse } from '/@/shared/types/domain-types';
export const useAddToPlaylist = (args: MutationHookArgs) => {
const { options } = args || {};
const queryClient = useQueryClient();
return useMutation<
AddToPlaylistResponse,
AxiosError,
Omit<AddToPlaylistArgs, 'apiClientProps' | 'server'>,
null
>({
return useMutation<AddToPlaylistResponse, AxiosError, AddToPlaylistArgs, null>({
mutationFn: (args) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.addToPlaylist({ ...args, apiClientProps: { server } });
return api.controller.addToPlaylist({
...args,
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onSuccess: (_data, variables) => {
const { serverId } = variables;
const { apiClientProps } = variables;
const serverId = apiClientProps.serverId;
if (!serverId) return;
@@ -4,32 +4,24 @@ import { AxiosError } from 'axios';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { MutationHookArgs } from '/@/renderer/lib/react-query';
import { getServerById } from '/@/renderer/store';
import { CreatePlaylistArgs, CreatePlaylistResponse } from '/@/shared/types/domain-types';
export const useCreatePlaylist = (args: MutationHookArgs) => {
const { options } = args || {};
const queryClient = useQueryClient();
return useMutation<
CreatePlaylistResponse,
AxiosError,
Omit<CreatePlaylistArgs, 'apiClientProps' | 'server'>,
null
>({
return useMutation<CreatePlaylistResponse, AxiosError, CreatePlaylistArgs, null>({
mutationFn: (args) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.createPlaylist({ ...args, apiClientProps: { server } });
return api.controller.createPlaylist({
...args,
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onSuccess: (_args, variables) => {
const server = getServerById(variables.serverId);
if (server) {
queryClient.invalidateQueries({
exact: false,
queryKey: queryKeys.playlists.list(server.id),
});
}
queryClient.invalidateQueries({
exact: false,
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
});
},
...options,
});
@@ -4,33 +4,29 @@ import { AxiosError } from 'axios';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { MutationHookArgs } from '/@/renderer/lib/react-query';
import { getServerById, useCurrentServer } from '/@/renderer/store';
import { DeletePlaylistArgs, DeletePlaylistResponse } from '/@/shared/types/domain-types';
export const useDeletePlaylist = (args: MutationHookArgs) => {
const { options } = args || {};
const queryClient = useQueryClient();
const server = useCurrentServer();
return useMutation<
DeletePlaylistResponse,
AxiosError,
Omit<DeletePlaylistArgs, 'apiClientProps' | 'server'>,
null
>({
return useMutation<DeletePlaylistResponse, AxiosError, DeletePlaylistArgs, null>({
mutationFn: (args) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.deletePlaylist({ ...args, apiClientProps: { server } });
return api.controller.deletePlaylist({
...args,
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onMutate: () => {
queryClient.cancelQueries({ queryKey: queryKeys.playlists.list(server?.id || '') });
onMutate: (variables) => {
queryClient.cancelQueries({
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
});
return null;
},
onSuccess: () => {
onSuccess: (_data, variables) => {
queryClient.invalidateQueries({
exact: false,
queryKey: queryKeys.playlists.list(server?.id || ''),
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
});
},
...options,
@@ -4,25 +4,21 @@ import { AxiosError } from 'axios';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { MutationOptions } from '/@/renderer/lib/react-query';
import { getServerById } from '/@/renderer/store';
import { RemoveFromPlaylistArgs, RemoveFromPlaylistResponse } from '/@/shared/types/domain-types';
export const useRemoveFromPlaylist = (options?: MutationOptions) => {
const queryClient = useQueryClient();
return useMutation<
RemoveFromPlaylistResponse,
AxiosError,
Omit<RemoveFromPlaylistArgs, 'apiClientProps' | 'server'>,
null
>({
return useMutation<RemoveFromPlaylistResponse, AxiosError, RemoveFromPlaylistArgs, null>({
mutationFn: (args) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.removeFromPlaylist({ ...args, apiClientProps: { server } });
return api.controller.removeFromPlaylist({
...args,
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onSuccess: (_data, variables) => {
const { serverId } = variables;
const { apiClientProps } = variables;
const serverId = apiClientProps.serverId;
if (!serverId) return;
@@ -4,26 +4,22 @@ import { AxiosError } from 'axios';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { MutationHookArgs } from '/@/renderer/lib/react-query';
import { getServerById } from '/@/renderer/store';
import { UpdatePlaylistArgs, UpdatePlaylistResponse } from '/@/shared/types/domain-types';
export const useUpdatePlaylist = (args: MutationHookArgs) => {
const { options } = args || {};
const queryClient = useQueryClient();
return useMutation<
UpdatePlaylistResponse,
AxiosError,
Omit<UpdatePlaylistArgs, 'apiClientProps' | 'server'>,
null
>({
return useMutation<UpdatePlaylistResponse, AxiosError, UpdatePlaylistArgs, null>({
mutationFn: (args) => {
const server = getServerById(args.serverId);
if (!server) throw new Error('Server not found');
return api.controller.updatePlaylist({ ...args, apiClientProps: { server } });
return api.controller.updatePlaylist({
...args,
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onSuccess: (_data, variables) => {
const { query, serverId } = variables;
const { apiClientProps, query } = variables;
const serverId = apiClientProps.serverId;
if (!serverId) return;
@@ -56,6 +56,7 @@ const PlaylistDetailSongListRoute = () => {
createPlaylistMutation.mutate(
{
apiClientProps: { serverId: detailQuery?.data?.serverId },
body: {
_custom: {
navidrome: {
@@ -69,7 +70,6 @@ const PlaylistDetailSongListRoute = () => {
name: detailQuery?.data?.name,
public: detailQuery?.data?.public || false,
},
serverId: detailQuery?.data?.serverId,
},
{
onSuccess: (data) => {
@@ -83,8 +83,8 @@ const PlaylistDetailSongListRoute = () => {
},
);
deletePlaylistMutation.mutate({
apiClientProps: { serverId: detailQuery?.data?.serverId },
query: { id: playlistId },
serverId: detailQuery?.data?.serverId,
});
},
},
@@ -124,7 +124,7 @@ const PlaylistDetailSongListRoute = () => {
}),
)
}
serverId={detailQuery?.data?.serverId}
serverId={detailQuery?.data?.serverId || ''}
/>
),
title: t('common.saveAs', { postProcess: 'sentenceCase' }),