From cc19ae9ca9863aa3e63437cf3b2a36e6503e82b1 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 16 Apr 2025 14:09:21 -0400 Subject: [PATCH 1/5] Update experimental layout library controls --- .../components/library/GridListViewButton.tsx | 64 ------ .../components/library/ItemsView.tsx | 178 +++++++++------ .../library/NewCollectionButton.tsx | 15 +- .../components/library/Pagination.tsx | 73 +++---- .../components/library/PlayAllButton.tsx | 18 +- .../components/library/QueueButton.tsx | 34 +-- .../components/library/ShuffleButton.tsx | 38 ++-- .../components/library/SortButton.tsx | 13 +- .../components/library/ViewSettingsButton.tsx | 205 +++++++++++------- .../library/filter/FilterButton.tsx | 17 +- src/strings/en-us.json | 1 + 11 files changed, 342 insertions(+), 314 deletions(-) delete mode 100644 src/apps/experimental/components/library/GridListViewButton.tsx diff --git a/src/apps/experimental/components/library/GridListViewButton.tsx b/src/apps/experimental/components/library/GridListViewButton.tsx deleted file mode 100644 index bf6f48391..000000000 --- a/src/apps/experimental/components/library/GridListViewButton.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React, { FC, useCallback } from 'react'; -import ButtonGroup from '@mui/material/ButtonGroup/ButtonGroup'; -import IconButton from '@mui/material/IconButton'; -import ViewModuleIcon from '@mui/icons-material/ViewModule'; -import ViewListIcon from '@mui/icons-material/ViewList'; - -import globalize from 'lib/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>; -} - -const GridListViewButton: FC = ({ - 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 ( - - {isGridView ? ( - - ) : ( - - - - )} - - - - - - ); -}; - -export default GridListViewButton; diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index aa6e8f881..c6d43d625 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -2,9 +2,10 @@ import type { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/bas import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { ImageType } from '@jellyfin/sdk/lib/generated-client/models/image-type'; import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; -import React, { type FC, useCallback } from 'react'; import Box from '@mui/material/Box'; +import ButtonGroup from '@mui/material/ButtonGroup'; import classNames from 'classnames'; +import React, { type FC, useCallback } from 'react'; import { useApi } from 'hooks/useApi'; import { useLocalStorage } from 'hooks/useLocalStorage'; @@ -31,8 +32,8 @@ import PlayAllButton from './PlayAllButton'; import QueueButton from './QueueButton'; import ShuffleButton from './ShuffleButton'; import SortButton from './SortButton'; -import GridListViewButton from './GridListViewButton'; import LibraryViewMenu from './LibraryViewMenu'; +import ViewSettingsButton from './ViewSettingsButton'; interface ItemsViewProps { viewType: LibraryTab; @@ -237,82 +238,127 @@ const ItemsView: FC = ({ )} sx={{ display: 'flex', - flexWrap: 'wrap' + flexWrap: 'wrap', + alignItems: 'center' }} > + + + - - - {isBtnPlayAllEnabled && ( - - )} - {isBtnShuffleEnabled && totalRecordCount > 1 && ( - - )} - {isBtnQueueEnabled - && item - && playbackManager.canQueue(item) && ( - - )} - {isBtnSortEnabled && ( - - )} - {isBtnFilterEnabled && ( - - )} - {isBtnNewCollectionEnabled && } - {isBtnGridListEnabled && ( - - )} - - {isPaginationEnabled && ( - + + {isBtnPlayAllEnabled && ( + + )} + + {isBtnShuffleEnabled && totalRecordCount > 1 && ( + + )} + + {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( + + )} + + + {isBtnNewCollectionEnabled && } + + + + + + {isBtnFilterEnabled && ( + + )} + + {isBtnSortEnabled && ( + + )} + + {isBtnGridListEnabled && ( + + )} + + + + {isPaginationEnabled && ( - - )} + )} + {isAlphabetPickerEnabled && hasSortName && ( diff --git a/src/apps/experimental/components/library/NewCollectionButton.tsx b/src/apps/experimental/components/library/NewCollectionButton.tsx index 92d9eea31..bfe2c864d 100644 --- a/src/apps/experimental/components/library/NewCollectionButton.tsx +++ b/src/apps/experimental/components/library/NewCollectionButton.tsx @@ -1,6 +1,7 @@ import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; -import AddIcon from '@mui/icons-material/Add'; +import Add from '@mui/icons-material/Add'; +import Button from '@mui/material/Button'; + import globalize from 'lib/globalize'; const NewCollectionButton: FC = () => { @@ -21,13 +22,13 @@ const NewCollectionButton: FC = () => { }, []); return ( - } onClick={showCollectionEditor} > - - + {globalize.translate('NewCollection')} + ); }; diff --git a/src/apps/experimental/components/library/Pagination.tsx b/src/apps/experimental/components/library/Pagination.tsx index 477a98231..782271271 100644 --- a/src/apps/experimental/components/library/Pagination.tsx +++ b/src/apps/experimental/components/library/Pagination.tsx @@ -2,8 +2,9 @@ import React, { FC, useCallback } from 'react'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; import ButtonGroup from '@mui/material/ButtonGroup'; -import IconButton from '@mui/material/IconButton'; +import Stack from '@mui/material/Stack'; import globalize from 'lib/globalize'; import * as userSettings from 'scripts/settings/userSettings'; @@ -47,47 +48,45 @@ const Pagination: FC = ({ }, [limit, setLibraryViewSettings, startIndex]); return ( - - - - {globalize.translate( - 'ListPaging', - recordsStart, - recordsEnd, - totalRecordCount - )} - - {showControls && ( - - - - - - = totalRecordCount || isPlaceholderData } - onClick={onNextPageClick} - > - - - + + {globalize.translate( + 'ListPaging', + recordsStart, + recordsEnd, + totalRecordCount )} - + {showControls && ( + + + + + + )} + ); }; diff --git a/src/apps/experimental/components/library/PlayAllButton.tsx b/src/apps/experimental/components/library/PlayAllButton.tsx index 16cef318a..4e9a1a47d 100644 --- a/src/apps/experimental/components/library/PlayAllButton.tsx +++ b/src/apps/experimental/components/library/PlayAllButton.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; -import PlayArrowIcon from '@mui/icons-material/PlayArrow'; +import Button from '@mui/material/Button'; +import PlayArrow from '@mui/icons-material/PlayArrow'; import { playbackManager } from 'components/playback/playbackmanager'; import globalize from 'lib/globalize'; @@ -47,19 +47,13 @@ const PlayAllButton: FC = ({ item, items, viewType, hasFilte }, [hasFilters, item, items, libraryViewSettings, viewType]); return ( - } onClick={play} - sx={{ - order: { - xs: 1, - sm: 'unset' - } - }} > - - + {globalize.translate('HeaderPlayAll')} + ); }; diff --git a/src/apps/experimental/components/library/QueueButton.tsx b/src/apps/experimental/components/library/QueueButton.tsx index c656e2b56..aa925e228 100644 --- a/src/apps/experimental/components/library/QueueButton.tsx +++ b/src/apps/experimental/components/library/QueueButton.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; -import QueueIcon from '@mui/icons-material/Queue'; +import Button from '@mui/material/Button'; +import Queue from '@mui/icons-material/Queue'; import { playbackManager } from 'components/playback/playbackmanager'; import globalize from 'lib/globalize'; @@ -8,11 +8,17 @@ import type { ItemDto } from 'types/base/models/item-dto'; interface QueueButtonProps { item: ItemDto | undefined - items: ItemDto[]; - hasFilters: boolean; + items: ItemDto[] + hasFilters: boolean + isTextVisible: boolean } -const QueueButton: FC = ({ item, items, hasFilters }) => { +const QueueButton: FC = ({ + item, + items, + hasFilters, + isTextVisible +}) => { const queue = useCallback(() => { if (item && !hasFilters) { playbackManager.queue({ @@ -30,19 +36,17 @@ const QueueButton: FC = ({ item, items, hasFilters }) => { }, [hasFilters, item, items]); return ( - : undefined} onClick={queue} - sx={{ - order: { - xs: 3, - sm: 'unset' - } - }} > - - + {isTextVisible ? ( + globalize.translate('AddToPlayQueue') + ) : ( + + )} + ); }; diff --git a/src/apps/experimental/components/library/ShuffleButton.tsx b/src/apps/experimental/components/library/ShuffleButton.tsx index 44acdbc54..7f240df44 100644 --- a/src/apps/experimental/components/library/ShuffleButton.tsx +++ b/src/apps/experimental/components/library/ShuffleButton.tsx @@ -1,7 +1,7 @@ import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; -import ShuffleIcon from '@mui/icons-material/Shuffle'; +import Shuffle from '@mui/icons-material/Shuffle'; +import Button from '@mui/material/Button'; import { playbackManager } from 'components/playback/playbackmanager'; import globalize from 'lib/globalize'; @@ -11,14 +11,22 @@ import { LibraryTab } from 'types/libraryTab'; import type { ItemDto } from 'types/base/models/item-dto'; interface ShuffleButtonProps { - item: ItemDto | undefined; - items: ItemDto[]; + item: ItemDto | undefined + items: ItemDto[] viewType: LibraryTab - hasFilters: boolean; + hasFilters: boolean + isTextVisible: boolean libraryViewSettings: LibraryViewSettings } -const ShuffleButton: FC = ({ item, items, viewType, hasFilters, libraryViewSettings }) => { +const ShuffleButton: FC = ({ + item, + items, + viewType, + hasFilters, + isTextVisible, + libraryViewSettings +}) => { const shuffle = useCallback(() => { if (item && !hasFilters) { playbackManager.shuffle(item); @@ -38,19 +46,17 @@ const ShuffleButton: FC = ({ item, items, viewType, hasFilte }, [hasFilters, item, items, libraryViewSettings, viewType]); return ( - : undefined} onClick={shuffle} - sx={{ - order: { - xs: 2, - sm: 'unset' - } - }} > - - + {isTextVisible ? ( + globalize.translate('Shuffle') + ) : ( + + )} + ); }; diff --git a/src/apps/experimental/components/library/SortButton.tsx b/src/apps/experimental/components/library/SortButton.tsx index 25f290b25..6e8acf8b9 100644 --- a/src/apps/experimental/components/library/SortButton.tsx +++ b/src/apps/experimental/components/library/SortButton.tsx @@ -1,12 +1,11 @@ import { ItemSortBy } from '@jellyfin/sdk/lib/generated-client/models/item-sort-by'; import { SortOrder } from '@jellyfin/sdk/lib/generated-client/models/sort-order'; import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; +import Button from '@mui/material/Button'; import MenuItem from '@mui/material/MenuItem'; import Popover from '@mui/material/Popover'; 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 Select, { SelectChangeEvent } from '@mui/material/Select'; @@ -149,16 +148,14 @@ const SortButton: FC = ({ const sortMenuOptions = getSortMenuOptions(viewType); return ( - - + = ({ - + ); }; diff --git a/src/apps/experimental/components/library/ViewSettingsButton.tsx b/src/apps/experimental/components/library/ViewSettingsButton.tsx index 2ee46b6f1..b61a41db6 100644 --- a/src/apps/experimental/components/library/ViewSettingsButton.tsx +++ b/src/apps/experimental/components/library/ViewSettingsButton.tsx @@ -1,25 +1,28 @@ import { ImageType } from '@jellyfin/sdk/lib/generated-client/models/image-type'; import React, { FC, useCallback } from 'react'; -import IconButton from '@mui/material/IconButton'; -import MenuItem from '@mui/material/MenuItem'; +import Check from '@mui/icons-material/Check'; +import MoreVert from '@mui/icons-material/MoreVert'; +import Button from '@mui/material/Button'; 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 InputLabel from '@mui/material/InputLabel'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import MenuItem from '@mui/material/MenuItem'; +import MenuList from '@mui/material/MenuList'; import Popover from '@mui/material/Popover'; -import ViewComfyIcon from '@mui/icons-material/ViewComfy'; +import Select, { SelectChangeEvent } from '@mui/material/Select'; +import Typography from '@mui/material/Typography'; import globalize from 'lib/globalize'; -import { LibraryViewSettings } from 'types/library'; +import { LibraryViewSettings, ViewMode } from 'types/library'; import { LibraryTab } from 'types/libraryTab'; -const excludedViewType = [ +const IMAGE_TYPE_EXCLUDED_VIEWS = [ LibraryTab.Episodes, LibraryTab.Artists, LibraryTab.AlbumArtists, @@ -71,6 +74,20 @@ const ViewSettingsButton: FC = ({ [setLibraryViewSettings] ); + const onGridViewClick = useCallback(() => { + setLibraryViewSettings(prevState => ({ + ...prevState, + ViewMode: ViewMode.GridView + })); + }, [ setLibraryViewSettings ]); + + const onListViewClick = useCallback(() => { + setLibraryViewSettings(prevState => ({ + ...prevState, + ViewMode: ViewMode.ListView + })); + }, [ setLibraryViewSettings ]); + const onSelectChange = useCallback( (event: SelectChangeEvent) => { setLibraryViewSettings((prevState) => ({ @@ -81,19 +98,18 @@ const ViewSettingsButton: FC = ({ [setLibraryViewSettings] ); - const isVisible = !excludedViewType.includes(viewType); + const isGridView = libraryViewSettings.ViewMode === ViewMode.GridView; + const isImageTypeVisible = !IMAGE_TYPE_EXCLUDED_VIEWS.includes(viewType); return ( - - + = ({ '& .MuiFormControl-root': { m: 1, width: 220 } }} > - {isVisible && ( - - - - {globalize.translate('LabelImageType')} - - - - - )} - - - - - } - label={globalize.translate('ShowTitle')} - /> - {isVisible && ( - - } - label={globalize.translate('ShowYear')} - /> + + + + {isGridView && ( + )} - - } - label={globalize.translate('EnableCardLayout')} - /> - - + + {globalize.translate('GridView')} + + + + {!isGridView && ( + + )} + + {globalize.translate('ListView')} + + + + {isGridView && ( + <> + + {isImageTypeVisible && ( + <> + + + + {globalize.translate('LabelImageType')} + + + + + + + )} + + + + } + label={globalize.translate('ShowTitle')} + /> + {isImageTypeVisible && ( + + } + label={globalize.translate('ShowYear')} + /> + )} + + } + label={globalize.translate('EnableCardLayout')} + /> + + + + )} + - + ); }; diff --git a/src/apps/experimental/components/library/filter/FilterButton.tsx b/src/apps/experimental/components/library/filter/FilterButton.tsx index 9442d8361..aed9d360b 100644 --- a/src/apps/experimental/components/library/filter/FilterButton.tsx +++ b/src/apps/experimental/components/library/filter/FilterButton.tsx @@ -1,8 +1,8 @@ import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind'; import React, { FC, useCallback } from 'react'; import ArrowForwardIosSharpIcon from '@mui/icons-material/ArrowForwardIosSharp'; -import Box from '@mui/material/Box'; -import FilterListIcon from '@mui/icons-material/FilterList'; +import FilterAlt from '@mui/icons-material/FilterAlt'; +import Button from '@mui/material/Button'; import Popover from '@mui/material/Popover'; import MuiAccordion, { AccordionProps } from '@mui/material/Accordion'; import MuiAccordionDetails from '@mui/material/AccordionDetails'; @@ -10,7 +10,6 @@ import MuiAccordionSummary, { AccordionSummaryProps } from '@mui/material/AccordionSummary'; import Badge from '@mui/material/Badge'; -import IconButton from '@mui/material/IconButton'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; @@ -158,18 +157,16 @@ const FilterButton: FC = ({ }; return ( - - + = ({ )} - + ); }; diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 6b6fd9324..a59ef8524 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1666,6 +1666,7 @@ "ViewAlbumArtist": "View album artist", "ViewLyrics": "View lyrics", "ViewPlaybackInfo": "View playback info", + "ViewSettings": "View settings", "Watched": "Watched", "Wednesday": "Wednesday", "WeeklyAt": "{0}s at {1}", From 92048bb3982c5f13803da6119f2d2269708b12c0 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 16 Apr 2025 18:35:16 -0400 Subject: [PATCH 2/5] Enable shuffle in songs view --- src/apps/experimental/routes/music/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/experimental/routes/music/index.tsx b/src/apps/experimental/routes/music/index.tsx index 98e1b125a..566c63ea8 100644 --- a/src/apps/experimental/routes/music/index.tsx +++ b/src/apps/experimental/routes/music/index.tsx @@ -39,6 +39,7 @@ const playlistsTabContent: LibraryTabContent = { const songsTabContent: LibraryTabContent = { viewType: LibraryTab.Songs, + isBtnShuffleEnabled: true, isBtnGridListEnabled: false, isAlphabetPickerEnabled: false, itemType: [BaseItemKind.Audio] From 9371c2a19081fc3850ea4d516d496129a1c88128 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Wed, 16 Apr 2025 18:36:07 -0400 Subject: [PATCH 3/5] Hide library actions while loading --- .../components/library/ItemsView.tsx | 78 ++++++++++--------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index c6d43d625..4ac78a0d5 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -76,7 +76,7 @@ const ItemsView: FC = ({ const { __legacyApiClient__ } = useApi(); const { - isLoading, + isPending, data: itemsResult, isPlaceholderData, refetch @@ -258,44 +258,48 @@ const ItemsView: FC = ({ justifyContent: 'end' }} > - - {isBtnPlayAllEnabled && ( - - )} + {!isPending && ( + <> + + {isBtnPlayAllEnabled && ( + + )} - {isBtnShuffleEnabled && totalRecordCount > 1 && ( - - )} + {isBtnShuffleEnabled && totalRecordCount > 1 && ( + + )} - {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( - - )} - + {isBtnQueueEnabled && item && playbackManager.canQueue(item) && ( + + )} + - {isBtnNewCollectionEnabled && } + {isBtnNewCollectionEnabled && } + + )} = ({ /> )} - {isLoading ? ( + {isPending ? ( ) : ( Date: Fri, 2 May 2025 17:21:40 -0400 Subject: [PATCH 4/5] Update library controls layout for mobile --- .../components/library/ItemsView.tsx | 116 +++++++++--------- .../library/NewCollectionButton.tsx | 16 ++- .../components/library/Pagination.tsx | 70 +++++++++-- .../components/library/PlayAllButton.tsx | 26 ++-- 4 files changed, 152 insertions(+), 76 deletions(-) diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index 4ac78a0d5..7c8834f87 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -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 = ({ 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 = ({ ); return ( - + = ({ }} > + + + {isBtnFilterEnabled && ( + + )} + + {isBtnSortEnabled && ( + + )} + + {isBtnGridListEnabled && ( + + )} + + + = ({ <> {isBtnPlayAllEnabled && ( = ({ items={items} viewType={viewType} hasFilters={hasFilters} + isTextVisible={isSmallScreen} libraryViewSettings={libraryViewSettings} /> )} @@ -282,7 +325,7 @@ const ItemsView: FC = ({ items={items} viewType={viewType} hasFilters={hasFilters} - isTextVisible={!isBtnPlayAllEnabled} + isTextVisible={isSmallScreen && !isBtnPlayAllEnabled} libraryViewSettings={libraryViewSettings} /> )} @@ -292,12 +335,12 @@ const ItemsView: FC = ({ item={item} items={items} hasFilters={hasFilters} - isTextVisible={!isBtnPlayAllEnabled && !isBtnShuffleEnabled} + isTextVisible={isSmallScreen && !isBtnPlayAllEnabled && !isBtnShuffleEnabled} /> )} - {isBtnNewCollectionEnabled && } + {isBtnNewCollectionEnabled && } )} @@ -310,51 +353,14 @@ const ItemsView: FC = ({ xs: '100%', md: 'auto' }, - flexGrow: 1 + flexGrow: 1, + marginTop: { + xs: 0.5, + sm: 0 + } }} > - - - {isBtnFilterEnabled && ( - - )} - - {isBtnSortEnabled && ( - - )} - - {isBtnGridListEnabled && ( - - )} - - - - {isPaginationEnabled && ( + {!isPending && isPaginationEnabled && ( = ({ )} - {isPaginationEnabled && ( + {!isPending && isPaginationEnabled && ( { +interface NewCollectionButtonProps { + isTextVisible: boolean +} + +const NewCollectionButton: FC = ({ + isTextVisible +}) => { const showCollectionEditor = useCallback(() => { import('components/collectionEditor/collectionEditor').then( ({ default: CollectionEditor }) => { @@ -24,10 +30,14 @@ const NewCollectionButton: FC = () => { return ( ); }; diff --git a/src/apps/experimental/components/library/Pagination.tsx b/src/apps/experimental/components/library/Pagination.tsx index 782271271..447357378 100644 --- a/src/apps/experimental/components/library/Pagination.tsx +++ b/src/apps/experimental/components/library/Pagination.tsx @@ -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 = ({ 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 = ({ spacing={0.5} sx={{ alignItems: 'center', - marginLeft: 0.5 + flexGrow: { + xs: 1, + md: 0 + }, + marginLeft: { + xs: 0, + sm: 0.5 + } }} > - - {globalize.translate( - 'ListPaging', - recordsStart, - recordsEnd, - totalRecordCount - )} + {!isSmallScreen && ( + + )} + + + + {globalize.translate( + 'ListPaging', + recordsStart, + recordsEnd, + totalRecordCount + )} + - {showControls && ( + + {isSmallScreen && ( )} + + {!isSmallScreen && ( + + )} ); }; diff --git a/src/apps/experimental/components/library/PlayAllButton.tsx b/src/apps/experimental/components/library/PlayAllButton.tsx index 4e9a1a47d..d02fcea5e 100644 --- a/src/apps/experimental/components/library/PlayAllButton.tsx +++ b/src/apps/experimental/components/library/PlayAllButton.tsx @@ -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 = ({ item, items, viewType, hasFilters, libraryViewSettings }) => { +const PlayAllButton: FC = ({ + item, + items, + viewType, + hasFilters, + isTextVisible, + libraryViewSettings +}) => { const play = useCallback(() => { if (item && !hasFilters) { playbackManager.play({ @@ -49,10 +57,14 @@ const PlayAllButton: FC = ({ item, items, viewType, hasFilte return ( ); }; From 3e2e2cf51d2405d26475cf6caca29d9ca88363d7 Mon Sep 17 00:00:00 2001 From: Bill Thornton Date: Fri, 2 May 2025 17:34:51 -0400 Subject: [PATCH 5/5] Fix library controls layout at small breakpoint --- src/apps/experimental/components/library/ItemsView.tsx | 4 ++-- src/apps/experimental/components/library/Pagination.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index 7c8834f87..ae985b22e 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -255,7 +255,7 @@ const ItemsView: FC = ({ sx={{ flexGrow: { xs: 1, - md: 0 + sm: 0 }, marginRight: 1 }} @@ -351,7 +351,7 @@ const ItemsView: FC = ({ justifyContent: 'end', flexBasis: { xs: '100%', - md: 'auto' + sm: 'auto' }, flexGrow: 1, marginTop: { diff --git a/src/apps/experimental/components/library/Pagination.tsx b/src/apps/experimental/components/library/Pagination.tsx index 447357378..d803ded46 100644 --- a/src/apps/experimental/components/library/Pagination.tsx +++ b/src/apps/experimental/components/library/Pagination.tsx @@ -60,7 +60,7 @@ const Pagination: FC = ({ alignItems: 'center', flexGrow: { xs: 1, - md: 0 + sm: 0 }, marginLeft: { xs: 0,