Add new swiper carousels to pages
This commit is contained in:
parent
58d912065b
commit
48ef7a987f
3 changed files with 117 additions and 178 deletions
|
@ -1,5 +1,5 @@
|
||||||
import { MutableRefObject, useCallback, useMemo } from 'react';
|
import { MutableRefObject, useCallback, useMemo } from 'react';
|
||||||
import { Button, GridCarousel, Text, TextTitle } from '/@/renderer/components';
|
import { Button, Text } from '/@/renderer/components';
|
||||||
import { ColDef, RowDoubleClickedEvent, RowHeightParams, RowNode } from '@ag-grid-community/core';
|
import { ColDef, RowDoubleClickedEvent, RowHeightParams, RowNode } from '@ag-grid-community/core';
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { Box, Group, Stack } from '@mantine/core';
|
import { Box, Group, Stack } from '@mantine/core';
|
||||||
|
@ -31,6 +31,7 @@ import {
|
||||||
useFixedTableHeader,
|
useFixedTableHeader,
|
||||||
VirtualTable,
|
VirtualTable,
|
||||||
} from '/@/renderer/components/virtual-table';
|
} from '/@/renderer/components/virtual-table';
|
||||||
|
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
||||||
|
|
||||||
const isFullWidthRow = (node: RowNode) => {
|
const isFullWidthRow = (node: RowNode) => {
|
||||||
return node.id?.includes('disc-');
|
return node.id?.includes('disc-');
|
||||||
|
@ -174,13 +175,14 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
|
||||||
query: {
|
query: {
|
||||||
_custom: {
|
_custom: {
|
||||||
jellyfin: {
|
jellyfin: {
|
||||||
albumArtistIds: detailQuery?.data?.albumArtists[0]?.id,
|
AlbumArtistIds: detailQuery?.data?.albumArtists[0]?.id,
|
||||||
|
ExcludeItemIds: detailQuery?.data?.id,
|
||||||
},
|
},
|
||||||
navidrome: {
|
navidrome: {
|
||||||
artist_id: detailQuery?.data?.albumArtists[0]?.id,
|
artist_id: detailQuery?.data?.albumArtists[0]?.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
limit: itemsPerPage,
|
limit: 10,
|
||||||
sortBy: AlbumListSort.YEAR,
|
sortBy: AlbumListSort.YEAR,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: pagination.artist * itemsPerPage,
|
startIndex: pagination.artist * itemsPerPage,
|
||||||
|
@ -198,14 +200,7 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
|
||||||
hasPreviousPage: pagination.artist > 0,
|
hasPreviousPage: pagination.artist > 0,
|
||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
title: (
|
title: 'More from this artist',
|
||||||
<TextTitle
|
|
||||||
order={2}
|
|
||||||
weight={700}
|
|
||||||
>
|
|
||||||
More from this artist
|
|
||||||
</TextTitle>
|
|
||||||
),
|
|
||||||
uniqueId: 'mostPlayed',
|
uniqueId: 'mostPlayed',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -325,7 +320,10 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
<Box ref={tableContainerRef}>
|
<Box
|
||||||
|
ref={tableContainerRef}
|
||||||
|
style={{ minHeight: '300px' }}
|
||||||
|
>
|
||||||
<VirtualTable
|
<VirtualTable
|
||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
autoFitColumns
|
autoFitColumns
|
||||||
|
@ -369,36 +367,45 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
|
||||||
ref={cq.ref}
|
ref={cq.ref}
|
||||||
mt="5rem"
|
mt="5rem"
|
||||||
>
|
>
|
||||||
{carousels.map((carousel, index) => (
|
<>
|
||||||
<GridCarousel
|
{cq.height || cq.width ? (
|
||||||
key={`carousel-${carousel.uniqueId}-${index}`}
|
<>
|
||||||
cardRows={[
|
{carousels.map((carousel, index) => (
|
||||||
{
|
<SwiperGridCarousel
|
||||||
property: 'name',
|
key={`carousel-${carousel.uniqueId}-${index}`}
|
||||||
route: {
|
cardRows={[
|
||||||
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
|
{
|
||||||
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }],
|
property: 'name',
|
||||||
},
|
route: {
|
||||||
},
|
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
|
||||||
{
|
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }],
|
||||||
arrayProperty: 'name',
|
},
|
||||||
property: 'albumArtists',
|
},
|
||||||
route: {
|
{
|
||||||
route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL,
|
arrayProperty: 'name',
|
||||||
slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }],
|
property: 'albumArtists',
|
||||||
},
|
route: {
|
||||||
},
|
route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL,
|
||||||
]}
|
slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }],
|
||||||
containerWidth={cq.width}
|
},
|
||||||
data={carousel.data}
|
},
|
||||||
itemType={LibraryItem.ALBUM}
|
]}
|
||||||
loading={carousel.loading}
|
data={carousel.data}
|
||||||
pagination={carousel.pagination}
|
isLoading={carousel.loading}
|
||||||
uniqueId={carousel.uniqueId}
|
itemType={LibraryItem.ALBUM}
|
||||||
>
|
route={{
|
||||||
<GridCarousel.Title>{carousel.title}</GridCarousel.Title>
|
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
|
||||||
</GridCarousel>
|
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }],
|
||||||
))}
|
}}
|
||||||
|
title={{
|
||||||
|
label: carousel.title,
|
||||||
|
}}
|
||||||
|
uniqueId={carousel.uniqueId}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</>
|
||||||
</Stack>
|
</Stack>
|
||||||
</ContentContainer>
|
</ContentContainer>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { Button, GridCarousel, Text, TextTitle } from '/@/renderer/components';
|
import { Button, Text, TextTitle } from '/@/renderer/components';
|
||||||
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||||
import { Box, Group, Stack } from '@mantine/core';
|
import { Box, Group, Stack } from '@mantine/core';
|
||||||
import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
||||||
|
@ -14,7 +14,7 @@ import {
|
||||||
useHandleGeneralContextMenu,
|
useHandleGeneralContextMenu,
|
||||||
useHandleTableContextMenu,
|
useHandleTableContextMenu,
|
||||||
} from '/@/renderer/features/context-menu';
|
} from '/@/renderer/features/context-menu';
|
||||||
import { Play, TableColumn } from '/@/renderer/types';
|
import { CardRow, Play, TableColumn } from '/@/renderer/types';
|
||||||
import {
|
import {
|
||||||
ARTIST_CONTEXT_MENU_ITEMS,
|
ARTIST_CONTEXT_MENU_ITEMS,
|
||||||
SONG_CONTEXT_MENU_ITEMS,
|
SONG_CONTEXT_MENU_ITEMS,
|
||||||
|
@ -22,6 +22,8 @@ import {
|
||||||
import { PlayButton, useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared';
|
import { PlayButton, useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared';
|
||||||
import { useAlbumList } from '/@/renderer/features/albums/queries/album-list-query';
|
import { useAlbumList } from '/@/renderer/features/albums/queries/album-list-query';
|
||||||
import {
|
import {
|
||||||
|
Album,
|
||||||
|
AlbumArtist,
|
||||||
AlbumListSort,
|
AlbumListSort,
|
||||||
LibraryItem,
|
LibraryItem,
|
||||||
QueueSong,
|
QueueSong,
|
||||||
|
@ -32,6 +34,7 @@ import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||||
import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album-artist-detail-query';
|
import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album-artist-detail-query';
|
||||||
import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query';
|
import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query';
|
||||||
import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table';
|
import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table';
|
||||||
|
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
||||||
|
|
||||||
const ContentContainer = styled.div`
|
const ContentContainer = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -55,7 +58,6 @@ export const AlbumArtistDetailContent = () => {
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const itemsPerPage = cq.isXl ? 9 : cq.isLg ? 7 : cq.isMd ? 5 : cq.isSm ? 4 : 3;
|
|
||||||
|
|
||||||
const detailQuery = useAlbumArtistDetail({ query: { id: albumArtistId }, serverId: server?.id });
|
const detailQuery = useAlbumArtistDetail({ query: { id: albumArtistId }, serverId: server?.id });
|
||||||
|
|
||||||
|
@ -77,7 +79,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
query: {
|
query: {
|
||||||
_custom: {
|
_custom: {
|
||||||
jellyfin: {
|
jellyfin: {
|
||||||
...(server?.type === ServerType.JELLYFIN ? { artistIds: albumArtistId } : undefined),
|
...(server?.type === ServerType.JELLYFIN ? { ArtistIds: albumArtistId } : undefined),
|
||||||
},
|
},
|
||||||
navidrome: {
|
navidrome: {
|
||||||
...(server?.type === ServerType.NAVIDROME
|
...(server?.type === ServerType.NAVIDROME
|
||||||
|
@ -85,7 +87,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
: undefined),
|
: undefined),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
limit: itemsPerPage,
|
// limit: 10,
|
||||||
sortBy: AlbumListSort.RELEASE_DATE,
|
sortBy: AlbumListSort.RELEASE_DATE,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
|
@ -98,7 +100,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
_custom: {
|
_custom: {
|
||||||
jellyfin: {
|
jellyfin: {
|
||||||
...(server?.type === ServerType.JELLYFIN
|
...(server?.type === ServerType.JELLYFIN
|
||||||
? { contributingArtistIds: albumArtistId }
|
? { ContributingArtistIds: albumArtistId }
|
||||||
: undefined),
|
: undefined),
|
||||||
},
|
},
|
||||||
navidrome: {
|
navidrome: {
|
||||||
|
@ -107,7 +109,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
: undefined),
|
: undefined),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
limit: itemsPerPage,
|
// limit: 10,
|
||||||
sortBy: AlbumListSort.RELEASE_DATE,
|
sortBy: AlbumListSort.RELEASE_DATE,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
|
@ -140,7 +142,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
const cardRows = {
|
const cardRows: Record<string, CardRow<Album>[] | CardRow<AlbumArtist>[]> = {
|
||||||
album: [
|
album: [
|
||||||
{
|
{
|
||||||
property: 'name',
|
property: 'name',
|
||||||
|
@ -169,17 +171,25 @@ export const AlbumArtistDetailContent = () => {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cardRoutes = {
|
||||||
|
album: {
|
||||||
|
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
|
||||||
|
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }],
|
||||||
|
},
|
||||||
|
albumArtist: {
|
||||||
|
route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL,
|
||||||
|
slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const carousels = [
|
const carousels = [
|
||||||
{
|
{
|
||||||
data: recentAlbumsQuery?.data?.items,
|
data: recentAlbumsQuery?.data?.items,
|
||||||
isHidden: !recentAlbumsQuery?.data?.items?.length,
|
isHidden: !recentAlbumsQuery?.data?.items?.length,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
loading: recentAlbumsQuery?.isLoading || recentAlbumsQuery.isFetching,
|
loading: recentAlbumsQuery?.isLoading || recentAlbumsQuery.isFetching,
|
||||||
pagination: {
|
|
||||||
itemsPerPage,
|
|
||||||
},
|
|
||||||
title: (
|
title: (
|
||||||
<>
|
<Group align="flex-end">
|
||||||
<TextTitle
|
<TextTitle
|
||||||
order={2}
|
order={2}
|
||||||
weight={700}
|
weight={700}
|
||||||
|
@ -195,7 +205,7 @@ export const AlbumArtistDetailContent = () => {
|
||||||
>
|
>
|
||||||
View discography
|
View discography
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</Group>
|
||||||
),
|
),
|
||||||
uniqueId: 'recentReleases',
|
uniqueId: 'recentReleases',
|
||||||
},
|
},
|
||||||
|
@ -204,9 +214,6 @@ export const AlbumArtistDetailContent = () => {
|
||||||
isHidden: !compilationAlbumsQuery?.data?.items?.length,
|
isHidden: !compilationAlbumsQuery?.data?.items?.length,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
loading: compilationAlbumsQuery?.isLoading || compilationAlbumsQuery.isFetching,
|
loading: compilationAlbumsQuery?.isLoading || compilationAlbumsQuery.isFetching,
|
||||||
pagination: {
|
|
||||||
itemsPerPage,
|
|
||||||
},
|
|
||||||
title: (
|
title: (
|
||||||
<TextTitle
|
<TextTitle
|
||||||
order={2}
|
order={2}
|
||||||
|
@ -218,13 +225,10 @@ export const AlbumArtistDetailContent = () => {
|
||||||
uniqueId: 'compilationAlbums',
|
uniqueId: 'compilationAlbums',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: detailQuery?.data?.similarArtists?.slice(0, itemsPerPage),
|
data: detailQuery?.data?.similarArtists || [],
|
||||||
isHidden: !detailQuery?.data?.similarArtists,
|
isHidden: !detailQuery?.data?.similarArtists,
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
loading: detailQuery?.isLoading || detailQuery.isFetching,
|
loading: detailQuery?.isLoading || detailQuery.isFetching,
|
||||||
pagination: {
|
|
||||||
itemsPerPage,
|
|
||||||
},
|
|
||||||
title: (
|
title: (
|
||||||
<TextTitle
|
<TextTitle
|
||||||
order={2}
|
order={2}
|
||||||
|
@ -446,18 +450,23 @@ export const AlbumArtistDetailContent = () => {
|
||||||
{carousels
|
{carousels
|
||||||
.filter((c) => !c.isHidden)
|
.filter((c) => !c.isHidden)
|
||||||
.map((carousel) => (
|
.map((carousel) => (
|
||||||
<GridCarousel
|
<SwiperGridCarousel
|
||||||
key={`carousel-${carousel.uniqueId}`}
|
key={`carousel-${carousel.uniqueId}`}
|
||||||
cardRows={cardRows[carousel.itemType as keyof typeof cardRows]}
|
cardRows={cardRows[carousel.itemType as keyof typeof cardRows]}
|
||||||
containerWidth={cq.width}
|
|
||||||
data={carousel.data}
|
data={carousel.data}
|
||||||
|
isLoading={carousel.loading}
|
||||||
itemType={carousel.itemType}
|
itemType={carousel.itemType}
|
||||||
loading={carousel.loading}
|
route={cardRoutes[carousel.itemType as keyof typeof cardRoutes]}
|
||||||
pagination={carousel.pagination}
|
swiperProps={{
|
||||||
|
grid: {
|
||||||
|
rows: 2,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
title={{
|
||||||
|
label: carousel.title,
|
||||||
|
}}
|
||||||
uniqueId={carousel.uniqueId}
|
uniqueId={carousel.uniqueId}
|
||||||
>
|
/>
|
||||||
<GridCarousel.Title>{carousel.title}</GridCarousel.Title>
|
|
||||||
</GridCarousel>
|
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
@ -1,27 +1,22 @@
|
||||||
import { useCallback, useMemo, useRef } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
import { Box, Stack } from '@mantine/core';
|
import { Box, Stack } from '@mantine/core';
|
||||||
import { useSetState } from '@mantine/hooks';
|
|
||||||
import { AlbumListSort, LibraryItem, ServerType, SortOrder } from '/@/renderer/api/types';
|
import { AlbumListSort, LibraryItem, ServerType, SortOrder } from '/@/renderer/api/types';
|
||||||
import { TextTitle, FeatureCarousel, GridCarousel, NativeScrollArea } from '/@/renderer/components';
|
import { FeatureCarousel, NativeScrollArea } from '/@/renderer/components';
|
||||||
import { useAlbumList } from '/@/renderer/features/albums';
|
import { useAlbumList } from '/@/renderer/features/albums';
|
||||||
import { useRecentlyPlayed } from '/@/renderer/features/home/queries/recently-played-query';
|
import { useRecentlyPlayed } from '/@/renderer/features/home/queries/recently-played-query';
|
||||||
import { AnimatedPage, LibraryHeaderBar } from '/@/renderer/features/shared';
|
import { AnimatedPage, LibraryHeaderBar } from '/@/renderer/features/shared';
|
||||||
import { useContainerQuery } from '/@/renderer/hooks';
|
import { useContainerQuery } from '/@/renderer/hooks';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer, useWindowSettings } from '/@/renderer/store';
|
||||||
|
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
||||||
|
import { Platform } from '/@/renderer/types';
|
||||||
|
|
||||||
const HomeRoute = () => {
|
const HomeRoute = () => {
|
||||||
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
const itemsPerPage = cq.isXl ? 9 : cq.isLg ? 7 : cq.isMd ? 5 : cq.isSm ? 4 : 3;
|
const itemsPerPage = 25;
|
||||||
|
const { windowBarStyle } = useWindowSettings();
|
||||||
const [pagination, setPagination] = useSetState({
|
|
||||||
mostPlayed: 0,
|
|
||||||
random: 0,
|
|
||||||
recentlyAdded: 0,
|
|
||||||
recentlyPlayed: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const feature = useAlbumList({
|
const feature = useAlbumList({
|
||||||
options: {
|
options: {
|
||||||
|
@ -43,154 +38,85 @@ const HomeRoute = () => {
|
||||||
|
|
||||||
const random = useAlbumList({
|
const random = useAlbumList({
|
||||||
options: {
|
options: {
|
||||||
cacheTime: 1000 * 60,
|
staleTime: 1000 * 60 * 5,
|
||||||
keepPreviousData: true,
|
|
||||||
staleTime: 1000 * 60,
|
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RANDOM,
|
sortBy: AlbumListSort.RANDOM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: SortOrder.ASC,
|
||||||
startIndex: pagination.random * itemsPerPage,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const recentlyPlayed = useRecentlyPlayed({
|
const recentlyPlayed = useRecentlyPlayed({
|
||||||
options: {
|
options: {
|
||||||
keepPreviousData: true,
|
|
||||||
staleTime: 0,
|
staleTime: 0,
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: pagination.recentlyPlayed * itemsPerPage,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const recentlyAdded = useAlbumList({
|
const recentlyAdded = useAlbumList({
|
||||||
options: {
|
|
||||||
keepPreviousData: true,
|
|
||||||
staleTime: 1000 * 60,
|
|
||||||
},
|
|
||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: pagination.recentlyAdded * itemsPerPage,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mostPlayed = useAlbumList({
|
const mostPlayed = useAlbumList({
|
||||||
options: {
|
options: {
|
||||||
keepPreviousData: true,
|
staleTime: 1000 * 60 * 5,
|
||||||
staleTime: 1000 * 60 * 60,
|
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.PLAY_COUNT,
|
sortBy: AlbumListSort.PLAY_COUNT,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: SortOrder.DESC,
|
||||||
startIndex: pagination.mostPlayed * itemsPerPage,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleNextPage = useCallback(
|
|
||||||
(key: 'mostPlayed' | 'random' | 'recentlyAdded' | 'recentlyPlayed') => {
|
|
||||||
setPagination({
|
|
||||||
[key]: pagination[key as keyof typeof pagination] + 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[pagination, setPagination],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handlePreviousPage = useCallback(
|
|
||||||
(key: 'mostPlayed' | 'random' | 'recentlyAdded' | 'recentlyPlayed') => {
|
|
||||||
setPagination({
|
|
||||||
[key]: pagination[key as keyof typeof pagination] - 1,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[pagination, setPagination],
|
|
||||||
);
|
|
||||||
|
|
||||||
const carousels = [
|
const carousels = [
|
||||||
{
|
{
|
||||||
data: random?.data?.items,
|
data: random?.data?.items,
|
||||||
loading: random?.isLoading || random.isFetching,
|
loading: random?.isLoading,
|
||||||
pagination: {
|
title: 'Explore from your library',
|
||||||
handleNextPage: () => handleNextPage('random'),
|
|
||||||
handlePreviousPage: () => handlePreviousPage('random'),
|
|
||||||
hasPreviousPage: pagination.random > 0,
|
|
||||||
itemsPerPage,
|
|
||||||
},
|
|
||||||
title: (
|
|
||||||
<TextTitle
|
|
||||||
order={2}
|
|
||||||
weight={700}
|
|
||||||
>
|
|
||||||
Explore from your library
|
|
||||||
</TextTitle>
|
|
||||||
),
|
|
||||||
uniqueId: 'random',
|
uniqueId: 'random',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: recentlyPlayed?.data?.items,
|
data: recentlyPlayed?.data?.items,
|
||||||
loading: recentlyPlayed?.isLoading || recentlyPlayed.isFetching,
|
loading: recentlyPlayed?.isLoading,
|
||||||
pagination: {
|
pagination: {
|
||||||
handleNextPage: () => handleNextPage('recentlyPlayed'),
|
|
||||||
handlePreviousPage: () => handlePreviousPage('recentlyPlayed'),
|
|
||||||
hasPreviousPage: pagination.recentlyPlayed > 0,
|
|
||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
title: (
|
title: 'Recently played',
|
||||||
<TextTitle
|
|
||||||
order={2}
|
|
||||||
weight={700}
|
|
||||||
>
|
|
||||||
Recently played
|
|
||||||
</TextTitle>
|
|
||||||
),
|
|
||||||
uniqueId: 'recentlyPlayed',
|
uniqueId: 'recentlyPlayed',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: recentlyAdded?.data?.items,
|
data: recentlyAdded?.data?.items,
|
||||||
loading: recentlyAdded?.isLoading || recentlyAdded.isFetching,
|
loading: recentlyAdded?.isLoading,
|
||||||
pagination: {
|
pagination: {
|
||||||
handleNextPage: () => handleNextPage('recentlyAdded'),
|
|
||||||
handlePreviousPage: () => handlePreviousPage('recentlyAdded'),
|
|
||||||
hasPreviousPage: pagination.recentlyAdded > 0,
|
|
||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
title: (
|
title: 'Newly added releases',
|
||||||
<TextTitle
|
|
||||||
order={2}
|
|
||||||
weight={700}
|
|
||||||
>
|
|
||||||
Newly added releases
|
|
||||||
</TextTitle>
|
|
||||||
),
|
|
||||||
uniqueId: 'recentlyAdded',
|
uniqueId: 'recentlyAdded',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
data: mostPlayed?.data?.items,
|
data: mostPlayed?.data?.items,
|
||||||
loading: mostPlayed?.isLoading || mostPlayed.isFetching,
|
loading: mostPlayed?.isLoading,
|
||||||
pagination: {
|
pagination: {
|
||||||
handleNextPage: () => handleNextPage('mostPlayed'),
|
|
||||||
handlePreviousPage: () => handlePreviousPage('mostPlayed'),
|
|
||||||
hasPreviousPage: pagination.mostPlayed > 0,
|
|
||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
title: (
|
title: 'Most played',
|
||||||
<TextTitle
|
|
||||||
order={2}
|
|
||||||
weight={700}
|
|
||||||
>
|
|
||||||
Most played
|
|
||||||
</TextTitle>
|
|
||||||
),
|
|
||||||
uniqueId: 'mostPlayed',
|
uniqueId: 'mostPlayed',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -211,12 +137,8 @@ const HomeRoute = () => {
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
ref={cq.ref}
|
ref={cq.ref}
|
||||||
pt="3rem"
|
pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'}
|
||||||
px="2rem"
|
px="2rem"
|
||||||
sx={{
|
|
||||||
height: '100%',
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Stack spacing={35}>
|
<Stack spacing={35}>
|
||||||
<FeatureCarousel data={featureItemsWithImage} />
|
<FeatureCarousel data={featureItemsWithImage} />
|
||||||
|
@ -231,9 +153,9 @@ const HomeRoute = () => {
|
||||||
|
|
||||||
return carousel;
|
return carousel;
|
||||||
})
|
})
|
||||||
.map((carousel, index) => (
|
.map((carousel) => (
|
||||||
<GridCarousel
|
<SwiperGridCarousel
|
||||||
key={`carousel-${carousel.uniqueId}-${index}`}
|
key={`carousel-${carousel.uniqueId}`}
|
||||||
cardRows={[
|
cardRows={[
|
||||||
{
|
{
|
||||||
property: 'name',
|
property: 'name',
|
||||||
|
@ -251,15 +173,16 @@ const HomeRoute = () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
containerWidth={cq.width}
|
|
||||||
data={carousel.data}
|
data={carousel.data}
|
||||||
|
isLoading={carousel.loading}
|
||||||
itemType={LibraryItem.ALBUM}
|
itemType={LibraryItem.ALBUM}
|
||||||
loading={carousel.loading}
|
route={{
|
||||||
pagination={carousel.pagination}
|
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
|
||||||
|
slugs: [{ idProperty: 'id', slugProperty: 'albumId' }],
|
||||||
|
}}
|
||||||
|
title={{ label: carousel.title }}
|
||||||
uniqueId={carousel.uniqueId}
|
uniqueId={carousel.uniqueId}
|
||||||
>
|
/>
|
||||||
<GridCarousel.Title>{carousel.title}</GridCarousel.Title>
|
|
||||||
</GridCarousel>
|
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
Reference in a new issue