mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 02:13:33 +00:00
Make album detail columns customizable
This commit is contained in:
parent
13d6758500
commit
3f813b1a26
4 changed files with 86 additions and 65 deletions
|
|
@ -187,15 +187,17 @@ export const TableConfigDropdown = ({ type }: TableConfigDropdownProps) => {
|
||||||
/>
|
/>
|
||||||
</Option.Control>
|
</Option.Control>
|
||||||
</Option>
|
</Option>
|
||||||
<Option>
|
{type !== 'albumDetail' && (
|
||||||
<Option.Label>Follow current song</Option.Label>
|
<Option>
|
||||||
<Option.Control>
|
<Option.Label>Follow current song</Option.Label>
|
||||||
<Switch
|
<Option.Control>
|
||||||
defaultChecked={tableConfig[type]?.followCurrentSong}
|
<Switch
|
||||||
onChange={handleUpdateFollow}
|
defaultChecked={tableConfig[type]?.followCurrentSong}
|
||||||
/>
|
onChange={handleUpdateFollow}
|
||||||
</Option.Control>
|
/>
|
||||||
</Option>
|
</Option.Control>
|
||||||
|
</Option>
|
||||||
|
)}
|
||||||
<Option>
|
<Option>
|
||||||
<Option.Control>
|
<Option.Control>
|
||||||
<Slider
|
<Slider
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
import { ColDef, RowDoubleClickedEvent, RowHeightParams, RowNode } from '@ag-grid-community/core';
|
import { 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';
|
||||||
import { useSetState } from '@mantine/hooks';
|
import { useSetState } from '@mantine/hooks';
|
||||||
import { MutableRefObject, useCallback, useMemo } from 'react';
|
import { MutableRefObject, useCallback, useMemo } from 'react';
|
||||||
import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
|
import { RiHeartFill, RiHeartLine, RiMoreFill, RiSettings2Fill } 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 { 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, Popover } from '/@/renderer/components';
|
||||||
import { MemoizedSwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
import { MemoizedSwiperGridCarousel } from '/@/renderer/components/grid-carousel';
|
||||||
import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table';
|
import {
|
||||||
|
getColumnDefs,
|
||||||
|
TableConfigDropdown,
|
||||||
|
VirtualTable,
|
||||||
|
} from '/@/renderer/components/virtual-table';
|
||||||
import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell';
|
import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell';
|
||||||
import { useCurrentSongRowStyles } from '/@/renderer/components/virtual-table/hooks/use-current-song-row-styles';
|
import { useCurrentSongRowStyles } from '/@/renderer/components/virtual-table/hooks/use-current-song-row-styles';
|
||||||
import { useAlbumDetail } from '/@/renderer/features/albums/queries/album-detail-query';
|
import { useAlbumDetail } from '/@/renderer/features/albums/queries/album-detail-query';
|
||||||
|
|
@ -30,8 +34,8 @@ import { LibraryBackgroundOverlay } from '/@/renderer/features/shared/components
|
||||||
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 } from '/@/renderer/store';
|
||||||
import { PersistedTableColumn, usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior, useTableSettings } from '/@/renderer/store/settings.store';
|
||||||
import { Play, ServerType, TableColumn } from '/@/renderer/types';
|
import { Play } from '/@/renderer/types';
|
||||||
|
|
||||||
const isFullWidthRow = (node: RowNode) => {
|
const isFullWidthRow = (node: RowNode) => {
|
||||||
return node.id?.startsWith('disc-');
|
return node.id?.startsWith('disc-');
|
||||||
|
|
@ -60,52 +64,11 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id });
|
const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id });
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||||
|
const tableConfig = useTableSettings('albumDetail');
|
||||||
|
|
||||||
// TODO: Make this customizable
|
console.log('tableConfig :>> ', tableConfig);
|
||||||
const columnDefs: ColDef[] = useMemo(() => {
|
|
||||||
const userRatingColumn =
|
|
||||||
detailQuery?.data?.serverType !== ServerType.JELLYFIN
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
column: TableColumn.USER_RATING,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const cols: PersistedTableColumn[] = [
|
const columnDefs = useMemo(() => getColumnDefs(tableConfig.columns), [tableConfig.columns]);
|
||||||
{
|
|
||||||
column: TableColumn.TRACK_NUMBER,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: TableColumn.TITLE_COMBINED,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: TableColumn.DURATION,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: TableColumn.BIT_RATE,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: TableColumn.PLAY_COUNT,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
column: TableColumn.LAST_PLAYED,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
...userRatingColumn,
|
|
||||||
{
|
|
||||||
column: TableColumn.USER_FAVORITE,
|
|
||||||
width: 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
return getColumnDefs(cols).filter((c) => c.colId !== 'album' && c.colId !== 'artist');
|
|
||||||
}, [detailQuery?.data?.serverType]);
|
|
||||||
|
|
||||||
const getRowHeight = useCallback((params: RowHeightParams) => {
|
const getRowHeight = useCallback((params: RowHeightParams) => {
|
||||||
if (isFullWidthRow(params.node)) {
|
if (isFullWidthRow(params.node)) {
|
||||||
|
|
@ -307,11 +270,12 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
<DetailContainer>
|
<DetailContainer>
|
||||||
<Box component="section">
|
<Box component="section">
|
||||||
<Group
|
<Group
|
||||||
|
position="apart"
|
||||||
py="1rem"
|
py="1rem"
|
||||||
spacing="md"
|
spacing="sm"
|
||||||
>
|
>
|
||||||
<PlayButton onClick={() => handlePlay(playButtonBehavior)} />
|
<Group>
|
||||||
<Group spacing="xs">
|
<PlayButton onClick={() => handlePlay(playButtonBehavior)} />
|
||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
loading={
|
loading={
|
||||||
|
|
@ -341,6 +305,21 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
<RiMoreFill size={20} />
|
<RiMoreFill size={20} />
|
||||||
</Button>
|
</Button>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
|
<Popover position="bottom-end">
|
||||||
|
<Popover.Target>
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
size="md"
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
<RiSettings2Fill size={20} />
|
||||||
|
</Button>
|
||||||
|
</Popover.Target>
|
||||||
|
<Popover.Dropdown>
|
||||||
|
<TableConfigDropdown type="albumDetail" />
|
||||||
|
</Popover.Dropdown>
|
||||||
|
</Popover>
|
||||||
</Group>
|
</Group>
|
||||||
</Box>
|
</Box>
|
||||||
{showGenres && (
|
{showGenres && (
|
||||||
|
|
@ -370,13 +349,12 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP
|
||||||
<Box style={{ minHeight: '300px' }}>
|
<Box style={{ minHeight: '300px' }}>
|
||||||
<VirtualTable
|
<VirtualTable
|
||||||
ref={tableRef}
|
ref={tableRef}
|
||||||
autoFitColumns
|
|
||||||
autoHeight
|
autoHeight
|
||||||
stickyHeader
|
stickyHeader
|
||||||
suppressCellFocus
|
suppressCellFocus
|
||||||
suppressHorizontalScroll
|
|
||||||
suppressLoadingOverlay
|
suppressLoadingOverlay
|
||||||
suppressRowDrag
|
suppressRowDrag
|
||||||
|
autoFitColumns={tableConfig.autoFit}
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
enableCellChangeFlash={false}
|
enableCellChangeFlash={false}
|
||||||
fullWidthCellRenderer={FullWidthDiscCell}
|
fullWidthCellRenderer={FullWidthDiscCell}
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ export interface SettingsState {
|
||||||
};
|
};
|
||||||
tab: 'general' | 'playback' | 'window' | 'hotkeys' | string;
|
tab: 'general' | 'playback' | 'window' | 'hotkeys' | string;
|
||||||
tables: {
|
tables: {
|
||||||
|
albumDetail: DataTableProps;
|
||||||
fullScreen: DataTableProps;
|
fullScreen: DataTableProps;
|
||||||
nowPlaying: DataTableProps;
|
nowPlaying: DataTableProps;
|
||||||
sideDrawerQueue: DataTableProps;
|
sideDrawerQueue: DataTableProps;
|
||||||
|
|
@ -287,6 +288,40 @@ const initialState: SettingsState = {
|
||||||
},
|
},
|
||||||
tab: 'general',
|
tab: 'general',
|
||||||
tables: {
|
tables: {
|
||||||
|
albumDetail: {
|
||||||
|
autoFit: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
column: TableColumn.TRACK_NUMBER,
|
||||||
|
width: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.TITLE_COMBINED,
|
||||||
|
width: 500,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.DURATION,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.BIT_RATE,
|
||||||
|
width: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.PLAY_COUNT,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.LAST_PLAYED,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
column: TableColumn.USER_FAVORITE,
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rowHeight: 60,
|
||||||
|
},
|
||||||
fullScreen: {
|
fullScreen: {
|
||||||
autoFit: true,
|
autoFit: true,
|
||||||
columns: [
|
columns: [
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,13 @@ export type CardRoute = {
|
||||||
slugs?: RouteSlug[];
|
slugs?: RouteSlug[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TableType = 'nowPlaying' | 'sideQueue' | 'sideDrawerQueue' | 'songs' | 'fullScreen';
|
export type TableType =
|
||||||
|
| 'nowPlaying'
|
||||||
|
| 'sideQueue'
|
||||||
|
| 'sideDrawerQueue'
|
||||||
|
| 'songs'
|
||||||
|
| 'fullScreen'
|
||||||
|
| 'albumDetail';
|
||||||
|
|
||||||
export type CardRow<T> = {
|
export type CardRow<T> = {
|
||||||
arrayProperty?: string;
|
arrayProperty?: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue