Add related genre albums to album detail
This commit is contained in:
parent
5f5c3bbb11
commit
8338aaf18d
2 changed files with 53 additions and 6 deletions
|
@ -95,6 +95,13 @@ export const queryKeys: Record<
|
||||||
|
|
||||||
return [serverId, 'albums', 'list'] as const;
|
return [serverId, 'albums', 'list'] as const;
|
||||||
},
|
},
|
||||||
|
related: (serverId: string, id: string, query?: AlbumDetailQuery) => {
|
||||||
|
if (query) {
|
||||||
|
return [serverId, 'albums', id, 'related', query] as const;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [serverId, 'albums', id, 'related'] as const;
|
||||||
|
},
|
||||||
root: (serverId: string) => [serverId, 'albums'],
|
root: (serverId: string) => [serverId, 'albums'],
|
||||||
serverRoot: (serverId: string) => [serverId, 'albums'],
|
serverRoot: (serverId: string) => [serverId, 'albums'],
|
||||||
songs: (serverId: string, query: SongListQuery) =>
|
songs: (serverId: string, query: SongListQuery) =>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
||||||
import { generatePath, useParams } from 'react-router';
|
import { generatePath, useParams } from 'react-router';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { AlbumListSort, LibraryItem, QueueSong, SortOrder } from '/@/renderer/api/types';
|
import { AlbumListSort, LibraryItem, QueueSong, SortOrder } from '/@/renderer/api/types';
|
||||||
import { Button } from '/@/renderer/components';
|
import { Button } from '/@/renderer/components';
|
||||||
import { MemoizedSwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
import { MemoizedSwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
||||||
|
@ -158,8 +159,6 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
[pagination, setPagination],
|
[pagination, setPagination],
|
||||||
);
|
);
|
||||||
|
|
||||||
const itemsPerPage = cq.isXl ? 9 : cq.isLg ? 7 : cq.isMd ? 5 : cq.isSm ? 4 : 3;
|
|
||||||
|
|
||||||
const artistQuery = useAlbumList({
|
const artistQuery = useAlbumList({
|
||||||
options: {
|
options: {
|
||||||
cacheTime: 1000 * 60,
|
cacheTime: 1000 * 60,
|
||||||
|
@ -177,14 +176,44 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
artist_id: detailQuery?.data?.albumArtists[0]?.id,
|
artist_id: detailQuery?.data?.albumArtists[0]?.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
limit: 10,
|
limit: 15,
|
||||||
sortBy: AlbumListSort.YEAR,
|
sortBy: AlbumListSort.YEAR,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: pagination.artist * itemsPerPage,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const relatedAlbumGenresRequest = {
|
||||||
|
_custom: {
|
||||||
|
jellyfin: {
|
||||||
|
GenreIds: detailQuery?.data?.genres?.[0]?.id,
|
||||||
|
},
|
||||||
|
navidrome: {
|
||||||
|
genre_id: detailQuery?.data?.genres?.[0]?.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
limit: 15,
|
||||||
|
sortBy: AlbumListSort.RANDOM,
|
||||||
|
sortOrder: SortOrder.ASC,
|
||||||
|
startIndex: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const relatedAlbumGenresQuery = useAlbumList({
|
||||||
|
options: {
|
||||||
|
cacheTime: 1000 * 60,
|
||||||
|
enabled: !!detailQuery?.data?.genres?.[0],
|
||||||
|
queryKey: queryKeys.albums.related(
|
||||||
|
server?.id || '',
|
||||||
|
albumId,
|
||||||
|
relatedAlbumGenresRequest,
|
||||||
|
),
|
||||||
|
staleTime: 1000 * 60,
|
||||||
|
},
|
||||||
|
query: relatedAlbumGenresRequest,
|
||||||
|
serverId: server?.id,
|
||||||
|
});
|
||||||
|
|
||||||
const carousels = [
|
const carousels = [
|
||||||
{
|
{
|
||||||
data: artistQuery?.data?.items.filter((a) => a.id !== detailQuery?.data?.id),
|
data: artistQuery?.data?.items.filter((a) => a.id !== detailQuery?.data?.id),
|
||||||
|
@ -195,11 +224,21 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
handleNextPage: () => handleNextPage('artist'),
|
handleNextPage: () => handleNextPage('artist'),
|
||||||
handlePreviousPage: () => handlePreviousPage('artist'),
|
handlePreviousPage: () => handlePreviousPage('artist'),
|
||||||
hasPreviousPage: pagination.artist > 0,
|
hasPreviousPage: pagination.artist > 0,
|
||||||
itemsPerPage,
|
|
||||||
},
|
},
|
||||||
title: 'More from this artist',
|
title: 'More from this artist',
|
||||||
uniqueId: 'mostPlayed',
|
uniqueId: 'mostPlayed',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
data: relatedAlbumGenresQuery?.data?.items.filter(
|
||||||
|
(a) => a.id !== detailQuery?.data?.id,
|
||||||
|
),
|
||||||
|
isHidden: !relatedAlbumGenresQuery?.data?.items.filter(
|
||||||
|
(a) => a.id !== detailQuery?.data?.id,
|
||||||
|
).length,
|
||||||
|
loading: relatedAlbumGenresQuery?.isLoading || relatedAlbumGenresQuery.isFetching,
|
||||||
|
title: `More from ${detailQuery?.data?.genres?.[0]?.name}`,
|
||||||
|
uniqueId: 'relatedGenres',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const playButtonBehavior = usePlayButtonBehavior();
|
const playButtonBehavior = usePlayButtonBehavior();
|
||||||
|
|
||||||
|
@ -359,7 +398,8 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
</Box>
|
</Box>
|
||||||
<Stack
|
<Stack
|
||||||
ref={cq.ref}
|
ref={cq.ref}
|
||||||
mt="5rem"
|
mt="3rem"
|
||||||
|
spacing="lg"
|
||||||
>
|
>
|
||||||
{cq.height || cq.width ? (
|
{cq.height || cq.width ? (
|
||||||
<>
|
<>
|
||||||
|
|
Reference in a new issue