Skip to content

Commit

Permalink
[enhancement]: support reordering homepage
Browse files Browse the repository at this point in the history
  • Loading branch information
kgarner7 committed Feb 5, 2024
1 parent 73c6ddd commit c3f4e9b
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 175 deletions.
4 changes: 4 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"channel_one": "channel",
"channel_other": "channels",
"clear": "clear",
"close": "close",
"collapse": "collapse",
"comingSoon": "coming soon…",
"configure": "configure",
Expand Down Expand Up @@ -458,6 +459,9 @@
"gaplessAudio_optionWeak": "weak (recommended)",
"globalMediaHotkeys": "global media hotkeys",
"globalMediaHotkeys_description": "enable or disable the usage of your system media hotkeys to control playback",
"homeConfiguration": "home page configuration",
"homeConfiguration_description": "configure what items are shown, and in what order, on the home page",
"homeConfigurationNote": "Recently played not available for Jellyfin",
"hotkey_browserBack": "browser back",
"hotkey_browserForward": "browser forward",
"hotkey_favoriteCurrentSong": "favorite $t(common.currentSong)",
Expand Down
183 changes: 95 additions & 88 deletions src/renderer/features/home/routes/home-route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import { useAlbumList } from '/@/renderer/features/albums';
import { useRecentlyPlayed } from '/@/renderer/features/home/queries/recently-played-query';
import { AnimatedPage, LibraryHeaderBar } from '/@/renderer/features/shared';
import { AppRoute } from '/@/renderer/router/routes';
import { useCurrentServer, useWindowSettings } from '/@/renderer/store';
import {
HomeItem,
useCurrentServer,
useGeneralSettings,
useWindowSettings,
} from '/@/renderer/store';
import { MemoizedSwiperGridCarousel } from '/@/renderer/components/grid-carousel';
import { Platform } from '/@/renderer/types';
import { useQueryClient } from '@tanstack/react-query';
Expand All @@ -28,6 +33,7 @@ const HomeRoute = () => {
const server = useCurrentServer();
const itemsPerPage = 15;
const { windowBarStyle } = useWindowSettings();
const { homeItems } = useGeneralSettings();

const feature = useAlbumList({
options: {
Expand Down Expand Up @@ -129,16 +135,15 @@ const HomeRoute = () => {
return <Spinner container />;
}

const carousels = [
{
const carousels = {
[HomeItem.RANDOM]: {
data: random?.data?.items,
itemType: LibraryItem.ALBUM,
sortBy: AlbumListSort.RANDOM,
sortOrder: SortOrder.ASC,
title: t('page.home.explore', { postProcess: 'sentenceCase' }),
uniqueId: 'random',
},
{
[HomeItem.RECENTLY_PLAYED]: {
data: recentlyPlayed?.data?.items,
itemType: LibraryItem.ALBUM,
pagination: {
Expand All @@ -147,9 +152,8 @@ const HomeRoute = () => {
sortBy: AlbumListSort.RECENTLY_PLAYED,
sortOrder: SortOrder.DESC,
title: t('page.home.recentlyPlayed', { postProcess: 'sentenceCase' }),
uniqueId: 'recentlyPlayed',
},
{
[HomeItem.RECENTLY_ADDED]: {
data: recentlyAdded?.data?.items,
itemType: LibraryItem.ALBUM,
pagination: {
Expand All @@ -158,9 +162,8 @@ const HomeRoute = () => {
sortBy: AlbumListSort.RECENTLY_ADDED,
sortOrder: SortOrder.DESC,
title: t('page.home.newlyAdded', { postProcess: 'sentenceCase' }),
uniqueId: 'recentlyAdded',
},
{
[HomeItem.MOST_PLAYED]: {
data:
server?.type === ServerType.JELLYFIN
? mostPlayedSongs?.data?.items
Expand All @@ -175,9 +178,24 @@ const HomeRoute = () => {
: AlbumListSort.PLAY_COUNT,
sortOrder: SortOrder.DESC,
title: t('page.home.mostPlayed', { postProcess: 'sentenceCase' }),
uniqueId: 'mostPlayed',
},
];
};

const sortedCarousel = homeItems
.filter((item) => {
if (item.disabled) {
return false;
}
if (server?.type === ServerType.JELLYFIN && item.id === HomeItem.RECENTLY_PLAYED) {
return false;
}

return true;
})
.map((item) => ({
...carousels[item.id],
uniqueId: item.id,
}));

const invalidateCarouselQuery = (carousel: {
itemType: LibraryItem;
Expand Down Expand Up @@ -232,87 +250,76 @@ const HomeRoute = () => {
spacing="lg"
>
<FeatureCarousel data={featureItemsWithImage} />
{carousels
.filter((carousel) => {
if (
server?.type === ServerType.JELLYFIN &&
carousel.uniqueId === 'recentlyPlayed'
) {
return null;
}

return carousel;
})
.map((carousel) => (
<MemoizedSwiperGridCarousel
key={`carousel-${carousel.uniqueId}`}
cardRows={[
{
property: 'name',
route: {
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
slugs: [
{
idProperty:
server?.type === ServerType.JELLYFIN &&
carousel.itemType === LibraryItem.SONG
? 'albumId'
: 'id',
slugProperty: 'albumId',
},
],
},
{sortedCarousel.map((carousel) => (
<MemoizedSwiperGridCarousel
key={`carousel-${carousel.uniqueId}`}
cardRows={[
{
property: 'name',
route: {
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
slugs: [
{
idProperty:
server?.type === ServerType.JELLYFIN &&
carousel.itemType === LibraryItem.SONG
? 'albumId'
: 'id',
slugProperty: 'albumId',
},
],
},
},
{
arrayProperty: 'name',
property: 'albumArtists',
route: {
route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL,
slugs: [
{
idProperty: 'id',
slugProperty: 'albumArtistId',
},
],
},
},
]}
data={carousel.data}
itemType={carousel.itemType}
route={{
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
slugs: [
{
arrayProperty: 'name',
property: 'albumArtists',
route: {
route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL,
slugs: [
{
idProperty: 'id',
slugProperty: 'albumArtistId',
},
],
},
idProperty:
server?.type === ServerType.JELLYFIN &&
carousel.itemType === LibraryItem.SONG
? 'albumId'
: 'id',
slugProperty: 'albumId',
},
]}
data={carousel.data}
itemType={carousel.itemType}
route={{
route: AppRoute.LIBRARY_ALBUMS_DETAIL,
slugs: [
{
idProperty:
server?.type === ServerType.JELLYFIN &&
carousel.itemType === LibraryItem.SONG
? 'albumId'
: 'id',
slugProperty: 'albumId',
},
],
}}
title={{
label: (
<Group>
<TextTitle
order={2}
weight={700}
>
{carousel.title}
</TextTitle>
],
}}
title={{
label: (
<Group>
<TextTitle
order={2}
weight={700}
>
{carousel.title}
</TextTitle>

<ActionIcon
onClick={() => invalidateCarouselQuery(carousel)}
>
<RiRefreshLine />
</ActionIcon>
</Group>
),
}}
uniqueId={carousel.uniqueId}
/>
))}
<ActionIcon
onClick={() => invalidateCarouselQuery(carousel)}
>
<RiRefreshLine />
</ActionIcon>
</Group>
),
}}
uniqueId={carousel.uniqueId}
/>
))}
</Stack>
</NativeScrollArea>
</AnimatedPage>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Group, Checkbox } from '@mantine/core';
import { useDragControls, Reorder } from 'framer-motion';
import { MdDragIndicator } from 'react-icons/md';

const DragHandle = ({ dragControls }: any) => {
return (
<MdDragIndicator
color="white"
style={{ cursor: 'grab' }}
onPointerDown={(event) => dragControls.start(event)}
/>
);
};

interface SidebarItem {
disabled: boolean;
id: string;
}

export interface DraggableItemProps {
handleChangeDisabled: (id: string, e: boolean) => void;
item: SidebarItem;
value: string;
}

export const DraggableItem = ({ item, value, handleChangeDisabled }: DraggableItemProps) => {
const dragControls = useDragControls();

return (
<Reorder.Item
as="div"
dragControls={dragControls}
dragListener={false}
value={item}
>
<Group
noWrap
h="3rem"
style={{ boxShadow: '0 1px 3px rgba(0,0,0,.1)' }}
>
<Checkbox
checked={!item.disabled}
onChange={(e) => handleChangeDisabled(item.id, e.target.checked)}
/>
<DragHandle dragControls={dragControls} />
{value}
</Group>
</Reorder.Item>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ThemeSettings } from '/@/renderer/features/settings/components/general/
import { RemoteSettings } from '/@/renderer/features/settings/components/general/remote-settings';
import { CacheSettings } from '/@/renderer/features/settings/components/window/cache-settngs';
import isElectron from 'is-electron';
import { HomeSettings } from '/@/renderer/features/settings/components/general/home-settings';

export const GeneralTab = () => {
return (
Expand All @@ -16,6 +17,8 @@ export const GeneralTab = () => {
<Divider />
<ControlSettings />
<Divider />
<HomeSettings />
<Divider />
<SidebarSettings />
{isElectron() && (
<>
Expand Down
Loading

0 comments on commit c3f4e9b

Please sign in to comment.