[enhancement]: Support toggling Album/Track view for gneres (#591)

* [enhancement]: Support toggling Album/Track view for gneres

The _primary_ purpose of this PR is to enable viewing tracks OR albums for genres.
This has a few requirements:
1. Ability to set default route for genres, **except** when already on song/album page
2. Ability to toggle between album and genre view
3. Fixed refresh for genre ID

Additionally, there was some refactoring:
- Since the *-list-headers had very similar functions for search, export that as a hook instead

* also use hook for album artist

* support switching albumartist tracks/albums

* remove toggle on song/album list, simplify logic
This commit is contained in:
Kendall Garner 2024-04-20 06:14:31 +00:00 committed by GitHub
parent 595eba152a
commit ba531505af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 336 additions and 158 deletions

View file

@ -1,62 +1,64 @@
import { ChangeEvent, MutableRefObject, useEffect, useRef } from 'react';
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import { Flex, Group, Stack } from '@mantine/core';
import debounce from 'lodash/debounce';
import { ChangeEvent, MutableRefObject } from 'react';
import { useTranslation } from 'react-i18next';
import { useListStoreByKey } from '../../../store/list.store';
import { LibraryItem } from '/@/renderer/api/types';
import { PageHeader, SearchInput } from '/@/renderer/components';
import { useListContext } from '/@/renderer/context/list-context';
import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared';
import { SongListHeaderFilters } from '/@/renderer/features/songs/components/song-list-header-filters';
import { useContainerQuery } from '/@/renderer/hooks';
import { useListFilterRefresh } from '/@/renderer/hooks/use-list-filter-refresh';
import { SongListFilter, useCurrentServer, useListStoreActions } from '/@/renderer/store';
import { SongListFilter, useCurrentServer } from '/@/renderer/store';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { ListDisplayType } from '/@/renderer/types';
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
import { useDisplayRefresh } from '/@/renderer/hooks/use-display-refresh';
interface SongListHeaderProps {
genreId?: string;
gridRef: MutableRefObject<VirtualInfiniteGridRef | null>;
itemCount?: number;
tableRef: MutableRefObject<AgGridReactType | null>;
title?: string;
}
export const SongListHeader = ({ gridRef, title, itemCount, tableRef }: SongListHeaderProps) => {
export const SongListHeader = ({
genreId,
gridRef,
title,
itemCount,
tableRef,
}: SongListHeaderProps) => {
const { t } = useTranslation();
const server = useCurrentServer();
const { pageKey, handlePlay, customFilters } = useListContext();
const { setFilter, setTablePagination } = useListStoreActions();
const { display, filter } = useListStoreByKey({ key: pageKey });
const cq = useContainerQuery();
const genreRef = useRef<string>();
const { handleRefreshTable, handleRefreshGrid } = useListFilterRefresh({
const { customFilters, filter, handlePlay, refresh, search } = useDisplayRefresh({
gridRef,
itemType: LibraryItem.SONG,
server,
tableRef,
});
const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => {
const searchTerm = e.target.value === '' ? undefined : e.target.value;
const updatedFilters = setFilter({
data: { searchTerm },
itemType: LibraryItem.SONG,
key: pageKey,
}) as SongListFilter;
const updatedFilters = search(e) as SongListFilter;
const filterWithCustom = {
...updatedFilters,
...customFilters,
};
if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) {
handleRefreshTable(tableRef, filterWithCustom);
setTablePagination({ data: { currentPage: 0 }, key: pageKey });
} else {
handleRefreshGrid(gridRef, filterWithCustom);
}
refresh(filterWithCustom);
}, 500);
useEffect(() => {
if (genreRef.current && genreRef.current !== genreId) {
refresh(customFilters);
}
genreRef.current = genreId;
}, [customFilters, genreId, refresh, tableRef]);
const playButtonBehavior = usePlayButtonBehavior();
return (

View file

@ -145,6 +145,7 @@ const TrackListRoute = () => {
<AnimatedPage>
<ListContext.Provider value={providerValue}>
<SongListHeader
genreId={genreId}
gridRef={gridRef}
itemCount={itemCount}
tableRef={tableRef}