import { Avatar, makeStyles, useMediaQuery } from '@material-ui/core'
import React, { cloneElement } from 'react'
import {
CreateButton,
Datagrid,
EditButton,
Filter,
sanitizeListRestProps,
SearchInput,
SimpleList,
TextField,
TopToolbar,
UrlField,
useTranslate,
} from 'react-admin'
import {
DateField,
List,
defaultRowsPerPageOptions,
getStoredPerPage,
ToggleFieldsMenu,
useSelectedFields,
} from '../common'
import { Artwork } from '../common/Artwork'
import { StreamField } from './StreamField'
import { setTrack } from '../actions'
import { songFromRadio } from './helper'
import { RADIO_PLACEHOLDER_IMAGE } from '../consts'
import { useDispatch } from 'react-redux'
const useStyles = makeStyles({
row: {
'&:hover': {
'& $contextMenu': {
visibility: 'visible',
},
},
},
contextMenu: {
visibility: 'hidden',
},
})
const RadioFilter = (props) => (
<Filter {...props} variant={'outlined'}>
<SearchInput id="search" source="name" alwaysOn />
</Filter>
)
const RadioListActions = ({
className,
filters,
resource,
showFilter,
displayedFilters,
filterValues,
isAdmin,
...rest
}) => {
const isNotSmall = useMediaQuery((theme) => theme.breakpoints.up('sm'))
const translate = useTranslate()
return (
<TopToolbar className={className} {...sanitizeListRestProps(rest)}>
{isAdmin && (
<CreateButton basePath="/radio">
{translate('ra.action.create')}
</CreateButton>
)}
{filters &&
cloneElement(filters, {
resource,
showFilter,
displayedFilters,
filterValues,
context: 'button',
})}
{isNotSmall && <ToggleFieldsMenu resource="radio" />}
</TopToolbar>
)
}
const avatarStyle = { width: 40, height: 40 }
const useCoverStyles = makeStyles({
cover: { width: 40, height: 40, borderRadius: '4px' },
})
const CoverArtField = ({ record }) => {
const classes = useCoverStyles()
if (!record) return null
if (record.uploadedImage) {
return (
<Artwork
record={record}
size={40}
square
className={classes.cover}
title={record.name}
/>
)
}
return (
<Avatar
src={RADIO_PLACEHOLDER_IMAGE}
variant="rounded"
style={avatarStyle}
alt={record.name}
/>
)
}
CoverArtField.defaultProps = { label: '' }
const RadioList = ({ permissions, ...props }) => {
const classes = useStyles()
const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))
const dispatch = useDispatch()
const isAdmin = permissions === 'admin'
const toggleableFields = {
coverArt: <CoverArtField source="id" sortable={false} />,
name: <TextField source="name" />,
homePageUrl: (
<UrlField
source="homePageUrl"
onClick={(e) => e.stopPropagation()}
target="_blank"
rel="noopener noreferrer"
/>
),
streamUrl: <TextField source="streamUrl" />,
updatedAt: <DateField source="updatedAt" showTime />,
createdAt: <DateField source="createdAt" showTime />,
}
const columns = useSelectedFields({
resource: 'radio',
columns: toggleableFields,
defaultOff: ['streamUrl', 'createdAt'],
})
const handleRowClick = async (id, basePath, record) => {
dispatch(setTrack(await songFromRadio(record)))
}
return (
<List
{...props}
exporter={false}
sort={{ field: 'name', order: 'ASC' }}
bulkActionButtons={isAdmin ? undefined : false}
hasCreate={isAdmin}
actions={<RadioListActions isAdmin={isAdmin} />}
filters={<RadioFilter />}
perPage={getStoredPerPage(
'radio',
defaultRowsPerPageOptions,
isXsmall ? 25 : 10,
)}
>
{isXsmall ? (
<SimpleList
leftAvatar={(r) => <CoverArtField record={r} />}
leftIcon={(r) => (
<StreamField
record={r}
source={'streamUrl'}
hideUrl
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
}}
/>
)}
primaryText={(r) => r.name}
secondaryText={(r) => r.homePageUrl}
/>
) : (
<Datagrid rowClick={handleRowClick} classes={{ row: classes.row }}>
{columns}
{isAdmin && <EditButton />}
</Datagrid>
)}
</List>
)
}
export default RadioList