Listenbrainz scrobbling (#1424)

* Refactor session_keys to its own package

* Adjust play_tracker

- Don't send external NowPlaying/Scrobble for tracks with unknown artist
- Continue to the next agent on error

* Implement ListenBrainz Agent and Auth Router

* Implement frontend for ListenBrainz linking

* Update listenBrainzRequest

- Don't marshal Player to json
- Rename Track to Title

* Return ErrRetryLater on ListenBrainz server errors

* Add tests for listenBrainzAgent

* Add tests for ListenBrainz Client

* Adjust ListenBrainzTokenDialog to handle errors better

* Refactor listenbrainz.formatListen and listenBrainzRequest structs

* Refactor agent auth_routers

* Refactor session_keys to agents package

* Add test for listenBrainzResponse

* Add tests for ListenBrainz auth_router

* Update ListenBrainzTokenDialog and auth_router

* Adjust player scrobble toggle
This commit is contained in:
Steve Richter
2021-10-30 12:17:42 -04:00
committed by GitHub
parent ccc871d1f7
commit a56d5bc850
33 changed files with 1214 additions and 54 deletions
@@ -0,0 +1,61 @@
import { useEffect, useState } from 'react'
import { useNotify, useTranslate } from 'react-admin'
import { FormControl, FormControlLabel, Switch } from '@material-ui/core'
import { httpClient } from '../dataProvider'
import { ListenBrainzTokenDialog } from '../dialogs'
import { useDispatch } from 'react-redux'
import { openListenBrainzTokenDialog } from '../actions'
export const ListenBrainzScrobbleToggle = () => {
const dispatch = useDispatch()
const notify = useNotify()
const translate = useTranslate()
const [linked, setLinked] = useState(null)
const toggleScrobble = () => {
if (linked) {
httpClient('/api/listenbrainz/link', { method: 'DELETE' })
.then(() => {
setLinked(false)
notify('message.listenBrainzUnlinkSuccess', 'success')
})
.catch(() => notify('message.listenBrainzUnlinkFailure', 'warning'))
} else {
dispatch(openListenBrainzTokenDialog())
}
}
useEffect(() => {
httpClient('/api/listenbrainz/link')
.then((response) => {
setLinked(response.json.status === true)
})
.catch(() => {
setLinked(false)
})
}, [])
return (
<>
<FormControl>
<FormControlLabel
control={
<Switch
id={'listenbrainz'}
color="primary"
checked={linked === true}
disabled={linked === null}
onChange={toggleScrobble}
/>
}
label={
<span>
{translate('menu.personal.options.listenBrainzScrobbling')}
</span>
}
/>
</FormControl>
<ListenBrainzTokenDialog setLinked={setLinked} />
</>
)
}
+2
View File
@@ -6,6 +6,7 @@ import { SelectTheme } from './SelectTheme'
import { SelectDefaultView } from './SelectDefaultView'
import { NotificationsToggle } from './NotificationsToggle'
import { LastfmScrobbleToggle } from './LastfmScrobbleToggle'
import { ListenBrainzScrobbleToggle } from './ListenBrainzScrobbleToggle'
import config from '../config'
const useStyles = makeStyles({
@@ -25,6 +26,7 @@ const Personal = () => {
<SelectDefaultView />
<NotificationsToggle />
{config.lastFMEnabled && <LastfmScrobbleToggle />}
{config.devListenBrainzEnabled && <ListenBrainzScrobbleToggle />}
</SimpleForm>
</Card>
)