Add view layout settings components
This commit is contained in:
parent
d26b361e53
commit
1f1aa892dc
3 changed files with 268 additions and 1 deletions
|
@ -0,0 +1,62 @@
|
|||
import React, { FC, useCallback } from 'react';
|
||||
import { ButtonGroup, IconButton } from '@mui/material';
|
||||
import ViewModuleIcon from '@mui/icons-material/ViewModule';
|
||||
import ViewListIcon from '@mui/icons-material/ViewList';
|
||||
import globalize from 'scripts/globalize';
|
||||
import { LibraryViewSettings, ViewMode } from 'types/library';
|
||||
import { LibraryTab } from 'types/libraryTab';
|
||||
import ViewSettingsButton from './ViewSettingsButton';
|
||||
|
||||
interface GridListViewButtonProps {
|
||||
viewType: LibraryTab;
|
||||
libraryViewSettings: LibraryViewSettings;
|
||||
setLibraryViewSettings: React.Dispatch<React.SetStateAction<LibraryViewSettings>>;
|
||||
}
|
||||
|
||||
const GridListViewButton: FC<GridListViewButtonProps> = ({
|
||||
viewType,
|
||||
libraryViewSettings,
|
||||
setLibraryViewSettings
|
||||
}) => {
|
||||
const handleToggleCurrentView = useCallback(() => {
|
||||
setLibraryViewSettings((prevState) => ({
|
||||
...prevState,
|
||||
ViewMode:
|
||||
prevState.ViewMode === ViewMode.ListView ? ViewMode.GridView : ViewMode.ListView
|
||||
}));
|
||||
}, [setLibraryViewSettings]);
|
||||
|
||||
const isGridView = libraryViewSettings.ViewMode === ViewMode.GridView;
|
||||
|
||||
return (
|
||||
<ButtonGroup>
|
||||
{isGridView ? (
|
||||
<ViewSettingsButton
|
||||
viewType={viewType}
|
||||
libraryViewSettings={libraryViewSettings}
|
||||
setLibraryViewSettings={setLibraryViewSettings}
|
||||
/>
|
||||
) : (
|
||||
<IconButton
|
||||
title={globalize.translate('GridView')}
|
||||
className='paper-icon-button-light autoSize'
|
||||
disabled={isGridView}
|
||||
onClick={handleToggleCurrentView}
|
||||
>
|
||||
<ViewModuleIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
|
||||
<IconButton
|
||||
title={globalize.translate('ListView')}
|
||||
className='paper-icon-button-light autoSize'
|
||||
disabled={!isGridView}
|
||||
onClick={handleToggleCurrentView}
|
||||
>
|
||||
<ViewListIcon />
|
||||
</IconButton>
|
||||
</ButtonGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default GridListViewButton;
|
198
src/apps/experimental/components/library/ViewSettingsButton.tsx
Normal file
198
src/apps/experimental/components/library/ViewSettingsButton.tsx
Normal file
|
@ -0,0 +1,198 @@
|
|||
import { ImageType } from '@jellyfin/sdk/lib/generated-client';
|
||||
import React, { FC, useCallback } from 'react';
|
||||
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Box from '@mui/material/Box';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import FormGroup from '@mui/material/FormGroup';
|
||||
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
||||
import Popover from '@mui/material/Popover';
|
||||
import ViewComfyIcon from '@mui/icons-material/ViewComfy';
|
||||
|
||||
import globalize from 'scripts/globalize';
|
||||
import { LibraryViewSettings, ViewMode } from 'types/library';
|
||||
import { LibraryTab } from 'types/libraryTab';
|
||||
|
||||
const imageTypesOptions = [
|
||||
{ label: 'Primary', value: ImageType.Primary },
|
||||
{ label: 'Banner', value: ImageType.Banner },
|
||||
{ label: 'Disc', value: ImageType.Disc },
|
||||
{ label: 'Logo', value: ImageType.Logo },
|
||||
{ label: 'Thumb', value: ImageType.Thumb }
|
||||
];
|
||||
|
||||
interface ViewSettingsButtonProps {
|
||||
viewType: LibraryTab;
|
||||
libraryViewSettings: LibraryViewSettings;
|
||||
setLibraryViewSettings: React.Dispatch<React.SetStateAction<LibraryViewSettings>>;
|
||||
}
|
||||
|
||||
const ViewSettingsButton: FC<ViewSettingsButtonProps> = ({
|
||||
viewType,
|
||||
libraryViewSettings,
|
||||
setLibraryViewSettings
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
const open = Boolean(anchorEl);
|
||||
const id = open ? 'selectview-popover' : undefined;
|
||||
|
||||
const handleClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
}, []);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
setAnchorEl(null);
|
||||
}, []);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const name = event.target.name;
|
||||
|
||||
setLibraryViewSettings((prevState) => ({
|
||||
...prevState,
|
||||
[name]: event.target.checked
|
||||
}));
|
||||
},
|
||||
[setLibraryViewSettings]
|
||||
);
|
||||
|
||||
const onSelectChange = useCallback(
|
||||
(event: SelectChangeEvent) => {
|
||||
setLibraryViewSettings((prevState) => ({
|
||||
...prevState,
|
||||
ImageType: event.target.value as ImageType
|
||||
}));
|
||||
},
|
||||
[setLibraryViewSettings]
|
||||
);
|
||||
|
||||
const getVisibleImageType = () => {
|
||||
const visibleImageType: ImageType[] = [ImageType.Primary];
|
||||
|
||||
if (
|
||||
viewType !== LibraryTab.Episodes
|
||||
&& viewType !== LibraryTab.Artists
|
||||
&& viewType !== LibraryTab.AlbumArtists
|
||||
&& viewType !== LibraryTab.Albums
|
||||
) {
|
||||
visibleImageType.push(ImageType.Banner);
|
||||
visibleImageType.push(ImageType.Disc);
|
||||
visibleImageType.push(ImageType.Logo);
|
||||
visibleImageType.push(ImageType.Thumb);
|
||||
}
|
||||
|
||||
return visibleImageType;
|
||||
};
|
||||
|
||||
const isViewSettingsEnabled = () => {
|
||||
return libraryViewSettings.ViewMode !== ViewMode.ListView;
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<IconButton
|
||||
title={globalize.translate('ButtonSelectView')}
|
||||
sx={{ ml: 2 }}
|
||||
aria-describedby={id}
|
||||
className='paper-icon-button-light btnShuffle autoSize'
|
||||
onClick={handleClick}
|
||||
>
|
||||
<ViewComfyIcon />
|
||||
</IconButton>
|
||||
<Popover
|
||||
id={id}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
anchorOrigin={{
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center'
|
||||
}}
|
||||
transformOrigin={{
|
||||
vertical: 'top',
|
||||
horizontal: 'center'
|
||||
}}
|
||||
sx={{
|
||||
'& .MuiFormControl-root': { m: 1, width: 220 }
|
||||
}}
|
||||
>
|
||||
<FormControl>
|
||||
<InputLabel id='select-sort-label'>
|
||||
<Typography component='span'>
|
||||
{globalize.translate('LabelImageType')}
|
||||
</Typography>
|
||||
</InputLabel>
|
||||
<Select
|
||||
value={libraryViewSettings.ImageType}
|
||||
label={globalize.translate('LabelImageType')}
|
||||
onChange={onSelectChange}
|
||||
>
|
||||
{imageTypesOptions
|
||||
.filter((imageType) => getVisibleImageType().includes(imageType.value))
|
||||
.map((imageType) => (
|
||||
<MenuItem
|
||||
key={imageType.value}
|
||||
value={imageType.value}
|
||||
>
|
||||
<Typography component='span'>
|
||||
{globalize.translate(imageType.label)}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
{isViewSettingsEnabled() && (
|
||||
<>
|
||||
<Divider />
|
||||
<FormControl>
|
||||
<FormGroup>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={libraryViewSettings.ShowTitle}
|
||||
onChange={handleChange}
|
||||
name='ShowTitle'
|
||||
/>
|
||||
}
|
||||
label={globalize.translate('ShowTitle')}
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={libraryViewSettings.ShowYear}
|
||||
onChange={handleChange}
|
||||
name='ShowYear'
|
||||
/>
|
||||
}
|
||||
label={globalize.translate('ShowYear')}
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={
|
||||
libraryViewSettings.CardLayout
|
||||
}
|
||||
onChange={handleChange}
|
||||
name='CardLayout'
|
||||
/>
|
||||
}
|
||||
label={globalize.translate(
|
||||
'EnableCardLayout'
|
||||
)}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FormControl>
|
||||
</>
|
||||
)}
|
||||
</Popover>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewSettingsButton;
|
|
@ -3,6 +3,7 @@ import type { VideoType } from '@jellyfin/sdk/lib/generated-client/models/video-
|
|||
import type { SortOrder } from '@jellyfin/sdk/lib/generated-client/models/sort-order';
|
||||
import type { SeriesStatus } from '@jellyfin/sdk/lib/generated-client/models/series-status';
|
||||
import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by';
|
||||
import { ImageType } from '@jellyfin/sdk/lib/generated-client';
|
||||
|
||||
export type ParentId = string | null | undefined;
|
||||
|
||||
|
@ -23,12 +24,18 @@ interface Filters {
|
|||
Years?: number[];
|
||||
}
|
||||
|
||||
export enum ViewMode {
|
||||
GridView = 'grid',
|
||||
ListView = 'list',
|
||||
}
|
||||
|
||||
export interface LibraryViewSettings {
|
||||
SortBy: ItemSortBy;
|
||||
SortOrder: SortOrder;
|
||||
StartIndex: number;
|
||||
CardLayout: boolean;
|
||||
ImageType: string;
|
||||
ImageType: ImageType;
|
||||
ViewMode: ViewMode;
|
||||
ShowTitle: boolean;
|
||||
ShowYear?: boolean;
|
||||
Filters?: Filters;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue