mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-16 05:36:00 +02:00
reimplement smart playlists
This commit is contained in:
@@ -3,6 +3,11 @@ import { AxiosError } from 'axios';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import {
|
||||
applyDeletePlaylistOptimisticUpdates,
|
||||
PreviousQueryData,
|
||||
restorePlaylistQueryData,
|
||||
} from '/@/renderer/features/playlists/mutations/playlist-optimistic-updates';
|
||||
import { MutationHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { DeletePlaylistArgs, DeletePlaylistResponse } from '/@/shared/types/domain-types';
|
||||
|
||||
@@ -10,25 +15,32 @@ export const useDeletePlaylist = (args: MutationHookArgs) => {
|
||||
const { options } = args || {};
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation<DeletePlaylistResponse, AxiosError, DeletePlaylistArgs, null>({
|
||||
mutationFn: (args) => {
|
||||
return api.controller.deletePlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
return useMutation<DeletePlaylistResponse, AxiosError, DeletePlaylistArgs, PreviousQueryData[]>(
|
||||
{
|
||||
mutationFn: (args) => {
|
||||
return api.controller.deletePlaylist({
|
||||
...args,
|
||||
apiClientProps: { serverId: args.apiClientProps.serverId },
|
||||
});
|
||||
},
|
||||
onError: (_error, _variables, context) => {
|
||||
if (context) {
|
||||
restorePlaylistQueryData(queryClient, context);
|
||||
}
|
||||
},
|
||||
onMutate: (variables) => {
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
return applyDeletePlaylistOptimisticUpdates(queryClient, variables);
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
queryClient.invalidateQueries({
|
||||
exact: false,
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
},
|
||||
onMutate: (variables) => {
|
||||
queryClient.cancelQueries({
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
return null;
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
queryClient.invalidateQueries({
|
||||
exact: false,
|
||||
queryKey: queryKeys.playlists.list(variables.apiClientProps.serverId),
|
||||
});
|
||||
},
|
||||
...options,
|
||||
});
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
import { QueryClient } from '@tanstack/react-query';
|
||||
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { infiniteLoaderDataQueryKey } from '/@/renderer/components/item-list/helpers/item-list-infinite-loader';
|
||||
import {
|
||||
DeletePlaylistArgs,
|
||||
LibraryItem,
|
||||
Playlist,
|
||||
PlaylistListResponse,
|
||||
} from '/@/shared/types/domain-types';
|
||||
|
||||
export interface PreviousQueryData {
|
||||
data: unknown;
|
||||
queryKey: readonly unknown[];
|
||||
}
|
||||
|
||||
export const applyDeletePlaylistOptimisticUpdates = (
|
||||
queryClient: QueryClient,
|
||||
variables: DeletePlaylistArgs,
|
||||
): PreviousQueryData[] => {
|
||||
const previousQueries: PreviousQueryData[] = [];
|
||||
const playlistId = variables.query.id;
|
||||
|
||||
// Update detail query - remove it
|
||||
const detailQueryKey = queryKeys.playlists.detail(
|
||||
variables.apiClientProps.serverId,
|
||||
playlistId,
|
||||
);
|
||||
|
||||
const detailQueries = queryClient.getQueriesData({
|
||||
exact: false,
|
||||
queryKey: detailQueryKey,
|
||||
});
|
||||
|
||||
if (detailQueries.length) {
|
||||
detailQueries.forEach(([queryKey, data]) => {
|
||||
if (data) {
|
||||
previousQueries.push({ data, queryKey });
|
||||
queryClient.setQueryData(queryKey, undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update list queries - remove the playlist from items
|
||||
const listQueryKey = queryKeys.playlists.list(variables.apiClientProps.serverId);
|
||||
|
||||
const listQueries = queryClient.getQueriesData({
|
||||
exact: false,
|
||||
queryKey: listQueryKey,
|
||||
});
|
||||
|
||||
if (listQueries.length) {
|
||||
listQueries.forEach(([queryKey, data]) => {
|
||||
if (data) {
|
||||
previousQueries.push({ data, queryKey });
|
||||
queryClient.setQueryData(queryKey, (prev: PlaylistListResponse | undefined) => {
|
||||
if (prev) {
|
||||
return {
|
||||
...prev,
|
||||
items: prev.items.filter((item: Playlist) => item.id !== playlistId),
|
||||
totalRecordCount: Math.max(
|
||||
0,
|
||||
(prev.totalRecordCount || prev.items.length) - 1,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
return prev;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update infinite loader queries - remove the playlist from data array
|
||||
const infiniteLoaderQueryKey = infiniteLoaderDataQueryKey(
|
||||
variables.apiClientProps.serverId,
|
||||
LibraryItem.PLAYLIST,
|
||||
);
|
||||
|
||||
const infiniteLoaderQueries = queryClient.getQueriesData({
|
||||
exact: false,
|
||||
queryKey: infiniteLoaderQueryKey,
|
||||
});
|
||||
|
||||
if (infiniteLoaderQueries.length) {
|
||||
infiniteLoaderQueries.forEach(([queryKey, data]) => {
|
||||
if (data) {
|
||||
previousQueries.push({ data, queryKey });
|
||||
queryClient.setQueryData(
|
||||
queryKey,
|
||||
(
|
||||
prev:
|
||||
| undefined
|
||||
| {
|
||||
data: unknown[];
|
||||
pagesLoaded: Record<string, boolean>;
|
||||
},
|
||||
) => {
|
||||
if (prev && prev.data) {
|
||||
return {
|
||||
...prev,
|
||||
data: prev.data.filter((item: any) => {
|
||||
if (!item || !item.id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return item.id !== playlistId;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return prev;
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update songList query - remove it
|
||||
const songListQueryKey = queryKeys.playlists.songList(
|
||||
variables.apiClientProps.serverId,
|
||||
playlistId,
|
||||
);
|
||||
|
||||
const songListQueries = queryClient.getQueriesData({
|
||||
exact: false,
|
||||
queryKey: songListQueryKey,
|
||||
});
|
||||
|
||||
if (songListQueries.length) {
|
||||
songListQueries.forEach(([queryKey, data]) => {
|
||||
if (data) {
|
||||
previousQueries.push({ data, queryKey });
|
||||
queryClient.setQueryData(queryKey, undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return previousQueries;
|
||||
};
|
||||
|
||||
export const restorePlaylistQueryData = (
|
||||
queryClient: QueryClient,
|
||||
previousQueries: PreviousQueryData[],
|
||||
): void => {
|
||||
previousQueries.forEach(({ data, queryKey }) => {
|
||||
queryClient.setQueryData(queryKey, data);
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user