Only show SongContextMenu on hover

This commit is contained in:
Deluan 2020-05-22 20:15:58 -04:00
parent ae847103a2
commit 978e7f2eaa
6 changed files with 88 additions and 24 deletions

View File

@ -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) => ({

View File

@ -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

View File

@ -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>
</>
)

View File

@ -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,
}

View File

@ -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>

View File

@ -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>
)