Allow navigating directly to playlist song view
This commit is contained in:
parent
d64040f3f0
commit
3dcb0dc4ed
6 changed files with 58 additions and 13 deletions
|
@ -225,6 +225,13 @@ export const PLAYLIST_CARD_ROWS: { [key: string]: CardRow<Playlist> } = {
|
|||
slugs: [{ idProperty: 'id', slugProperty: 'playlistId' }],
|
||||
},
|
||||
},
|
||||
nameFull: {
|
||||
property: 'name',
|
||||
route: {
|
||||
route: AppRoute.PLAYLISTS_DETAIL_SONGS,
|
||||
slugs: [{ idProperty: 'id', slugProperty: 'playlistId' }],
|
||||
},
|
||||
},
|
||||
owner: {
|
||||
property: 'owner',
|
||||
},
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||
import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useCurrentServer, usePlaylistListStore } from '/@/renderer/store';
|
||||
import { useCurrentServer, useGeneralSettings, usePlaylistListStore } from '/@/renderer/store';
|
||||
import { CardRow, ListDisplayType } from '/@/renderer/types';
|
||||
|
||||
interface PlaylistListGridViewProps {
|
||||
|
@ -31,6 +31,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
const grid = usePlaylistGridStore();
|
||||
const { setGrid } = usePlaylistStoreActions();
|
||||
const page = usePlaylistListStore();
|
||||
const { defaultFullPlaylist } = useGeneralSettings();
|
||||
|
||||
const createFavoriteMutation = useCreateFavorite({});
|
||||
const deleteFavoriteMutation = useDeleteFavorite({});
|
||||
|
@ -61,7 +62,9 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
};
|
||||
|
||||
const cardRows = useMemo(() => {
|
||||
const rows: CardRow<Playlist>[] = [PLAYLIST_CARD_ROWS.name];
|
||||
const rows: CardRow<Playlist>[] = defaultFullPlaylist
|
||||
? [PLAYLIST_CARD_ROWS.nameFull]
|
||||
: [PLAYLIST_CARD_ROWS.name];
|
||||
|
||||
switch (page.filter.sortBy) {
|
||||
case PlaylistListSort.DURATION:
|
||||
|
@ -84,7 +87,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
}
|
||||
|
||||
return rows;
|
||||
}, [page.filter.sortBy]);
|
||||
}, [defaultFullPlaylist, page.filter.sortBy]);
|
||||
|
||||
const handleGridScroll = useCallback(
|
||||
(e: ListOnScrollProps) => {
|
||||
|
@ -144,7 +147,9 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
|||
loading={itemCount === undefined || itemCount === null}
|
||||
minimumBatchSize={40}
|
||||
route={{
|
||||
route: AppRoute.PLAYLISTS_DETAIL,
|
||||
route: defaultFullPlaylist
|
||||
? AppRoute.PLAYLISTS_DETAIL_SONGS
|
||||
: AppRoute.PLAYLISTS_DETAIL,
|
||||
slugs: [{ idProperty: 'id', slugProperty: 'playlistId' }],
|
||||
}}
|
||||
width={width}
|
||||
|
|
|
@ -27,6 +27,7 @@ import {
|
|||
useSetPlaylistTable,
|
||||
useCurrentServer,
|
||||
usePlaylistListStore,
|
||||
useGeneralSettings,
|
||||
} from '/@/renderer/store';
|
||||
import { ListDisplayType } from '/@/renderer/types';
|
||||
|
||||
|
@ -43,6 +44,7 @@ export const PlaylistListTableView = ({ tableRef, itemCount }: PlaylistListTable
|
|||
const pagination = usePlaylistTablePagination();
|
||||
const setPagination = useSetPlaylistTablePagination();
|
||||
const setTable = useSetPlaylistTable();
|
||||
const { defaultFullPlaylist } = useGeneralSettings();
|
||||
|
||||
const isPaginationEnabled = page.display === ListDisplayType.TABLE_PAGINATED;
|
||||
|
||||
|
@ -171,7 +173,11 @@ export const PlaylistListTableView = ({ tableRef, itemCount }: PlaylistListTable
|
|||
|
||||
const handleRowDoubleClick = (e: RowDoubleClickedEvent) => {
|
||||
if (!e.data) return;
|
||||
if (defaultFullPlaylist) {
|
||||
navigate(generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: e.data.id }));
|
||||
} else {
|
||||
navigate(generatePath(AppRoute.PLAYLISTS_DETAIL, { playlistId: e.data.id }));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -195,6 +195,26 @@ export const ControlSettings = () => {
|
|||
isHidden: !isElectron(),
|
||||
title: 'Save play queue',
|
||||
},
|
||||
{
|
||||
control: (
|
||||
<Switch
|
||||
aria-label="Go to playlist songs page by default"
|
||||
defaultChecked={settings.defaultFullPlaylist}
|
||||
onChange={(e) =>
|
||||
setSettings({
|
||||
general: {
|
||||
...settings,
|
||||
defaultFullPlaylist: e.currentTarget.checked,
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
description:
|
||||
'When navigating to a playlist, go to the playlist song list page instead of the default page',
|
||||
isHidden: false,
|
||||
title: 'Go to playlist songs page by default',
|
||||
},
|
||||
];
|
||||
|
||||
return <SettingsSection options={controlOptions} />;
|
||||
|
|
|
@ -13,12 +13,21 @@ import { Play } from '/@/renderer/types';
|
|||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import { FixedSizeList, ListChildComponentProps } from 'react-window';
|
||||
import { useHideScrollbar } from '/@/renderer/hooks';
|
||||
import { useGeneralSettings } from '/@/renderer/store';
|
||||
|
||||
interface SidebarPlaylistListProps {
|
||||
data: ReturnType<typeof usePlaylistList>['data'];
|
||||
}
|
||||
|
||||
const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => {
|
||||
const path = data?.items[index].id
|
||||
? data.defaultFullPlaylist
|
||||
? generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: data.items[index].id })
|
||||
: generatePath(AppRoute.PLAYLISTS_DETAIL, {
|
||||
playlistId: data?.items[index].id,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0.5rem 0', padding: '0 1.5rem', ...style }}>
|
||||
<Group
|
||||
|
@ -47,13 +56,7 @@ const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => {
|
|||
cursor: 'default',
|
||||
width: '100%',
|
||||
}}
|
||||
to={
|
||||
data?.items[index].id
|
||||
? generatePath(AppRoute.PLAYLISTS_DETAIL, {
|
||||
playlistId: data?.items[index].id,
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
to={path}
|
||||
>
|
||||
{data?.items[index].name}
|
||||
</Text>
|
||||
|
@ -110,6 +113,7 @@ const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => {
|
|||
export const SidebarPlaylistList = ({ data }: SidebarPlaylistListProps) => {
|
||||
const { isScrollbarHidden, hideScrollbarElementProps } = useHideScrollbar(0);
|
||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||
const { defaultFullPlaylist } = useGeneralSettings();
|
||||
|
||||
const [rect, setRect] = useState({
|
||||
height: 0,
|
||||
|
@ -133,10 +137,11 @@ export const SidebarPlaylistList = ({ data }: SidebarPlaylistListProps) => {
|
|||
|
||||
const memoizedItemData = useMemo(() => {
|
||||
return {
|
||||
defaultFullPlaylist,
|
||||
handlePlay: handlePlayPlaylist,
|
||||
items: data?.items,
|
||||
};
|
||||
}, [data?.items, handlePlayPlaylist]);
|
||||
}, [data?.items, defaultFullPlaylist, handlePlayPlaylist]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
|
|
|
@ -103,6 +103,7 @@ export enum BindingActions {
|
|||
|
||||
export interface SettingsState {
|
||||
general: {
|
||||
defaultFullPlaylist: boolean;
|
||||
followSystemTheme: boolean;
|
||||
fontContent: string;
|
||||
playButtonBehavior: Play;
|
||||
|
@ -183,6 +184,7 @@ const platformDefaultWindowBarStyle: Platform = getPlatformDefaultWindowBarStyle
|
|||
|
||||
const initialState: SettingsState = {
|
||||
general: {
|
||||
defaultFullPlaylist: false,
|
||||
followSystemTheme: false,
|
||||
fontContent: 'Poppins',
|
||||
playButtonBehavior: Play.NOW,
|
||||
|
|
Reference in a new issue