mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
add missing releases from musicbrainz to artist page
This commit is contained in:
@@ -20,6 +20,11 @@
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.container.external {
|
||||
opacity: 0.6;
|
||||
filter: grayscale(0.3) saturate(0.7);
|
||||
}
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
@@ -65,6 +70,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.image-container.no-hover-overlay {
|
||||
&:hover {
|
||||
&::before {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-badge {
|
||||
position: absolute;
|
||||
top: -50px;
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
Genre,
|
||||
LibraryItem,
|
||||
Playlist,
|
||||
ServerType,
|
||||
Song,
|
||||
} from '/@/shared/types/domain-types';
|
||||
import { DragOperation, DragTarget } from '/@/shared/types/drag-and-drop';
|
||||
@@ -339,9 +340,11 @@ const CompactItemCard = ({
|
||||
? (data as { userRating: null | number }).userRating
|
||||
: null;
|
||||
const hasRating = showRating && userRating !== null && userRating > 0;
|
||||
const isExternal = data._serverType === ServerType.EXTERNAL;
|
||||
|
||||
const imageContainerClassName = clsx(styles.imageContainer, {
|
||||
[styles.isRound]: isRound,
|
||||
[styles.noHoverOverlay]: isExternal,
|
||||
});
|
||||
|
||||
const imageContainerContent = (
|
||||
@@ -374,7 +377,7 @@ const CompactItemCard = ({
|
||||
{isFavorite && <div className={styles.favoriteBadge} />}
|
||||
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
|
||||
<AnimatePresence>
|
||||
{withControls && showControls && data && (
|
||||
{withControls && showControls && data && !isExternal && (
|
||||
<ItemCardControls
|
||||
controls={controls}
|
||||
enableExpansion={enableExpansion}
|
||||
@@ -409,6 +412,7 @@ const CompactItemCard = ({
|
||||
<div
|
||||
className={clsx(styles.container, styles.compact, {
|
||||
[styles.dragging]: isDragging,
|
||||
[styles.external]: isExternal,
|
||||
[styles.selected]: isSelected,
|
||||
})}
|
||||
ref={ref}
|
||||
@@ -570,10 +574,6 @@ const DefaultItemCard = ({
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const imageContainerClassName = clsx(styles.imageContainer, {
|
||||
[styles.isRound]: isRound,
|
||||
});
|
||||
|
||||
const isFavorite =
|
||||
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
|
||||
const userRating =
|
||||
@@ -582,6 +582,12 @@ const DefaultItemCard = ({
|
||||
? (data as { userRating: null | number }).userRating
|
||||
: null;
|
||||
const hasRating = showRating && userRating !== null && userRating > 0;
|
||||
const isExternal = data._serverType === ServerType.EXTERNAL;
|
||||
|
||||
const imageContainerClassName = clsx(styles.imageContainer, {
|
||||
[styles.isRound]: isRound,
|
||||
[styles.noHoverOverlay]: isExternal,
|
||||
});
|
||||
|
||||
const imageContainerContent = (
|
||||
<>
|
||||
@@ -611,7 +617,7 @@ const DefaultItemCard = ({
|
||||
{isFavorite && <div className={styles.favoriteBadge} />}
|
||||
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
|
||||
<AnimatePresence>
|
||||
{withControls && showControls && (
|
||||
{withControls && showControls && !isExternal && (
|
||||
<ItemCardControls
|
||||
controls={controls}
|
||||
enableExpansion={enableExpansion}
|
||||
@@ -628,6 +634,7 @@ const DefaultItemCard = ({
|
||||
return (
|
||||
<div
|
||||
className={clsx(styles.container, {
|
||||
[styles.external]: isExternal,
|
||||
[styles.selected]: isSelected,
|
||||
})}
|
||||
>
|
||||
@@ -870,10 +877,6 @@ const PosterItemCard = ({
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
const imageContainerClassName = clsx(styles.imageContainer, {
|
||||
[styles.isRound]: isRound,
|
||||
});
|
||||
|
||||
const isFavorite =
|
||||
'userFavorite' in data && (data as { userFavorite: boolean }).userFavorite;
|
||||
const userRating =
|
||||
@@ -882,6 +885,12 @@ const PosterItemCard = ({
|
||||
? (data as { userRating: null | number }).userRating
|
||||
: null;
|
||||
const hasRating = showRating && userRating !== null && userRating > 0;
|
||||
const isExternal = data._serverType === ServerType.EXTERNAL;
|
||||
|
||||
const imageContainerClassName = clsx(styles.imageContainer, {
|
||||
[styles.isRound]: isRound,
|
||||
[styles.noHoverOverlay]: isExternal,
|
||||
});
|
||||
|
||||
const imageContainerContent = (
|
||||
<>
|
||||
@@ -911,7 +920,7 @@ const PosterItemCard = ({
|
||||
{isFavorite && <div className={styles.favoriteBadge} />}
|
||||
{hasRating && <div className={styles.ratingBadge}>{userRating}</div>}
|
||||
<AnimatePresence>
|
||||
{withControls && showControls && data && (
|
||||
{withControls && showControls && data && !isExternal && (
|
||||
<ItemCardControls
|
||||
controls={controls}
|
||||
enableExpansion={enableExpansion}
|
||||
@@ -930,6 +939,7 @@ const PosterItemCard = ({
|
||||
<div
|
||||
className={clsx(styles.container, styles.poster, {
|
||||
[styles.dragging]: isDragging,
|
||||
[styles.external]: isExternal,
|
||||
[styles.selected]: isSelected,
|
||||
})}
|
||||
ref={ref}
|
||||
|
||||
@@ -24,6 +24,7 @@ import { ItemTableListColumn } from '/@/renderer/components/item-list/item-table
|
||||
import { ItemControls } from '/@/renderer/components/item-list/types';
|
||||
import { artistsQueries } from '/@/renderer/features/artists/api/artists-api';
|
||||
import { AlbumArtistGridCarousel } from '/@/renderer/features/artists/components/album-artist-grid-carousel';
|
||||
import { musicbrainzQueries } from '/@/renderer/features/musicbrainz/api/musicbrainz-api';
|
||||
import { useIsPlayerFetching, usePlayer } from '/@/renderer/features/player/context/player-context';
|
||||
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
||||
import {
|
||||
@@ -1364,16 +1365,44 @@ const ArtistAlbums = ({ albumsQuery }: ArtistAlbumsProps) => {
|
||||
albumArtistId?: string;
|
||||
artistId?: string;
|
||||
};
|
||||
|
||||
const serverId = useCurrentServerId();
|
||||
const routeId = (artistId || albumArtistId) as string;
|
||||
|
||||
const detailQuery = useSuspenseQuery(
|
||||
artistsQueries.albumArtistDetail({
|
||||
query: { id: routeId },
|
||||
serverId: serverId,
|
||||
}),
|
||||
);
|
||||
|
||||
const musicbrainzArtistQuery = useQuery({
|
||||
...musicbrainzQueries.artist({ mbzArtistId: detailQuery.data?.mbz as string }),
|
||||
meta: {
|
||||
albumArtist: detailQuery.data,
|
||||
},
|
||||
});
|
||||
|
||||
const musicbrainzAlbums = useMemo(() => {
|
||||
return musicbrainzArtistQuery.data || [];
|
||||
}, [musicbrainzArtistQuery.data]);
|
||||
|
||||
const rows = useGridRows(LibraryItem.ALBUM, ItemListKey.ALBUM);
|
||||
const controls = useDefaultItemListControls();
|
||||
|
||||
const filteredAndSortedAlbums = useMemo(() => {
|
||||
const albums = albumsQuery.data?.items || [];
|
||||
const existingReleaseIds = new Set(
|
||||
albumsQuery.data?.items?.map((item) => item.mbzId) || [],
|
||||
);
|
||||
|
||||
const newMusicbrainzAlbums = musicbrainzAlbums.filter(
|
||||
(album) => !existingReleaseIds.has(album.mbzId),
|
||||
);
|
||||
|
||||
const albums = [...(albumsQuery.data?.items || []), ...newMusicbrainzAlbums];
|
||||
const searched = searchLibraryItems(albums, debouncedSearchTerm, LibraryItem.ALBUM);
|
||||
return sortAlbumList(searched, sortBy, sortOrder);
|
||||
}, [albumsQuery.data?.items, debouncedSearchTerm, sortBy, sortOrder]);
|
||||
}, [albumsQuery.data?.items, debouncedSearchTerm, musicbrainzAlbums, sortBy, sortOrder]);
|
||||
|
||||
const albumsByReleaseType = useMemo(() => {
|
||||
return groupAlbumsByReleaseType(filteredAndSortedAlbums, routeId, groupingType);
|
||||
|
||||
Reference in New Issue
Block a user