Make ratings/favourites a bit more customizable (#2262)

* 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
This commit is contained in:
Marc Plano-Lesay
2026-07-26 22:59:17 +10:00
committed by GitHub
parent d0710f3549
commit 07ef323ccc
15 changed files with 143 additions and 69 deletions
@@ -9,7 +9,7 @@ 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 { useShowRatings } from '/@/renderer/store';
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';
@@ -35,6 +35,7 @@ interface AlbumGroupControlsProps {
export const AlbumGroupControls = ({ albumId, serverId, serverType }: AlbumGroupControlsProps) => {
const showRatingsSetting = useShowRatings();
const showFavorites = useShowFavorites();
const detailQuery = useAlbumGroupAlbum(albumId, serverId);
const setFavorite = useSetFavorite();
const setRating = useSetRating();
@@ -77,23 +78,25 @@ export const AlbumGroupControls = ({ albumId, serverId, serverType }: AlbumGroup
return (
<div className={styles.controls}>
<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"
/>
{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}