diff --git a/ui/src/album/AlbumActions.js b/ui/src/album/AlbumActions.js index 95ad15363..f86c47475 100644 --- a/ui/src/album/AlbumActions.js +++ b/ui/src/album/AlbumActions.js @@ -16,7 +16,7 @@ import subsonic from '../subsonic' import { formatBytes } from '../utils' import { useMediaQuery, makeStyles } from '@material-ui/core' import config from '../config' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ToggleFieldsMenu } from '../common' const useStyles = makeStyles({ toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' }, diff --git a/ui/src/album/AlbumList.js b/ui/src/album/AlbumList.js index 809f9bfd4..b8fbabd6d 100644 --- a/ui/src/album/AlbumList.js +++ b/ui/src/album/AlbumList.js @@ -1,5 +1,5 @@ -import React, { useEffect } from 'react' -import { useSelector, useDispatch } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import { Redirect, useLocation } from 'react-router-dom' import { AutocompleteInput, @@ -13,14 +13,19 @@ import { } from 'react-admin' import FavoriteIcon from '@material-ui/icons/Favorite' import { withWidth } from '@material-ui/core' -import { List, QuickFilter, Title, useAlbumsPerPage } from '../common' +import { + List, + QuickFilter, + Title, + useAlbumsPerPage, + useSetToggleableFields, +} from '../common' import AlbumListActions from './AlbumListActions' import AlbumTableView from './AlbumTableView' import AlbumGridView from './AlbumGridView' import { AddToPlaylistDialog } from '../dialogs' import albumLists, { defaultAlbumList } from './albumLists' import config from '../config' -import { setToggleableFields, setOmittedFields } from '../actions' const AlbumFilter = (props) => { const translate = useTranslate() @@ -66,10 +71,6 @@ const AlbumList = (props) => { const albumView = useSelector((state) => state.albumView) const [perPage, perPageOptions] = useAlbumsPerPage(width) const location = useLocation() - const toggleableAlbumFields = useSelector( - (state) => state.settings.toggleableFields - )?.album - const dispatch = useDispatch() const albumListType = location.pathname .replace(/^\/album/, '') @@ -78,24 +79,14 @@ const AlbumList = (props) => { // 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 - - useEffect(() => { - if (!toggleableAlbumFields) { - dispatch( - setToggleableFields({ - album: { - artist: true, - songCount: true, - playCount: true, - year: true, - duration: true, - rating: true, - }, - }) - ) - dispatch(setOmittedFields({ album: [] })) - } - }, [dispatch, toggleableAlbumFields]) + useSetToggleableFields('album', [ + 'artist', + 'songCount', + 'playCount', + 'year', + 'duration', + 'rating', + ]) // If it does not have filter/sort params (usually coming from Menu), // reload with correct filter/sort params diff --git a/ui/src/album/AlbumListActions.js b/ui/src/album/AlbumListActions.js index 662d94550..801672e46 100644 --- a/ui/src/album/AlbumListActions.js +++ b/ui/src/album/AlbumListActions.js @@ -15,7 +15,7 @@ import ViewHeadlineIcon from '@material-ui/icons/ViewHeadline' import ViewModuleIcon from '@material-ui/icons/ViewModule' import { useDispatch, useSelector } from 'react-redux' import { albumViewGrid, albumViewTable } from '../actions' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ToggleFieldsMenu } from '../common' const useStyles = makeStyles({ title: { margin: '1rem' }, diff --git a/ui/src/album/AlbumSongs.js b/ui/src/album/AlbumSongs.js index 307992d9d..08bcf3b46 100644 --- a/ui/src/album/AlbumSongs.js +++ b/ui/src/album/AlbumSongs.js @@ -21,10 +21,10 @@ import { SongDetails, SongTitleField, RatingField, + QualityInfo, + useSelectedFields, } from '../common' import { AddToPlaylistDialog } from '../dialogs' -import { QualityInfo } from '../common/QualityInfo' -import useSelectedFields from '../common/useSelectedFields' import config from '../config' const useStyles = makeStyles( diff --git a/ui/src/album/AlbumTableView.js b/ui/src/album/AlbumTableView.js index b6c298570..f7446f615 100644 --- a/ui/src/album/AlbumTableView.js +++ b/ui/src/album/AlbumTableView.js @@ -26,9 +26,9 @@ import { MultiLineTextField, AlbumContextMenu, RatingField, + useSelectedFields, } from '../common' import config from '../config' -import useSelectedFields from '../common/useSelectedFields' const useStyles = makeStyles({ columnIcon: { diff --git a/ui/src/artist/ArtistList.js b/ui/src/artist/ArtistList.js index dec51ac8d..51d08de11 100644 --- a/ui/src/artist/ArtistList.js +++ b/ui/src/artist/ArtistList.js @@ -10,6 +10,7 @@ import { import { useMediaQuery, withWidth } from '@material-ui/core' import FavoriteIcon from '@material-ui/icons/Favorite' import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder' +import { makeStyles } from '@material-ui/core/styles' import { AddToPlaylistDialog } from '../dialogs' import { ArtistContextMenu, @@ -18,11 +19,10 @@ import { useGetHandleArtistClick, ArtistSimpleList, RatingField, + useSelectedFields, } from '../common' -import { makeStyles } from '@material-ui/core/styles' import config from '../config' import ArtistListActions from './ArtistListActions' -import useSelectedFields from '../common/useSelectedFields' const useStyles = makeStyles({ contextHeader: { diff --git a/ui/src/artist/ArtistListActions.js b/ui/src/artist/ArtistListActions.js index a1aa4c089..946557670 100644 --- a/ui/src/artist/ArtistListActions.js +++ b/ui/src/artist/ArtistListActions.js @@ -1,7 +1,7 @@ import React from 'react' import { sanitizeListRestProps, TopToolbar } from 'react-admin' import { useMediaQuery } from '@material-ui/core' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ToggleFieldsMenu } from '../common' const ArtistListActions = ({ className, ...rest }) => { const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm')) diff --git a/ui/src/audioplayer/Player.js b/ui/src/audioplayer/Player.js index a02d03ae0..8489616da 100644 --- a/ui/src/audioplayer/Player.js +++ b/ui/src/audioplayer/Player.js @@ -26,7 +26,7 @@ import PlayerToolbar from './PlayerToolbar' import { sendNotification } from '../utils' import { keyMap } from '../hotkeys' import useCurrentTheme from '../themes/useCurrentTheme' -import { QualityInfo } from '../common/QualityInfo' +import { QualityInfo } from '../common' const useStyle = makeStyles( (theme) => ({ diff --git a/ui/src/common/ToggleFieldsMenu.js b/ui/src/common/ToggleFieldsMenu.js index cdae143e9..eb90fdabf 100644 --- a/ui/src/common/ToggleFieldsMenu.js +++ b/ui/src/common/ToggleFieldsMenu.js @@ -27,7 +27,10 @@ const useStyles = makeStyles({ }, }) -const ToggleFieldsMenu = ({ resource, topbarComponent: TopBarComponent }) => { +export const ToggleFieldsMenu = ({ + resource, + topbarComponent: TopBarComponent, +}) => { const [anchorEl, setAnchorEl] = useState(null) const dispatch = useDispatch() const translate = useTranslate() @@ -101,8 +104,6 @@ const ToggleFieldsMenu = ({ resource, topbarComponent: TopBarComponent }) => { ) } -export default ToggleFieldsMenu - ToggleFieldsMenu.propTypes = { resource: PropTypes.string.isRequired, topbarComponent: PropTypes.elementType, diff --git a/ui/src/common/index.js b/ui/src/common/index.js index a7a8a50ee..2aba393eb 100644 --- a/ui/src/common/index.js +++ b/ui/src/common/index.js @@ -30,3 +30,6 @@ export * from './SongSimpleList' export * from './ArtistSimpleList' export * from './RatingField' export * from './useRating' +export * from './useSelectedFields' +export * from './ToggleFieldsMenu' +export * from './QualityInfo' diff --git a/ui/src/common/useSelectedFields.js b/ui/src/common/useSelectedFields.js index 6e3d40c74..7ebdcf60e 100644 --- a/ui/src/common/useSelectedFields.js +++ b/ui/src/common/useSelectedFields.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import { useDispatch, useSelector } from 'react-redux' import { setOmittedFields, setToggleableFields } from '../actions' -const useSelectedFields = ({ +export const useSelectedFields = ({ resource, columns, omittedColumns = [], @@ -69,11 +69,39 @@ const useSelectedFields = ({ return React.Children.toArray(filteredComponents) } -export default useSelectedFields - useSelectedFields.propTypes = { resource: PropTypes.string, columns: PropTypes.object, omittedColumns: PropTypes.arrayOf(PropTypes.string), defaultOff: PropTypes.arrayOf(PropTypes.string), } + +export const useSetToggleableFields = ( + resource, + toggleableColumns, + defaultOff = [] +) => { + const current = useSelector((state) => state.settings.toggleableFields)?.album + const dispatch = useDispatch() + useEffect(() => { + if (!current) { + dispatch( + setToggleableFields({ + [resource]: toggleableColumns.reduce((acc, cur) => { + return { + ...acc, + ...{ [cur]: true }, + } + }, {}), + }) + ) + dispatch(setOmittedFields({ [resource]: defaultOff })) + } + }, [resource, toggleableColumns, dispatch, current, defaultOff]) +} + +useSetToggleableFields.propTypes = { + resource: PropTypes.string, + toggleableColumns: PropTypes.arrayOf(PropTypes.string), + defaultOff: PropTypes.arrayOf(PropTypes.string), +} diff --git a/ui/src/playlist/PlaylistActions.js b/ui/src/playlist/PlaylistActions.js index 3987e4180..4273d27cb 100644 --- a/ui/src/playlist/PlaylistActions.js +++ b/ui/src/playlist/PlaylistActions.js @@ -21,7 +21,7 @@ import PropTypes from 'prop-types' import { formatBytes } from '../utils' import { useMediaQuery, makeStyles } from '@material-ui/core' import config from '../config' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ToggleFieldsMenu } from '../common' const useStyles = makeStyles({ toolbar: { display: 'flex', justifyContent: 'space-between', width: '100%' }, diff --git a/ui/src/playlist/PlaylistList.js b/ui/src/playlist/PlaylistList.js index 320f16c5e..8a1c68210 100644 --- a/ui/src/playlist/PlaylistList.js +++ b/ui/src/playlist/PlaylistList.js @@ -12,8 +12,13 @@ import { } from 'react-admin' import Switch from '@material-ui/core/Switch' import { useMediaQuery } from '@material-ui/core' -import { DurationField, List, Writable, isWritable } from '../common' -import useSelectedFields from '../common/useSelectedFields' +import { + DurationField, + List, + Writable, + isWritable, + useSelectedFields, +} from '../common' import PlaylistListActions from './PlaylistListActions' const PlaylistFilter = (props) => ( diff --git a/ui/src/playlist/PlaylistListActions.js b/ui/src/playlist/PlaylistListActions.js index 3717dfac7..54998f3e1 100644 --- a/ui/src/playlist/PlaylistListActions.js +++ b/ui/src/playlist/PlaylistListActions.js @@ -6,7 +6,7 @@ import { useTranslate, } from 'react-admin' import { useMediaQuery } from '@material-ui/core' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ToggleFieldsMenu } from '../common' const PlaylistListActions = ({ className, ...rest }) => { const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm')) diff --git a/ui/src/playlist/PlaylistSongs.js b/ui/src/playlist/PlaylistSongs.js index 8a4556864..eebbc2fc4 100644 --- a/ui/src/playlist/PlaylistSongs.js +++ b/ui/src/playlist/PlaylistSongs.js @@ -22,13 +22,13 @@ import { SongContextMenu, SongDatagrid, SongTitleField, + QualityInfo, + useSelectedFields, } from '../common' import { AddToPlaylistDialog } from '../dialogs' import { AlbumLinkField } from '../song/AlbumLinkField' import { playTracks } from '../actions' import PlaylistSongBulkActions from './PlaylistSongBulkActions' -import { QualityInfo } from '../common/QualityInfo' -import useSelectedFields from '../common/useSelectedFields' const useStyles = makeStyles( (theme) => ({ diff --git a/ui/src/song/SongList.js b/ui/src/song/SongList.js index 37017bcb5..61dce6c41 100644 --- a/ui/src/song/SongList.js +++ b/ui/src/song/SongList.js @@ -20,16 +20,14 @@ import { RatingField, } from '../common' import { useDispatch } from 'react-redux' +import { makeStyles } from '@material-ui/core/styles' +import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder' import { setTrack } from '../actions' -import { SongBulkActions } from '../common' import { SongListActions } from './SongListActions' import { AlbumLinkField } from './AlbumLinkField' import { AddToPlaylistDialog } from '../dialogs' -import { makeStyles } from '@material-ui/core/styles' -import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder' +import { SongBulkActions, QualityInfo, useSelectedFields } from '../common' import config from '../config' -import useSelectedFields from '../common/useSelectedFields' -import { QualityInfo } from '../common/QualityInfo' const useStyles = makeStyles({ contextHeader: { diff --git a/ui/src/song/SongListActions.js b/ui/src/song/SongListActions.js index 617b38448..82dbe789e 100644 --- a/ui/src/song/SongListActions.js +++ b/ui/src/song/SongListActions.js @@ -1,8 +1,7 @@ import React, { cloneElement } from 'react' import { sanitizeListRestProps, TopToolbar } from 'react-admin' import { useMediaQuery } from '@material-ui/core' -import { ShuffleAllButton } from '../common' -import ToggleFieldsMenu from '../common/ToggleFieldsMenu' +import { ShuffleAllButton, ToggleFieldsMenu } from '../common' export const SongListActions = ({ currentSort,