navidrome/ui/src/common/useSelectedFields.js
Aldrin Jenson cf8ee251ee
Option to toggle fields in songs, albums & artists (#923)
* Add toggleColumns

- Add logic for toggling columns
- Add MenuComponent + useSelectedFields hook

* Refactoring

* eslint-fixes

* Typo

* skip menu in albumGridView

* add omittedFields

* Add toggling for playlists and albumSong

* Refactoring

* defaultProps - fix

* Add toggling for PlaylistSongs

* remove accidental console log

* Refactoring for future compatibility

* Hide ToggleMenu in albumGridView

* Add TopBarComponent in ToggleFieldsMenu

* Add defaultOff for useSelectedFields

* Fix edge case

* eslint fix

* Refactoring

* Add propType for forwardRef

* Fix issues

* add translation for grid and table

* add translation for grid and table

* Ignore menuBtn for spotify-ish and Ligera themes

* hide bpm by default in playlistSongs

* Add memoization

* Default album view must be Grid

Co-authored-by: Deluan <deluan@navidrome.org>
2021-05-24 11:09:06 -04:00

79 lines
2 KiB
JavaScript

import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import { useDispatch, useSelector } from 'react-redux'
import { setOmittedFields, setToggleableFields } from '../actions'
const useSelectedFields = ({
resource,
columns,
omittedColumns = [],
defaultOff = [],
}) => {
const dispatch = useDispatch()
const resourceFields = useSelector(
(state) => state.settings.toggleableFields
)?.[resource]
const omittedFields = useSelector((state) => state.settings.omittedFields)?.[
resource
]
const [filteredComponents, setFilteredComponents] = useState([])
useEffect(() => {
if (
!resourceFields ||
Object.keys(resourceFields).length !== Object.keys(columns).length
) {
const obj = {}
for (const key of Object.keys(columns)) {
obj[key] = !defaultOff.includes(key)
}
dispatch(setToggleableFields({ [resource]: obj }))
}
if (!omittedFields) {
dispatch(setOmittedFields({ [resource]: omittedColumns }))
}
}, [
columns,
defaultOff,
dispatch,
omittedColumns,
omittedFields,
resource,
resourceFields,
])
useEffect(() => {
if (resourceFields) {
const filtered = []
const omitted = omittedColumns
for (const [key, val] of Object.entries(columns)) {
if (!val) omitted.push(key)
else if (resourceFields[key]) filtered.push(val)
}
if (filteredComponents.length !== filtered.length)
setFilteredComponents(filtered)
if (omittedFields.length !== omitted.length)
dispatch(setOmittedFields({ [resource]: omitted }))
}
}, [
resourceFields,
columns,
dispatch,
omittedColumns,
omittedFields,
resource,
filteredComponents.length,
])
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),
}