@@ -1,26 +1,33 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { useGetOne } from 'react-admin'
|
import { useGetOne } from 'react-admin'
|
||||||
import IconButton from '@material-ui/core/IconButton'
|
import { StarButton, useToggleStar } from '../common'
|
||||||
import StarBorderIcon from '@material-ui/icons/StarBorder'
|
import { useHotkeys } from 'react-hotkeys-hook'
|
||||||
import { StarButton } from '../common'
|
|
||||||
|
|
||||||
const Placeholder = () => (
|
const Placeholder = () => <StarButton disabled={true} />
|
||||||
<IconButton>
|
|
||||||
<StarBorderIcon disabled={true} />
|
|
||||||
</IconButton>
|
|
||||||
)
|
|
||||||
|
|
||||||
const Toolbar = ({ id }) => {
|
const Toolbar = ({ id }) => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const resource = location.pathname.startsWith('/song') ? 'song' : 'albumSong'
|
const resource = location.pathname.startsWith('/song') ? 'song' : 'albumSong'
|
||||||
const { data, loading } = useGetOne(resource, id)
|
const { data, loading } = useGetOne(resource, id)
|
||||||
|
const [toggleStar, toggling] = useToggleStar(resource, data)
|
||||||
|
|
||||||
if (loading) {
|
useHotkeys(
|
||||||
return <Placeholder />
|
's',
|
||||||
}
|
() => {
|
||||||
|
toggleStar()
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
[toggleStar]
|
||||||
|
)
|
||||||
|
|
||||||
return <StarButton record={data} resource={resource} />
|
return (
|
||||||
|
<StarButton
|
||||||
|
record={data}
|
||||||
|
resource={resource}
|
||||||
|
disabled={loading || toggling}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlayerToolbar = ({ id }) => (id ? <Toolbar id={id} /> : <Placeholder />)
|
const PlayerToolbar = ({ id }) => (id ? <Toolbar id={id} /> : <Placeholder />)
|
||||||
|
|||||||
+15
-40
@@ -1,11 +1,10 @@
|
|||||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { useNotify, useDataProvider } from 'react-admin'
|
|
||||||
import StarIcon from '@material-ui/icons/Star'
|
import StarIcon from '@material-ui/icons/Star'
|
||||||
import StarBorderIcon from '@material-ui/icons/StarBorder'
|
import StarBorderIcon from '@material-ui/icons/StarBorder'
|
||||||
import IconButton from '@material-ui/core/IconButton'
|
import IconButton from '@material-ui/core/IconButton'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import subsonic from '../subsonic'
|
import { useToggleStar } from './useToggleStar'
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
star: {
|
star: {
|
||||||
@@ -27,52 +26,26 @@ export const StarButton = ({
|
|||||||
size,
|
size,
|
||||||
component: Button,
|
component: Button,
|
||||||
addLabel,
|
addLabel,
|
||||||
|
disabled,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
const [loading, setLoading] = useState(false)
|
|
||||||
const classes = useStyles({ color, visible, starred: record.starred })
|
const classes = useStyles({ color, visible, starred: record.starred })
|
||||||
const notify = useNotify()
|
const [toggleStar, loading] = useToggleStar(resource, record)
|
||||||
|
|
||||||
const mountedRef = useRef(false)
|
const handleToggleStar = useCallback(
|
||||||
useEffect(() => {
|
(e) => {
|
||||||
mountedRef.current = true
|
e.preventDefault()
|
||||||
return () => {
|
toggleStar()
|
||||||
mountedRef.current = false
|
e.stopPropagation()
|
||||||
}
|
},
|
||||||
}, [])
|
[toggleStar]
|
||||||
|
)
|
||||||
const dataProvider = useDataProvider()
|
|
||||||
|
|
||||||
const refreshRecord = useCallback(() => {
|
|
||||||
dataProvider.getOne(resource, { id: record.id }).then(() => {
|
|
||||||
if (mountedRef.current) {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [dataProvider, record.id, resource])
|
|
||||||
|
|
||||||
const handleToggleStar = (e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
const toggleStar = record.starred ? subsonic.unstar : subsonic.star
|
|
||||||
|
|
||||||
setLoading(true)
|
|
||||||
toggleStar(record.id)
|
|
||||||
.then(refreshRecord)
|
|
||||||
.catch((e) => {
|
|
||||||
console.log('Error toggling star: ', e)
|
|
||||||
notify('ra.page.error', 'warning')
|
|
||||||
if (mountedRef.current) {
|
|
||||||
setLoading(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
e.stopPropagation()
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
onClick={handleToggleStar}
|
onClick={handleToggleStar}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
disabled={loading}
|
disabled={disabled || loading}
|
||||||
className={classes.star}
|
className={classes.star}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
@@ -92,6 +65,7 @@ StarButton.propTypes = {
|
|||||||
color: PropTypes.string,
|
color: PropTypes.string,
|
||||||
size: PropTypes.string,
|
size: PropTypes.string,
|
||||||
component: PropTypes.object,
|
component: PropTypes.object,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
StarButton.defaultProps = {
|
StarButton.defaultProps = {
|
||||||
@@ -101,4 +75,5 @@ StarButton.defaultProps = {
|
|||||||
size: 'small',
|
size: 'small',
|
||||||
color: 'inherit',
|
color: 'inherit',
|
||||||
component: IconButton,
|
component: IconButton,
|
||||||
|
disabled: false,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,5 +23,6 @@ export * from './Title'
|
|||||||
export * from './SongBulkActions'
|
export * from './SongBulkActions'
|
||||||
export * from './useAlbumsPerPage'
|
export * from './useAlbumsPerPage'
|
||||||
export * from './useInterval'
|
export * from './useInterval'
|
||||||
|
export * from './useToggleStar'
|
||||||
export * from './useTraceUpdate'
|
export * from './useTraceUpdate'
|
||||||
export * from './Writable'
|
export * from './Writable'
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
|
import { useDataProvider, useNotify } from 'react-admin'
|
||||||
|
import subsonic from '../subsonic'
|
||||||
|
|
||||||
|
export const useToggleStar = (resource, record) => {
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const notify = useNotify()
|
||||||
|
|
||||||
|
const mountedRef = useRef(false)
|
||||||
|
useEffect(() => {
|
||||||
|
mountedRef.current = true
|
||||||
|
return () => {
|
||||||
|
mountedRef.current = false
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const dataProvider = useDataProvider()
|
||||||
|
|
||||||
|
const refreshRecord = useCallback(() => {
|
||||||
|
dataProvider.getOne(resource, { id: record.id }).then(() => {
|
||||||
|
if (mountedRef.current) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [dataProvider, record.id, resource])
|
||||||
|
|
||||||
|
const toggleStar = () => {
|
||||||
|
const toggle = record.starred ? subsonic.unstar : subsonic.star
|
||||||
|
|
||||||
|
setLoading(true)
|
||||||
|
toggle(record.id)
|
||||||
|
.then(refreshRecord)
|
||||||
|
.catch((e) => {
|
||||||
|
console.log('Error toggling star: ', e)
|
||||||
|
notify('ra.page.error', 'warning')
|
||||||
|
if (mountedRef.current) {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return [toggleStar, loading]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user