Merge 420706815d
into 1e96b858a9
This commit is contained in:
commit
11617be2e0
|
@ -1,6 +1,7 @@
|
|||
export const SET_NOTIFICATIONS_STATE = 'SET_NOTIFICATIONS_STATE'
|
||||
export const SET_TOGGLEABLE_FIELDS = 'SET_TOGGLEABLE_FIELDS'
|
||||
export const SET_OMITTED_FIELDS = 'SET_OMITTED_FIELDS'
|
||||
export const SET_PLAYER_RATING_CONTROL = 'SET_PLAYER_RATING_CONTROL'
|
||||
|
||||
export const setNotificationsState = (enabled) => ({
|
||||
type: SET_NOTIFICATIONS_STATE,
|
||||
|
@ -16,3 +17,8 @@ export const setOmittedFields = (obj) => ({
|
|||
type: SET_OMITTED_FIELDS,
|
||||
data: obj,
|
||||
})
|
||||
|
||||
export const setPlayerRatingControl = (obj) => ({
|
||||
type: SET_PLAYER_RATING_CONTROL,
|
||||
data: obj,
|
||||
})
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
import React, { useCallback } from 'react'
|
||||
import { useGetOne } from 'react-admin'
|
||||
import { GlobalHotKeys } from 'react-hotkeys'
|
||||
import { LoveButton, useToggleLove } from '../common'
|
||||
import { LoveButton, RatingField, useToggleLove } from '../common'
|
||||
import { keyMap } from '../hotkeys'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
const Placeholder = () => <LoveButton disabled={true} resource={'song'} />
|
||||
const Placeholder = () => {
|
||||
const playerRatingControl = useSelector(
|
||||
(state) => state.settings.playerRatingControl,
|
||||
)
|
||||
|
||||
switch (playerRatingControl) {
|
||||
case 'love':
|
||||
return <LoveButton disabled={true} resource={'song'} />
|
||||
case 'rating':
|
||||
return (
|
||||
<RatingField
|
||||
disabled={true}
|
||||
source={'rating'}
|
||||
resource={'song'}
|
||||
size={'small'}
|
||||
/>
|
||||
)
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const Toolbar = ({ id }) => {
|
||||
const playerRatingControl = useSelector(
|
||||
(state) => state.settings.playerRatingControl,
|
||||
)
|
||||
const { data, loading } = useGetOne('song', id)
|
||||
const [toggleLove, toggling] = useToggleLove('song', data)
|
||||
|
||||
|
@ -14,16 +38,31 @@ const Toolbar = ({ id }) => {
|
|||
TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
|
||||
<LoveButton
|
||||
record={data}
|
||||
resource={'song'}
|
||||
disabled={loading || toggling}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
switch (playerRatingControl) {
|
||||
case 'love':
|
||||
return (
|
||||
<>
|
||||
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
|
||||
<LoveButton
|
||||
record={data}
|
||||
resource={'song'}
|
||||
disabled={loading || toggling}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
case 'rating':
|
||||
return (
|
||||
<RatingField
|
||||
record={data}
|
||||
source={'rating'}
|
||||
resource={'song'}
|
||||
size={'small'}
|
||||
disabled={loading || toggling}
|
||||
/>
|
||||
)
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
const PlayerToolbar = ({ id, isRadio }) =>
|
||||
|
|
|
@ -26,6 +26,7 @@ export const RatingField = ({
|
|||
className,
|
||||
size,
|
||||
color,
|
||||
disabled,
|
||||
...rest
|
||||
}) => {
|
||||
const record = useRecordContext(rest) || {}
|
||||
|
@ -43,6 +44,11 @@ export const RatingField = ({
|
|||
[rate],
|
||||
)
|
||||
|
||||
// If the rating is not yet loaded or unset, it will be `undefined`.
|
||||
// material-ui uses an `null` to indicate an unset value.
|
||||
// Passing `undefined` will switch the component into "uncontrolled" mode.
|
||||
const ratingValue = rating ?? null
|
||||
|
||||
return (
|
||||
<span onClick={(e) => stopPropagation(e)}>
|
||||
<Rating
|
||||
|
@ -52,10 +58,11 @@ export const RatingField = ({
|
|||
classes.rating,
|
||||
rating > 0 ? classes.show : classes.hide,
|
||||
)}
|
||||
value={rating}
|
||||
value={ratingValue}
|
||||
size={size}
|
||||
emptyIcon={<StarBorderIcon fontSize="inherit" />}
|
||||
onChange={(e, newValue) => handleRating(e, newValue)}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</span>
|
||||
)
|
||||
|
@ -64,6 +71,7 @@ RatingField.propTypes = {
|
|||
resource: PropTypes.string.isRequired,
|
||||
record: PropTypes.object,
|
||||
visible: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
size: PropTypes.string,
|
||||
}
|
||||
|
||||
|
@ -71,4 +79,5 @@ RatingField.defaultProps = {
|
|||
visible: true,
|
||||
size: 'small',
|
||||
color: 'inherit',
|
||||
disabled: false,
|
||||
}
|
||||
|
|
|
@ -400,6 +400,12 @@
|
|||
"none": "Disabled",
|
||||
"album": "Use Album Gain",
|
||||
"track": "Use Track Gain"
|
||||
},
|
||||
"playerRatingControl": "Player rating control",
|
||||
"playerRatingControls": {
|
||||
"none": "None",
|
||||
"love": "Love",
|
||||
"rating": "Rating"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@ import { LastfmScrobbleToggle } from './LastfmScrobbleToggle'
|
|||
import { ListenBrainzScrobbleToggle } from './ListenBrainzScrobbleToggle'
|
||||
import config from '../config'
|
||||
import { ReplayGainToggle } from './ReplayGainToggle'
|
||||
import { SelectPlayerRatingControl } from './SelectPlayerRatingControl'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: { marginTop: '1em' },
|
||||
|
@ -26,6 +27,7 @@ const Personal = () => {
|
|||
<SelectLanguage />
|
||||
<SelectDefaultView />
|
||||
{config.enableReplayGain && <ReplayGainToggle />}
|
||||
<SelectPlayerRatingControl />
|
||||
<NotificationsToggle />
|
||||
{config.lastFMEnabled && <LastfmScrobbleToggle />}
|
||||
{config.listenBrainzEnabled && <ListenBrainzScrobbleToggle />}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import { SelectInput, useTranslate } from 'react-admin'
|
||||
import { setPlayerRatingControl } from '../actions/settings'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
export const SelectPlayerRatingControl = (props) => {
|
||||
const translate = useTranslate()
|
||||
const dispatch = useDispatch()
|
||||
const current = useSelector((state) => state.settings.playerRatingControl)
|
||||
const choices = [
|
||||
{
|
||||
id: 'none',
|
||||
name: translate(`menu.personal.options.playerRatingControls.none`),
|
||||
},
|
||||
{
|
||||
id: 'love',
|
||||
name: translate(`menu.personal.options.playerRatingControls.love`),
|
||||
},
|
||||
{
|
||||
id: 'rating',
|
||||
name: translate(`menu.personal.options.playerRatingControls.rating`),
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<SelectInput
|
||||
{...props}
|
||||
source="playerRatingControl"
|
||||
label={translate('menu.personal.options.playerRatingControl')}
|
||||
defaultValue={current}
|
||||
choices={choices}
|
||||
translateChoice={false}
|
||||
onChange={(event) => {
|
||||
dispatch(setPlayerRatingControl(event.target.value))
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -2,12 +2,14 @@ import {
|
|||
SET_NOTIFICATIONS_STATE,
|
||||
SET_OMITTED_FIELDS,
|
||||
SET_TOGGLEABLE_FIELDS,
|
||||
SET_PLAYER_RATING_CONTROL,
|
||||
} from '../actions'
|
||||
|
||||
const initialState = {
|
||||
notifications: false,
|
||||
toggleableFields: {},
|
||||
omittedFields: {},
|
||||
playerRatingControl: localStorage.getItem('playerRating') ?? 'love',
|
||||
}
|
||||
|
||||
export const settingsReducer = (previousState = initialState, payload) => {
|
||||
|
@ -34,6 +36,12 @@ export const settingsReducer = (previousState = initialState, payload) => {
|
|||
...data,
|
||||
},
|
||||
}
|
||||
case SET_PLAYER_RATING_CONTROL:
|
||||
localStorage.setItem('playerRating', data)
|
||||
return {
|
||||
...previousState,
|
||||
playerRatingControl: data,
|
||||
}
|
||||
default:
|
||||
return previousState
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue