import { useSelector } from 'react-redux' import { Redirect, useLocation } from 'react-router-dom' import { AutocompleteArrayInput, AutocompleteInput, Filter, NullableBooleanInput, NumberInput, Pagination, ReferenceArrayInput, ReferenceInput, SearchInput, useListContext, usePermissions, useRefresh, useTranslate, useVersion, } from 'react-admin' import FavoriteIcon from '@material-ui/icons/Favorite' import { withWidth } from '@material-ui/core' import { List, QuickFilter, Title, useAlbumsPerPage, useResourceRefresh, useSetToggleableFields, } from '../common' import AlbumListActions from './AlbumListActions' import AlbumTableView from './AlbumTableView' import AlbumGridView from './AlbumGridView' import albumLists, { defaultAlbumList } from './albumLists' import config from '../config' import AlbumInfo from './AlbumInfo' import ExpandInfoDialog from '../dialogs/ExpandInfoDialog' import { humanize } from 'inflection' import { makeStyles } from '@material-ui/core/styles' const useStyles = makeStyles({ chip: { margin: 0, height: '24px', }, }) const formatReleaseType = (record) => record?.tagValue ? humanize(record?.tagValue) : '-- None --' const AlbumFilter = (props) => { const classes = useStyles() const translate = useTranslate() const { permissions } = usePermissions() const isAdmin = permissions === 'admin' return ( ({ name: [searchText] })} > ({ name: [searchText] })} > ({ tag_value: [searchText], })} > ({ tag_value: [searchText], })} > ({ tag_value: [searchText], })} > ({ tag_value: [searchText], })} > ({ tag_value: [searchText], })} > {config.enableFavourites && ( } defaultValue={true} /> )} {isAdmin && } ) } const AlbumListTitle = ({ albumListType }) => { const translate = useTranslate() let title = translate('resources.album.name', { smart_count: 2 }) if (albumListType) { let listTitle = translate(`resources.album.lists.${albumListType}`, { smart_count: 2, }) title = `${title} - ${listTitle}` } return } const AlbumListPagination = ({ albumListType, ...rest }) => { const { loading } = useListContext() if (loading && albumListType === 'random') { return null } return <Pagination {...rest} /> } const randomStartingSeed = Math.random().toString() const AlbumList = (props) => { const { width } = props const albumView = useSelector((state) => state.albumView) const [perPage, perPageOptions] = useAlbumsPerPage(width) const location = useLocation() const version = useVersion() const refresh = useRefresh() useResourceRefresh('album') const seed = `${randomStartingSeed}-${version}` const albumListType = location.pathname .replace(/^\/album/, '') .replace(/^\//, '') // Workaround to force album columns to appear the first time. // See https://github.com/navidrome/navidrome/pull/923#issuecomment-833004842 // TODO: Find a better solution useSetToggleableFields( 'album', [ 'artist', 'songCount', 'playCount', 'year', 'mood', 'duration', 'rating', 'size', 'createdAt', ], ['createdAt', 'size'], ) // If it does not have filter/sort params (usually coming from Menu), // reload with correct filter/sort params if (!location.search) { const type = albumListType || localStorage.getItem('defaultView') || defaultAlbumList const listParams = albumLists[type] if (type === 'songs') { return <Redirect to="/song" /> } if (type === 'random') { refresh() } if (listParams) { return <Redirect to={`/album/${type}?${listParams.params}`} /> } } return ( <> <List {...props} exporter={false} bulkActionButtons={false} filter={{ seed }} actions={<AlbumListActions />} filters={<AlbumFilter />} perPage={perPage} pagination={ <AlbumListPagination rowsPerPageOptions={perPageOptions} albumListType={albumListType} /> } title={<AlbumListTitle albumListType={albumListType} />} > {albumView.grid ? ( <AlbumGridView albumListType={albumListType} {...props} /> ) : ( <AlbumTableView {...props} /> )} </List> <ExpandInfoDialog content={<AlbumInfo />} /> </> ) } const AlbumListWithWidth = withWidth()(AlbumList) export default AlbumListWithWidth