mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-20 22:07:43 +03:00
Add "Page Size Multiplier" option
Some users (eg me) prefer in-browser search and scroll to clicking through pages. This attempts to be a minimally-invasive change to enable that workflow. Adds a "Page Size Multiplier" option to the Personal page to allow the user to set the number of items per page to a multiple of the default page size. Also abstracts some of the page sizes from bare integers into constants.
This commit is contained in:
parent
46a963a02a
commit
c0ba4d4684
@ -2,6 +2,7 @@ import React from 'react'
|
||||
import { List as RAList } from 'react-admin'
|
||||
import { Pagination } from './Pagination'
|
||||
import { Title } from './index'
|
||||
import { defaultPageSize } from '../utils/pageSizes'
|
||||
|
||||
export const List = (props) => {
|
||||
const { resource } = props
|
||||
@ -13,7 +14,7 @@ export const List = (props) => {
|
||||
args={{ smart_count: 2 }}
|
||||
/>
|
||||
}
|
||||
perPage={15}
|
||||
perPage={defaultPageSize()}
|
||||
pagination={<Pagination />}
|
||||
{...props}
|
||||
/>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Pagination as RAPagination } from 'react-admin'
|
||||
import { defaultPageSizes } from '../utils/pageSizes'
|
||||
|
||||
export const Pagination = (props) => (
|
||||
<RAPagination rowsPerPageOptions={[15, 25, 50]} {...props} />
|
||||
<RAPagination rowsPerPageOptions={defaultPageSizes()} {...props} />
|
||||
)
|
||||
|
@ -1,19 +1,24 @@
|
||||
import { useSelector } from 'react-redux'
|
||||
import { pageSizeMultiplier } from '../utils/pageSizes'
|
||||
|
||||
const getPerPage = (width) => {
|
||||
if (width === 'xs') return 12
|
||||
if (width === 'sm') return 12
|
||||
if (width === 'md') return 12
|
||||
if (width === 'lg') return 18
|
||||
return 36
|
||||
let baseSize
|
||||
if (width === 'xs') baseSize = 12
|
||||
else if (width === 'sm') baseSize = 12
|
||||
else if (width === 'md') baseSize = 12
|
||||
else if (width === 'lg') baseSize = 18
|
||||
else baseSize = 36
|
||||
return baseSize * pageSizeMultiplier()
|
||||
}
|
||||
|
||||
const getPerPageOptions = (width) => {
|
||||
const options = [3, 6, 12]
|
||||
if (width === 'xs') return [12]
|
||||
if (width === 'sm') return [12]
|
||||
if (width === 'md') return options.map((v) => v * 4)
|
||||
return options.map((v) => v * 6)
|
||||
let sizeOptions
|
||||
if (width === 'xs') sizeOptions = [12]
|
||||
else if (width === 'sm') sizeOptions = [12]
|
||||
else if (width === 'md') sizeOptions = options.map((v) => v * 4)
|
||||
else sizeOptions = options.map((v) => v * 6)
|
||||
return sizeOptions.map((size) => size * pageSizeMultiplier())
|
||||
}
|
||||
|
||||
export const useAlbumsPerPage = (width) => {
|
||||
|
@ -390,6 +390,7 @@
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"defaultView": "Default View",
|
||||
"pageSizeMultiplier": "Page Size Multiplier",
|
||||
"desktop_notifications": "Desktop Notifications",
|
||||
"lastfmNotConfigured": "Last.fm API-Key is not configured",
|
||||
"lastfmScrobbling": "Scrobble to Last.fm",
|
||||
|
@ -4,6 +4,7 @@ import { makeStyles } from '@material-ui/core/styles'
|
||||
import { SelectLanguage } from './SelectLanguage'
|
||||
import { SelectTheme } from './SelectTheme'
|
||||
import { SelectDefaultView } from './SelectDefaultView'
|
||||
import { SelectPageSize } from './SelectPageSize'
|
||||
import { NotificationsToggle } from './NotificationsToggle'
|
||||
import { LastfmScrobbleToggle } from './LastfmScrobbleToggle'
|
||||
import { ListenBrainzScrobbleToggle } from './ListenBrainzScrobbleToggle'
|
||||
@ -25,6 +26,7 @@ const Personal = () => {
|
||||
<SelectTheme />
|
||||
<SelectLanguage />
|
||||
<SelectDefaultView />
|
||||
<SelectPageSize />
|
||||
{config.enableReplayGain && <ReplayGainToggle />}
|
||||
<NotificationsToggle />
|
||||
{config.lastFMEnabled && <LastfmScrobbleToggle />}
|
||||
|
28
ui/src/personal/SelectPageSize.jsx
Normal file
28
ui/src/personal/SelectPageSize.jsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { SelectInput, useTranslate } from 'react-admin'
|
||||
import {
|
||||
pageSizeMultipliers,
|
||||
defaultPageSizeMultiplier,
|
||||
} from '../utils/pageSizes'
|
||||
export const SelectPageSize = (props) => {
|
||||
const translate = useTranslate()
|
||||
const current =
|
||||
localStorage.getItem('pageSizeMultiplier') || defaultPageSizeMultiplier
|
||||
const choices = pageSizeMultipliers.map((v) => ({
|
||||
id: v,
|
||||
name: `× ${v}`,
|
||||
}))
|
||||
|
||||
return (
|
||||
<SelectInput
|
||||
{...props}
|
||||
source="pageSize"
|
||||
label={translate('menu.personal.options.pageSizeMultiplier')}
|
||||
defaultValue={current}
|
||||
choices={choices}
|
||||
translateChoice={false}
|
||||
onChange={(event) => {
|
||||
localStorage.setItem('pageSizeMultiplier', event.target.value)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
16
ui/src/utils/pageSizes.js
Normal file
16
ui/src/utils/pageSizes.js
Normal file
@ -0,0 +1,16 @@
|
||||
/* Groups page-size logic, since it's used in several different parts of the UI */
|
||||
export const defaultPageSizeMultiplier = '1'
|
||||
export const pageSizeMultipliers = ['1', '4', '10', '1000']
|
||||
export const defaultBasePageSize = 15
|
||||
export const defaultBasePageSizes = [15, 25, 50]
|
||||
|
||||
// Stored as a string for consistency, so we provide a getter. Function, not
|
||||
// constant, because it's read from localStorage (which might change)
|
||||
export const pageSizeMultiplier = () =>
|
||||
parseInt(
|
||||
localStorage.getItem('pageSizeMultiplier') || defaultPageSizeMultiplier,
|
||||
)
|
||||
|
||||
export const defaultPageSize = () => defaultBasePageSize * pageSizeMultiplier()
|
||||
export const defaultPageSizes = () =>
|
||||
defaultBasePageSizes.map((size) => size * pageSizeMultiplier())
|
Loading…
x
Reference in New Issue
Block a user