add rating / favorite to player context and events

This commit is contained in:
jeffvli
2025-11-07 19:44:19 -08:00
parent b4558491e7
commit 9fafb4f397
6 changed files with 100 additions and 117 deletions
@@ -1,38 +1,19 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useMutation } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import isElectron from 'is-electron';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { eventEmitter } from '/@/renderer/events/event-emitter';
import { MutationHookArgs } from '/@/renderer/lib/react-query';
import { useSetAlbumListItemDataById } from '/@/renderer/store';
import { useRatingEvent } from '/@/renderer/store/event.store';
import {
Album,
AlbumArtist,
AlbumArtistDetailResponse,
AlbumDetailResponse,
AnyLibraryItems,
LibraryItem,
RatingResponse,
SetRatingArgs,
} from '/@/shared/types/domain-types';
const remote = isElectron() ? window.api.remote : null;
import { LibraryItem, RatingResponse, SetRatingArgs } from '/@/shared/types/domain-types';
export const useSetRating = (args: MutationHookArgs) => {
const { options } = args || {};
const queryClient = useQueryClient();
const setAlbumListData = useSetAlbumListItemDataById();
// const setQueueRating = useSetQueueRating();
const setRatingEvent = useRatingEvent();
return useMutation<
RatingResponse,
AxiosError,
SetRatingArgs,
{ previous: undefined | { items: AnyLibraryItems } }
{ previous: undefined | { id: string[]; rating: number; type: LibraryItem } }
>({
mutationFn: (args) => {
return api.controller.setRating({
@@ -40,92 +21,13 @@ export const useSetRating = (args: MutationHookArgs) => {
apiClientProps: { serverId: args.apiClientProps.serverId },
});
},
onError: (_error, _variables, context) => {
for (const item of context?.previous?.items || []) {
switch (item.itemType) {
case LibraryItem.ALBUM:
setAlbumListData(item.id, { userRating: item.userRating });
break;
case LibraryItem.SONG:
// setQueueRating([item.id], item.userRating);
setRatingEvent([item.id], item.userRating);
break;
}
}
},
onMutate: (variables) => {
eventEmitter.emit('USER_RATING', {
id: variables.query.item.map((item) => item.id),
itemType: variables.query.item[0].itemType,
rating: variables.query.rating,
});
const songIds: string[] = [];
for (const item of variables.query.item) {
switch (item.itemType) {
case LibraryItem.ALBUM:
setAlbumListData(item.id, { userRating: variables.query.rating });
break;
case LibraryItem.SONG:
songIds.push(item.id);
break;
}
}
if (songIds.length > 0) {
// setQueueRating(songIds, variables.query.rating);
setRatingEvent(songIds, variables.query.rating);
}
if (remote) {
remote.updateRating(
variables.query.rating,
variables.query.item[0]._serverId,
songIds,
);
}
return { previous: { items: variables.query.item } };
},
onSuccess: (_data, variables) => {
// We only need to set if we're already on the album detail page
const isAlbumDetailPage =
variables.query.item.length === 1 &&
variables.query.item[0].itemType === LibraryItem.ALBUM;
if (isAlbumDetailPage) {
const { id: albumId, _serverId } = variables.query.item[0] as Album;
const queryKey = queryKeys.albums.detail(_serverId || '', { id: albumId });
const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey);
if (previous) {
queryClient.setQueryData<AlbumDetailResponse>(queryKey, {
...previous,
userRating: variables.query.rating,
});
}
}
// We only need to set if we're already on the album artist detail page
const isAlbumArtistDetailPage =
variables.query.item.length === 1 &&
variables.query.item[0].itemType === LibraryItem.ALBUM_ARTIST;
if (isAlbumArtistDetailPage) {
const { id: albumArtistId, serverId } = variables.query.item[0] as AlbumArtist;
const queryKey = queryKeys.albumArtists.detail(serverId || '', {
id: albumArtistId,
});
const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey);
if (previous) {
queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, {
...previous,
userRating: variables.query.rating,
});
}
}
eventEmitter.emit('USER_RATING', {
id: variables.query.id,
itemType: variables.query.type,
rating: variables.query.rating,
serverId: variables.apiClientProps.serverId,
});
},
...options,
});