Update library controls layout for mobile

This commit is contained in:
Bill Thornton
2025-05-02 17:21:40 -04:00
parent 9371c2a190
commit 0a89cc6b8f
4 changed files with 152 additions and 76 deletions
@@ -4,6 +4,8 @@ import { ImageType } from '@jellyfin/sdk/lib/generated-client/models/image-type'
import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by';
import Box from '@mui/material/Box';
import ButtonGroup from '@mui/material/ButtonGroup';
import type { Theme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import classNames from 'classnames';
import React, { type FC, useCallback } from 'react';
@@ -73,6 +75,7 @@ const ItemsView: FC<ItemsViewProps> = ({
getSettingsKey(viewType, parentId),
getDefaultLibraryViewSettings(viewType)
);
const isSmallScreen = useMediaQuery((t: Theme) => t.breakpoints.up('sm'));
const { __legacyApiClient__ } = useApi();
const {
@@ -230,10 +233,10 @@ const ItemsView: FC<ItemsViewProps> = ({
);
return (
<Box>
<Box className='padded-bottom-page'>
<Box
className={classNames(
'padded-top padded-left padded-right padded-bottom',
'padded-top padded-left padded-right',
{ 'padded-right-withalphapicker': isAlphabetPickerEnabled }
)}
sx={{
@@ -243,17 +246,59 @@ const ItemsView: FC<ItemsViewProps> = ({
}}
>
<Box
sx={{ marginRight: 0.5 }}
sx={{ marginRight: 1 }}
>
<LibraryViewMenu />
</Box>
<Box
sx={{
flexGrow: {
xs: 1,
md: 0
},
marginRight: 1
}}
>
<ButtonGroup
color='inherit'
variant='text'
>
{isBtnFilterEnabled && (
<FilterButton
parentId={parentId}
itemType={itemType}
viewType={viewType}
hasFilters={hasFilters}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnSortEnabled && (
<SortButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnGridListEnabled && (
<ViewSettingsButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
</ButtonGroup>
</Box>
<Box
sx={{
display: 'flex',
flexGrow: {
xs: 1,
md: 0
sm: 0
},
justifyContent: 'end'
}}
@@ -262,9 +307,6 @@ const ItemsView: FC<ItemsViewProps> = ({
<>
<ButtonGroup
variant='contained'
sx={{
marginRight: 0.5
}}
>
{isBtnPlayAllEnabled && (
<PlayAllButton
@@ -272,6 +314,7 @@ const ItemsView: FC<ItemsViewProps> = ({
items={items}
viewType={viewType}
hasFilters={hasFilters}
isTextVisible={isSmallScreen}
libraryViewSettings={libraryViewSettings}
/>
)}
@@ -282,7 +325,7 @@ const ItemsView: FC<ItemsViewProps> = ({
items={items}
viewType={viewType}
hasFilters={hasFilters}
isTextVisible={!isBtnPlayAllEnabled}
isTextVisible={isSmallScreen && !isBtnPlayAllEnabled}
libraryViewSettings={libraryViewSettings}
/>
)}
@@ -292,12 +335,12 @@ const ItemsView: FC<ItemsViewProps> = ({
item={item}
items={items}
hasFilters={hasFilters}
isTextVisible={!isBtnPlayAllEnabled && !isBtnShuffleEnabled}
isTextVisible={isSmallScreen && !isBtnPlayAllEnabled && !isBtnShuffleEnabled}
/>
)}
</ButtonGroup>
{isBtnNewCollectionEnabled && <NewCollectionButton />}
{isBtnNewCollectionEnabled && <NewCollectionButton isTextVisible={isSmallScreen} />}
</>
)}
</Box>
@@ -310,51 +353,14 @@ const ItemsView: FC<ItemsViewProps> = ({
xs: '100%',
md: 'auto'
},
flexGrow: 1
flexGrow: 1,
marginTop: {
xs: 0.5,
sm: 0
}
}}
>
<Box
sx={{
flexGrow: {
xs: 1,
md: 0
}
}}
>
<ButtonGroup
color='inherit'
variant='text'
>
{isBtnFilterEnabled && (
<FilterButton
parentId={parentId}
itemType={itemType}
viewType={viewType}
hasFilters={hasFilters}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnSortEnabled && (
<SortButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
{isBtnGridListEnabled && (
<ViewSettingsButton
viewType={viewType}
libraryViewSettings={libraryViewSettings}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
</ButtonGroup>
</Box>
{isPaginationEnabled && (
{!isPending && isPaginationEnabled && (
<Pagination
totalRecordCount={totalRecordCount}
libraryViewSettings={libraryViewSettings}
@@ -385,10 +391,10 @@ const ItemsView: FC<ItemsViewProps> = ({
</ItemsContainer>
)}
{isPaginationEnabled && (
{!isPending && isPaginationEnabled && (
<Box
className={classNames(
'padded-top padded-left padded-right padded-bottom',
'padded-left padded-right',
{ 'padded-right-withalphapicker': isAlphabetPickerEnabled }
)}
sx={{
@@ -4,7 +4,13 @@ import Button from '@mui/material/Button';
import globalize from 'lib/globalize';
const NewCollectionButton: FC = () => {
interface NewCollectionButtonProps {
isTextVisible: boolean
}
const NewCollectionButton: FC<NewCollectionButtonProps> = ({
isTextVisible
}) => {
const showCollectionEditor = useCallback(() => {
import('components/collectionEditor/collectionEditor').then(
({ default: CollectionEditor }) => {
@@ -24,10 +30,14 @@ const NewCollectionButton: FC = () => {
return (
<Button
variant='contained'
startIcon={<Add />}
startIcon={isTextVisible ? <Add /> : undefined}
onClick={showCollectionEditor}
>
{globalize.translate('NewCollection')}
{isTextVisible ? (
globalize.translate('NewCollection')
) : (
<Add />
)}
</Button>
);
};
@@ -5,6 +5,9 @@ import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import ButtonGroup from '@mui/material/ButtonGroup';
import Stack from '@mui/material/Stack';
import type { Theme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import useMediaQuery from '@mui/material/useMediaQuery';
import globalize from 'lib/globalize';
import * as userSettings from 'scripts/settings/userSettings';
@@ -23,6 +26,8 @@ const Pagination: FC<PaginationProps> = ({
totalRecordCount,
isPlaceholderData
}) => {
const isSmallScreen = useMediaQuery((t: Theme) => t.breakpoints.up('sm'));
const limit = userSettings.libraryPageSize(undefined);
const startIndex = libraryViewSettings.StartIndex ?? 0;
const recordsStart = totalRecordCount ? startIndex + 1 : 0;
@@ -53,25 +58,56 @@ const Pagination: FC<PaginationProps> = ({
spacing={0.5}
sx={{
alignItems: 'center',
marginLeft: 0.5
flexGrow: {
xs: 1,
md: 0
},
marginLeft: {
xs: 0,
sm: 0.5
}
}}
>
<Box>
{globalize.translate(
'ListPaging',
recordsStart,
recordsEnd,
totalRecordCount
)}
{!isSmallScreen && (
<Button
color='inherit'
variant='text'
title={globalize.translate('Previous')}
disabled={!showControls || startIndex == 0 || isPlaceholderData}
onClick={onPreviousPageClick}
>
<ArrowBackIcon />
</Button>
)}
<Box
sx={{
display: 'flex',
flexGrow: 1,
alignItems: 'center',
justifyContent: 'center',
marginLeft: 1,
marginRight: 1
}}
>
<Typography variant='body2'>
{globalize.translate(
'ListPaging',
recordsStart,
recordsEnd,
totalRecordCount
)}
</Typography>
</Box>
{showControls && (
{isSmallScreen && (
<ButtonGroup
color='inherit'
variant='text'
>
<Button
title={globalize.translate('Previous')}
disabled={startIndex == 0 || isPlaceholderData}
disabled={!showControls || startIndex == 0 || isPlaceholderData}
onClick={onPreviousPageClick}
>
<ArrowBackIcon />
@@ -79,13 +115,25 @@ const Pagination: FC<PaginationProps> = ({
<Button
title={globalize.translate('Next')}
disabled={startIndex + limit >= totalRecordCount || isPlaceholderData }
disabled={!showControls || startIndex + limit >= totalRecordCount || isPlaceholderData }
onClick={onNextPageClick}
>
<ArrowForwardIcon />
</Button>
</ButtonGroup>
)}
{!isSmallScreen && (
<Button
color='inherit'
variant='text'
title={globalize.translate('Next')}
disabled={!showControls || startIndex + limit >= totalRecordCount || isPlaceholderData }
onClick={onNextPageClick}
>
<ArrowForwardIcon />
</Button>
)}
</Stack>
);
};
@@ -10,14 +10,22 @@ import { LibraryTab } from 'types/libraryTab';
import type { ItemDto } from 'types/base/models/item-dto';
interface PlayAllButtonProps {
item: ItemDto | undefined;
items: ItemDto[];
viewType: LibraryTab;
hasFilters: boolean;
item: ItemDto | undefined
items: ItemDto[]
viewType: LibraryTab
hasFilters: boolean
isTextVisible: boolean
libraryViewSettings: LibraryViewSettings
}
const PlayAllButton: FC<PlayAllButtonProps> = ({ item, items, viewType, hasFilters, libraryViewSettings }) => {
const PlayAllButton: FC<PlayAllButtonProps> = ({
item,
items,
viewType,
hasFilters,
isTextVisible,
libraryViewSettings
}) => {
const play = useCallback(() => {
if (item && !hasFilters) {
playbackManager.play({
@@ -49,10 +57,14 @@ const PlayAllButton: FC<PlayAllButtonProps> = ({ item, items, viewType, hasFilte
return (
<Button
title={globalize.translate('HeaderPlayAll')}
startIcon={<PlayArrow />}
startIcon={isTextVisible ? <PlayArrow /> : undefined}
onClick={play}
>
{globalize.translate('HeaderPlayAll')}
{isTextVisible ? (
globalize.translate('HeaderPlayAll')
) : (
<PlayArrow />
)}
</Button>
);
};