Add artist context menu
This commit is contained in:
@@ -12,7 +12,7 @@ import { linkToRecord, Loading } from 'react-admin'
|
|||||||
import { withContentRect } from 'react-measure'
|
import { withContentRect } from 'react-measure'
|
||||||
import subsonic from '../subsonic'
|
import subsonic from '../subsonic'
|
||||||
import { ArtistLinkField, RangeField } from '../common'
|
import { ArtistLinkField, RangeField } from '../common'
|
||||||
import AlbumContextMenu from '../common/AlbumContextMenu.js'
|
import { AlbumContextMenu } from '../common'
|
||||||
|
|
||||||
const useStyles = makeStyles((theme) => ({
|
const useStyles = makeStyles((theme) => ({
|
||||||
root: {
|
root: {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
SimpleList,
|
SimpleList,
|
||||||
} from '../common'
|
} from '../common'
|
||||||
import { useMediaQuery } from '@material-ui/core'
|
import { useMediaQuery } from '@material-ui/core'
|
||||||
import AlbumContextMenu from '../common/AlbumContextMenu'
|
import { AlbumContextMenu } from '../common'
|
||||||
|
|
||||||
const AlbumDetails = (props) => {
|
const AlbumDetails = (props) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
+70
-17
@@ -1,13 +1,21 @@
|
|||||||
import React from 'react'
|
import React, { cloneElement, isValidElement, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Datagrid,
|
Datagrid,
|
||||||
|
DatagridBody,
|
||||||
|
DatagridRow,
|
||||||
Filter,
|
Filter,
|
||||||
NumberField,
|
NumberField,
|
||||||
SearchInput,
|
SearchInput,
|
||||||
TextField,
|
TextField,
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { List, useGetHandleArtistClick } from '../common'
|
import { useMediaQuery, withWidth } from '@material-ui/core'
|
||||||
import { withWidth } from '@material-ui/core'
|
import AddToPlaylistDialog from '../dialogs/AddToPlaylistDialog'
|
||||||
|
import {
|
||||||
|
ArtistContextMenu,
|
||||||
|
List,
|
||||||
|
SimpleList,
|
||||||
|
useGetHandleArtistClick,
|
||||||
|
} from '../common'
|
||||||
|
|
||||||
const ArtistFilter = (props) => (
|
const ArtistFilter = (props) => (
|
||||||
<Filter {...props}>
|
<Filter {...props}>
|
||||||
@@ -15,22 +23,67 @@ const ArtistFilter = (props) => (
|
|||||||
</Filter>
|
</Filter>
|
||||||
)
|
)
|
||||||
|
|
||||||
const ArtistList = ({ width, ...props }) => {
|
const ArtistDatagridRow = ({ children, ...rest }) => {
|
||||||
const handleArtistLink = useGetHandleArtistClick(width)
|
const [visible, setVisible] = useState(false)
|
||||||
|
const childCount = React.Children.count(children)
|
||||||
return (
|
return (
|
||||||
<List
|
<DatagridRow
|
||||||
{...props}
|
onMouseEnter={() => setVisible(true)}
|
||||||
sort={{ field: 'name', order: 'ASC' }}
|
onMouseLeave={() => setVisible(false)}
|
||||||
exporter={false}
|
{...rest}
|
||||||
bulkActionButtons={false}
|
|
||||||
filters={<ArtistFilter />}
|
|
||||||
>
|
>
|
||||||
<Datagrid rowClick={handleArtistLink}>
|
{React.Children.map(
|
||||||
<TextField source="name" />
|
children,
|
||||||
<NumberField source="albumCount" sortByOrder={'DESC'} />
|
(child, index) =>
|
||||||
<NumberField source="songCount" sortByOrder={'DESC'} />
|
child &&
|
||||||
</Datagrid>
|
isValidElement(child) &&
|
||||||
</List>
|
(index < childCount - 1
|
||||||
|
? child
|
||||||
|
: cloneElement(child, {
|
||||||
|
visible,
|
||||||
|
}))
|
||||||
|
)}
|
||||||
|
</DatagridRow>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ArtistDatagridBody = (props) => (
|
||||||
|
<DatagridBody {...props} row={<ArtistDatagridRow />} />
|
||||||
|
)
|
||||||
|
const ArtistDatagrid = (props) => (
|
||||||
|
<Datagrid {...props} body={<ArtistDatagridBody />} />
|
||||||
|
)
|
||||||
|
|
||||||
|
const ArtistList = ({ width, ...rest }) => {
|
||||||
|
const handleArtistLink = useGetHandleArtistClick(width)
|
||||||
|
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<List
|
||||||
|
{...rest}
|
||||||
|
sort={{ field: 'name', order: 'ASC' }}
|
||||||
|
exporter={false}
|
||||||
|
bulkActionButtons={false}
|
||||||
|
filters={<ArtistFilter />}
|
||||||
|
>
|
||||||
|
{isXsmall ? (
|
||||||
|
<SimpleList
|
||||||
|
primaryText={(r) => r.name}
|
||||||
|
linkType={'show'}
|
||||||
|
rightIcon={(r) => <ArtistContextMenu record={r} />}
|
||||||
|
{...rest}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<ArtistDatagrid rowClick={handleArtistLink}>
|
||||||
|
<TextField source="name" />
|
||||||
|
<NumberField source="albumCount" sortByOrder={'DESC'} />
|
||||||
|
<NumberField source="songCount" sortByOrder={'DESC'} />
|
||||||
|
<ArtistContextMenu />
|
||||||
|
</ArtistDatagrid>
|
||||||
|
)}
|
||||||
|
</List>
|
||||||
|
<AddToPlaylistDialog />
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const useStyles = makeStyles({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const AlbumContextMenu = ({ record, discNumber, color, visible }) => {
|
const ContextMenu = ({ record, color, visible, songQueryParams }) => {
|
||||||
const classes = useStyles({ color, visible })
|
const classes = useStyles({ color, visible })
|
||||||
const dataProvider = useDataProvider()
|
const dataProvider = useDataProvider()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
@@ -87,11 +87,7 @@ const AlbumContextMenu = ({ record, discNumber, color, visible }) => {
|
|||||||
const key = e.target.getAttribute('value')
|
const key = e.target.getAttribute('value')
|
||||||
if (options[key].needData) {
|
if (options[key].needData) {
|
||||||
dataProvider
|
dataProvider
|
||||||
.getList('albumSong', {
|
.getList('albumSong', songQueryParams)
|
||||||
pagination: { page: 1, perPage: -1 },
|
|
||||||
sort: { field: 'discNumber, trackNumber', order: 'ASC' },
|
|
||||||
filter: { album_id: record.id, disc_number: discNumber },
|
|
||||||
})
|
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
let { data, ids } = extractSongsData(response)
|
let { data, ids } = extractSongsData(response)
|
||||||
options[key].action(data, ids)
|
options[key].action(data, ids)
|
||||||
@@ -140,6 +136,17 @@ const AlbumContextMenu = ({ record, discNumber, color, visible }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const AlbumContextMenu = (props) => (
|
||||||
|
<ContextMenu
|
||||||
|
{...props}
|
||||||
|
songQueryParams={{
|
||||||
|
pagination: { page: 1, perPage: -1 },
|
||||||
|
sort: { field: 'discNumber, trackNumber', order: 'ASC' },
|
||||||
|
filter: { album_id: props.record.id, disc_number: props.discNumber },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
AlbumContextMenu.propTypes = {
|
AlbumContextMenu.propTypes = {
|
||||||
record: PropTypes.object,
|
record: PropTypes.object,
|
||||||
discNumber: PropTypes.number,
|
discNumber: PropTypes.number,
|
||||||
@@ -152,4 +159,24 @@ AlbumContextMenu.defaultProps = {
|
|||||||
addLabel: true,
|
addLabel: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AlbumContextMenu
|
export const ArtistContextMenu = (props) => (
|
||||||
|
<ContextMenu
|
||||||
|
{...props}
|
||||||
|
songQueryParams={{
|
||||||
|
pagination: { page: 1, perPage: 200 },
|
||||||
|
sort: { field: 'album, discNumber, trackNumber', order: 'ASC' },
|
||||||
|
filter: { album_artist_id: props.record.id },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
ArtistContextMenu.propTypes = {
|
||||||
|
record: PropTypes.object,
|
||||||
|
visible: PropTypes.bool,
|
||||||
|
color: PropTypes.string,
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtistContextMenu.defaultProps = {
|
||||||
|
visible: true,
|
||||||
|
addLabel: true,
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types'
|
|||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import AlbumIcon from '@material-ui/icons/Album'
|
import AlbumIcon from '@material-ui/icons/Album'
|
||||||
import { playTracks } from '../audioplayer'
|
import { playTracks } from '../audioplayer'
|
||||||
import AlbumContextMenu from './AlbumContextMenu'
|
import { AlbumContextMenu } from '../common'
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
row: {
|
row: {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import SongContextMenu from './SongContextMenu'
|
|||||||
import SongTitleField from './SongTitleField'
|
import SongTitleField from './SongTitleField'
|
||||||
import QuickFilter from './QuickFilter'
|
import QuickFilter from './QuickFilter'
|
||||||
import useAlbumsPerPage from './useAlbumsPerPage'
|
import useAlbumsPerPage from './useAlbumsPerPage'
|
||||||
|
import { AlbumContextMenu, ArtistContextMenu } from './ContextMenus'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Title,
|
Title,
|
||||||
@@ -33,6 +34,8 @@ export {
|
|||||||
DocLink,
|
DocLink,
|
||||||
formatRange,
|
formatRange,
|
||||||
ArtistLinkField,
|
ArtistLinkField,
|
||||||
|
AlbumContextMenu,
|
||||||
|
ArtistContextMenu,
|
||||||
useGetHandleArtistClick,
|
useGetHandleArtistClick,
|
||||||
SongContextMenu,
|
SongContextMenu,
|
||||||
QuickFilter,
|
QuickFilter,
|
||||||
|
|||||||
Reference in New Issue
Block a user