import { useMemo } from 'react'import {AutocompleteArrayInput,Filter,FunctionField,NumberField,ReferenceArrayInput,SearchInput,TextField,useTranslate,NullableBooleanInput,usePermissions,} from 'react-admin'import { useMediaQuery } from '@material-ui/core'import FavoriteIcon from '@material-ui/icons/Favorite'import {DateField,DurationField,List,SongContextMenu,SongDatagrid,SongInfo,SongTitleField,SongSimpleList,RatingField,useResourceRefresh,ArtistLinkField,PathField,defaultRowsPerPageOptions,getStoredPerPage,} from '../common'import { useDispatch } from 'react-redux'import { makeStyles } from '@material-ui/core/styles'import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'import { setTrack } from '../actions'import { SongListActions } from './SongListActions'import { AlbumLinkField } from './AlbumLinkField'import { SongBulkActions, QualityInfo, useSelectedFields } from '../common'import config from '../config'import ExpandInfoDialog from '../dialogs/ExpandInfoDialog'const useStyles = makeStyles({contextHeader: {marginLeft: '3px',marginTop: '-2px',verticalAlign: 'text-top',},row: {'&:hover': {'& $contextMenu': {visibility: 'visible',},'& $ratingField': {visibility: 'visible',},},},contextMenu: {visibility: 'hidden',},ratingField: {visibility: 'hidden',},chip: {margin: 0,height: '24px',},})const SongFilter = (props) => {const classes = useStyles()const translate = useTranslate()const { permissions } = usePermissions()const isAdmin = permissions === 'admin'return (<Filter {...props} variant={'outlined'}><SearchInput source="title" alwaysOn /><ReferenceArrayInputlabel={translate('resources.song.fields.genre')}source="genre_id"reference="genre"perPage={0}sort={{ field: 'name', order: 'ASC' }}filterToQuery={(searchText) => ({ name: [searchText] })}><AutocompleteArrayInput emptyText="-- None --" classes={classes} /></ReferenceArrayInput><ReferenceArrayInputlabel={translate('resources.song.fields.grouping')}source="grouping"reference="tag"perPage={0}sort={{ field: 'tagValue', order: 'ASC' }}filter={{ tag_name: 'grouping' }}filterToQuery={(searchText) => ({tag_value: [searchText],})}><AutocompleteArrayInputemptyText="-- None --"classes={classes}optionText="tagValue"/></ReferenceArrayInput><ReferenceArrayInputlabel={translate('resources.song.fields.mood')}source="mood"reference="tag"perPage={0}sort={{ field: 'tagValue', order: 'ASC' }}filter={{ tag_name: 'mood' }}filterToQuery={(searchText) => ({tag_value: [searchText],})}><AutocompleteArrayInputemptyText="-- None --"classes={classes}optionText="tagValue"/></ReferenceArrayInput>{config.enableFavourites && (<NullableBooleanInputsource="starred"label={<FavoriteIcon fontSize={'small'} />}/>)}{isAdmin && <NullableBooleanInput source="missing" />}</Filter>)}const SongList = (props) => {const classes = useStyles()const dispatch = useDispatch()const isXsmall = useMediaQuery((theme) => theme.breakpoints.down('xs'))const isDesktop = useMediaQuery((theme) => theme.breakpoints.up('md'))useResourceRefresh('song')const handleRowClick = (id, basePath, record) => {dispatch(setTrack(record))}const toggleableFields = useMemo(() => {return {album: isDesktop && <AlbumLinkField source="album" sortByOrder={'ASC'} />,artist: <ArtistLinkField source="artist" />,composer: <ArtistLinkField source="composer" sortable={false} />,albumArtist: <ArtistLinkField source="albumArtist" />,trackNumber: isDesktop && (<NumberField source="trackNumber" sortable={false} />),playCount: isDesktop && (<NumberField source="playCount" sortByOrder={'DESC'} />),playDate: <DateField source="playDate" sortByOrder={'DESC'} showTime />,year: isDesktop && (<FunctionFieldsource="year"render={(r) => r.year || ''}sortByOrder={'DESC'}/>),quality: isDesktop && <QualityInfo source="quality" sortable={false} />,channels: isDesktop && (<NumberField source="channels" sortByOrder={'ASC'} />),duration: <DurationField source="duration" />,rating: config.enableStarRating && (<RatingFieldsource="rating"sortByOrder={'DESC'}resource={'song'}className={classes.ratingField}/>),bpm: isDesktop && <NumberField source="bpm" />,genre: <TextField source="genre" />,mood: isDesktop && (<FunctionFieldsource="mood"render={(r) => r.tags?.mood?.[0] || ''}sortable={false}/>),comment: <TextField source="comment" />,path: <PathField source="path" />,createdAt: (<DateField source="createdAt" sortBy="recently_added" showTime />),}}, [isDesktop, classes.ratingField])const columns = useSelectedFields({resource: 'song',columns: toggleableFields,defaultOff: ['composer','channels','bpm','playDate','albumArtist','genre','mood','comment','path','createdAt',],})return (<><List{...props}sort={{ field: 'title', order: 'ASC' }}exporter={false}bulkActionButtons={<SongBulkActions />}actions={<SongListActions />}filters={<SongFilter />}perPage={getStoredPerPage('song',defaultRowsPerPageOptions,isXsmall ? 50 : 15,)}>{isXsmall ? (<SongSimpleList />) : (<SongDatagridrowClick={handleRowClick}contextAlwaysVisible={!isDesktop}classes={{ row: classes.row }}><SongTitleField source="title" showTrackNumbers={false} />{columns}<SongContextMenusource={'starred_at'}sortByOrder={'DESC'}sortable={config.enableFavourites}className={classes.contextMenu}label={config.enableFavourites && (<FavoriteBorderIconfontSize={'small'}className={classes.contextHeader}/>)}/></SongDatagrid>)}</List><ExpandInfoDialog content={<SongInfo />} /></>)}export default SongList