mirror of
https://github.com/jeffvli/feishin.git
synced 2026-08-08 05:12:57 +02:00
07ef323ccc
* Replace show ratings toggle with favorite/rating controls setting Swap `genera.showRatings` (previously a simple bool) for a `favoriteRatingControls` enum, exposed via derived `useShowRatings` / `useShowFavorites` hooks. Settings switch becomes a select, with a migration to a new v32 schema mapping the old boolean forward with no user change. * Gate favorite controls on `favoriteRatingControls` setting Hide the playerbar and mobile fullscreen favorite buttons and the context-menu favorite action when the setting excludes favorites, mirroring how ratings are already gated. * Gate favorite controls on item cards and detail list Drill a `showFavorite` flag through the item-card tree (mirroring `showRating`), and gate the card/detail-list favorite badges and hover buttons on the `favoriteRatingControls` setting. * Gate favorite controls in detail headers and album group controls * Keep the original `showRatings` switch and add a `showFavorites` * Gate album header favorite hander at definition
112 lines
4.2 KiB
TypeScript
112 lines
4.2 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { useCallback } from 'react';
|
|
|
|
import styles from './album-group-controls.module.css';
|
|
|
|
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
|
|
import { useSetFavorite } from '/@/renderer/features/shared/hooks/use-set-favorite';
|
|
import { useSetRating } from '/@/renderer/features/shared/hooks/use-set-rating';
|
|
import { useIsMutatingCreateFavorite } from '/@/renderer/features/shared/mutations/create-favorite-mutation';
|
|
import { useIsMutatingDeleteFavorite } from '/@/renderer/features/shared/mutations/delete-favorite-mutation';
|
|
import { useIsMutatingRating } from '/@/renderer/features/shared/mutations/set-rating-mutation';
|
|
import { useShowFavorites, useShowRatings } from '/@/renderer/store';
|
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
|
import { Rating } from '/@/shared/components/rating/rating';
|
|
import { LibraryItem, ServerType } from '/@/shared/types/domain-types';
|
|
|
|
const isRatingSupported = (serverType: ServerType | undefined) =>
|
|
serverType === ServerType.NAVIDROME || serverType === ServerType.SUBSONIC;
|
|
|
|
const useAlbumGroupAlbum = (albumId: string | undefined, serverId: string | undefined) => {
|
|
const enabled = !!albumId && !!serverId && !albumId.startsWith('dummy/');
|
|
|
|
return useQuery({
|
|
...albumQueries.detail({ query: { id: albumId! }, serverId: serverId! }),
|
|
enabled,
|
|
staleTime: 5 * 60 * 1000,
|
|
});
|
|
};
|
|
|
|
interface AlbumGroupControlsProps {
|
|
albumId: string | undefined;
|
|
serverId: string | undefined;
|
|
serverType: ServerType | undefined;
|
|
}
|
|
|
|
export const AlbumGroupControls = ({ albumId, serverId, serverType }: AlbumGroupControlsProps) => {
|
|
const showRatingsSetting = useShowRatings();
|
|
const showFavorites = useShowFavorites();
|
|
const detailQuery = useAlbumGroupAlbum(albumId, serverId);
|
|
const setFavorite = useSetFavorite();
|
|
const setRating = useSetRating();
|
|
|
|
const isMutatingCreateFavorite = useIsMutatingCreateFavorite();
|
|
const isMutatingDeleteFavorite = useIsMutatingDeleteFavorite();
|
|
const isMutatingFavorite = isMutatingCreateFavorite || isMutatingDeleteFavorite;
|
|
const isMutatingRating = useIsMutatingRating();
|
|
|
|
const album = detailQuery.data;
|
|
const showRating = showRatingsSetting && isRatingSupported(serverType ?? album?._serverType);
|
|
|
|
const handleFavorite = useCallback(
|
|
(event: React.MouseEvent<HTMLButtonElement>) => {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
if (!album) return;
|
|
|
|
setFavorite(album._serverId, [album.id], LibraryItem.ALBUM, !album.userFavorite);
|
|
},
|
|
[album, setFavorite],
|
|
);
|
|
|
|
const handleRating = useCallback(
|
|
(rating: number) => {
|
|
if (!album) return;
|
|
|
|
if (album.userRating === rating) {
|
|
return setRating(album._serverId, [album.id], LibraryItem.ALBUM, 0);
|
|
}
|
|
|
|
return setRating(album._serverId, [album.id], LibraryItem.ALBUM, rating);
|
|
},
|
|
[album, setRating],
|
|
);
|
|
|
|
if (!album) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<div className={styles.controls}>
|
|
{showFavorites && (
|
|
<ActionIcon
|
|
className={styles.favorite}
|
|
disabled={isMutatingFavorite}
|
|
icon="favorite"
|
|
iconProps={{
|
|
color: album.userFavorite ? 'primary' : 'muted',
|
|
fill: album.userFavorite ? 'primary' : undefined,
|
|
size: 'xs',
|
|
}}
|
|
onClick={handleFavorite}
|
|
onDoubleClick={(event) => {
|
|
event.stopPropagation();
|
|
event.preventDefault();
|
|
}}
|
|
size="xs"
|
|
variant="transparent"
|
|
/>
|
|
)}
|
|
{showRating && (
|
|
<Rating
|
|
className={styles.rating}
|
|
onChange={handleRating}
|
|
readOnly={isMutatingRating}
|
|
size="xs"
|
|
value={album.userRating || 0}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|