Only show SongContextMenu on hover
This commit is contained in:
parent
ae847103a2
commit
978e7f2eaa
|
@ -14,8 +14,12 @@ import { useDispatch } from 'react-redux'
|
|||
import { Card, useMediaQuery } from '@material-ui/core'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { playTracks } from '../audioplayer'
|
||||
import { DurationField, SongDetails, SongDatagridRow } from '../common'
|
||||
import { SongContextMenu } from '../song/SongContextMenu'
|
||||
import {
|
||||
DurationField,
|
||||
SongDetails,
|
||||
SongDatagridRow,
|
||||
SongContextMenu,
|
||||
} from '../common'
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme) => ({
|
||||
|
|
|
@ -9,17 +9,24 @@ import StarIcon from '@material-ui/icons/Star'
|
|||
import StarBorderIcon from '@material-ui/icons/StarBorder'
|
||||
import NestedMenuItem from 'material-ui-nested-menu-item'
|
||||
import { addTracks, setTrack } from '../audioplayer'
|
||||
import { AddToPlaylistMenu } from '../common'
|
||||
import AddToPlaylistMenu from './AddToPlaylistMenu'
|
||||
import config from '../config'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
noWrap: {
|
||||
whiteSpace: 'nowrap',
|
||||
},
|
||||
menu: {
|
||||
visibility: (props) => (props.visible ? 'visible' : 'hidden'),
|
||||
},
|
||||
star: {
|
||||
visibility: (props) =>
|
||||
props.visible || props.starred ? 'visible' : 'hidden',
|
||||
},
|
||||
})
|
||||
|
||||
export const SongContextMenu = ({ className, record, onAddToPlaylist }) => {
|
||||
const classes = useStyles()
|
||||
const SongContextMenu = ({ record, onAddToPlaylist, visible }) => {
|
||||
const classes = useStyles({ visible, starred: record.starred })
|
||||
const dispatch = useDispatch()
|
||||
const translate = useTranslate()
|
||||
const notify = useNotify()
|
||||
|
@ -54,7 +61,7 @@ export const SongContextMenu = ({ className, record, onAddToPlaylist }) => {
|
|||
e.stopPropagation()
|
||||
}
|
||||
|
||||
const [toggleStar, { toggling: loading }] = useUpdate(
|
||||
const [updateRecord, { loading: updating }] = useUpdate(
|
||||
'albumSong',
|
||||
record.id,
|
||||
record,
|
||||
|
@ -68,26 +75,36 @@ export const SongContextMenu = ({ className, record, onAddToPlaylist }) => {
|
|||
}
|
||||
)
|
||||
|
||||
const handleToggleStar = (e, record) => {
|
||||
const toggleStar = (record) => {
|
||||
record.starred = !record.starred
|
||||
toggleStar()
|
||||
updateRecord()
|
||||
}
|
||||
|
||||
const handleToggleStar = (e, record) => {
|
||||
toggleStar(record)
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
const open = Boolean(anchorEl)
|
||||
|
||||
return (
|
||||
<span className={`${classes.noWrap} ${className}`}>
|
||||
<span className={classes.noWrap}>
|
||||
{config.enableStarred && !onAddToPlaylist && (
|
||||
<IconButton
|
||||
onClick={(e) => handleToggleStar(e, record)}
|
||||
size={'small'}
|
||||
disabled={loading}
|
||||
disabled={updating}
|
||||
className={classes.star}
|
||||
>
|
||||
{record.starred ? <StarIcon /> : <StarBorderIcon />}
|
||||
</IconButton>
|
||||
)}
|
||||
<IconButton onClick={handleClick} size={'small'}>
|
||||
<IconButton
|
||||
onClick={handleClick}
|
||||
size={'small'}
|
||||
className={classes.menu}
|
||||
disabled={updating}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
|
@ -119,4 +136,7 @@ export const SongContextMenu = ({ className, record, onAddToPlaylist }) => {
|
|||
SongContextMenu.propTypes = {
|
||||
record: PropTypes.object,
|
||||
onAddToPlaylist: PropTypes.func,
|
||||
visible: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default SongContextMenu
|
|
@ -1,17 +1,18 @@
|
|||
import React from 'react'
|
||||
import React, { useState, isValidElement, cloneElement } from 'react'
|
||||
import { DatagridRow, useTranslate } from 'react-admin'
|
||||
import { TableRow, TableCell, Typography } from '@material-ui/core'
|
||||
import { TableCell, TableRow, Typography } from '@material-ui/core'
|
||||
import PropTypes from 'prop-types'
|
||||
import RangeField from './RangeField'
|
||||
|
||||
const SongDatagridRow = ({ record, children, multiDisc, ...rest }) => {
|
||||
const translate = useTranslate()
|
||||
const [visible, setVisible] = useState(false)
|
||||
return (
|
||||
<>
|
||||
{multiDisc && (
|
||||
<TableRow>
|
||||
{record.trackNumber === 1 && (
|
||||
<TableCell colSpan={children.length + 1}>
|
||||
<TableCell colSpan={children.length + 2}>
|
||||
<Typography variant="h6">
|
||||
{record.discSubtitle
|
||||
? translate('message.discSubtitle', {
|
||||
|
@ -26,8 +27,19 @@ const SongDatagridRow = ({ record, children, multiDisc, ...rest }) => {
|
|||
)}
|
||||
</TableRow>
|
||||
)}
|
||||
<DatagridRow record={record} {...rest}>
|
||||
{children}
|
||||
<DatagridRow
|
||||
record={record}
|
||||
onMouseEnter={() => setVisible(true)}
|
||||
onMouseLeave={() => setVisible(false)}
|
||||
{...rest}
|
||||
>
|
||||
{React.Children.map(children, (child) =>
|
||||
child &&
|
||||
isValidElement(child) &&
|
||||
child.type.name === 'SongContextMenu'
|
||||
? cloneElement(child, { visible, ...rest })
|
||||
: child
|
||||
)}
|
||||
</DatagridRow>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -12,6 +12,7 @@ import DocLink from './DocLink'
|
|||
import List from './List'
|
||||
import SongDatagridRow from './SongDatagridRow'
|
||||
import AddToPlaylistMenu from './AddToPlaylistMenu'
|
||||
import SongContextMenu from './SongContextMenu'
|
||||
|
||||
export {
|
||||
Title,
|
||||
|
@ -30,4 +31,5 @@ export {
|
|||
ArtistLinkField,
|
||||
artistLink,
|
||||
AddToPlaylistMenu,
|
||||
SongContextMenu,
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||
import {
|
||||
BulkActionsToolbar,
|
||||
Datagrid,
|
||||
DatagridBody,
|
||||
DatagridLoading,
|
||||
ListToolbar,
|
||||
TextField,
|
||||
|
@ -11,8 +12,12 @@ import {
|
|||
import classnames from 'classnames'
|
||||
import { Card, useMediaQuery } from '@material-ui/core'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { DurationField, SongDetails } from '../common'
|
||||
import { SongContextMenu } from '../song/SongContextMenu'
|
||||
import {
|
||||
DurationField,
|
||||
SongDetails,
|
||||
SongContextMenu,
|
||||
SongDatagridRow,
|
||||
} from '../common'
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme) => ({
|
||||
|
@ -50,6 +55,13 @@ const useStylesListToolbar = makeStyles({
|
|||
},
|
||||
})
|
||||
|
||||
const SongsDatagridBody = (props) => (
|
||||
<DatagridBody {...props} row={<SongDatagridRow />} />
|
||||
)
|
||||
const SongsDatagrid = (props) => (
|
||||
<Datagrid {...props} body={<SongsDatagridBody />} />
|
||||
)
|
||||
|
||||
const PlaylistSongs = (props) => {
|
||||
const classes = useStyles(props)
|
||||
const classesToolbar = useStylesListToolbar(props)
|
||||
|
@ -106,7 +118,7 @@ const PlaylistSongs = (props) => {
|
|||
size={'small'}
|
||||
/>
|
||||
) : (
|
||||
<Datagrid
|
||||
<SongsDatagrid
|
||||
expand={!isXsmall && <SongDetails />}
|
||||
rowClick={null}
|
||||
{...controllerProps}
|
||||
|
@ -117,7 +129,7 @@ const PlaylistSongs = (props) => {
|
|||
{isDesktop && <TextField source="artist" />}
|
||||
<DurationField source="duration" />
|
||||
<SongContextMenu onAddToPlaylist={onAddToPlaylist} />
|
||||
</Datagrid>
|
||||
</SongsDatagrid>
|
||||
)}
|
||||
</Card>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react'
|
||||
import {
|
||||
Datagrid,
|
||||
DatagridBody,
|
||||
Filter,
|
||||
FunctionField,
|
||||
NumberField,
|
||||
|
@ -8,12 +9,18 @@ import {
|
|||
TextField,
|
||||
} from 'react-admin'
|
||||
import { useMediaQuery } from '@material-ui/core'
|
||||
import { DurationField, SimpleList, List, SongDetails } from '../common'
|
||||
import {
|
||||
DurationField,
|
||||
SimpleList,
|
||||
List,
|
||||
SongDetails,
|
||||
SongDatagridRow,
|
||||
SongContextMenu,
|
||||
} from '../common'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { setTrack } from '../audioplayer'
|
||||
import { SongBulkActions } from './SongBulkActions'
|
||||
import { AlbumLinkField } from './AlbumLinkField'
|
||||
import { SongContextMenu } from './SongContextMenu'
|
||||
|
||||
const SongFilter = (props) => (
|
||||
<Filter {...props}>
|
||||
|
@ -21,6 +28,13 @@ const SongFilter = (props) => (
|
|||
</Filter>
|
||||
)
|
||||
|
||||
const SongsDatagridBody = (props) => (
|
||||
<DatagridBody {...props} row={<SongDatagridRow />} />
|
||||
)
|
||||
const SongsDatagrid = (props) => (
|
||||
<Datagrid {...props} body={<SongsDatagridBody />} />
|
||||
)
|
||||
|
||||
const SongList = (props) => {
|
||||
const dispatch = useDispatch()
|
||||
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
||||
|
@ -48,7 +62,7 @@ const SongList = (props) => {
|
|||
rightIcon={(r) => <SongContextMenu record={r} />}
|
||||
/>
|
||||
) : (
|
||||
<Datagrid
|
||||
<SongsDatagrid
|
||||
expand={<SongDetails />}
|
||||
rowClick={(id, basePath, record) => dispatch(setTrack(record))}
|
||||
>
|
||||
|
@ -62,7 +76,7 @@ const SongList = (props) => {
|
|||
)}
|
||||
<DurationField source="duration" />
|
||||
<SongContextMenu />
|
||||
</Datagrid>
|
||||
</SongsDatagrid>
|
||||
)}
|
||||
</List>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue