Added quality info (#918)

* added quality info

* fixed formatting

* implemented various suggestions

* npm run prettier

* applied suggestions

* npm run prettier

* corrected lossless formats and other suggestions

* moved losslessformats into consts.js

* added some test

* typo while resolving conflicts

* fetch

* removed a bug causing component (as suggested)

* Update PlayerToolbar.js

* implemented suggestions

* added few more tests

* npm run prettier

* added size

* updated qualityInfo

* implemented suggestions

* added test for when no record is recieved

* Update QualityInfo.js
This commit is contained in:
Himanshu maurya 2021-04-07 07:00:17 +05:30 committed by GitHub
parent c57fa7a8fc
commit 52812fa48b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 124 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import {
SongTitleField,
} from '../common'
import { AddToPlaylistDialog } from '../dialogs'
import { QualityInfo } from '../common/QualityInfo'
import config from '../config'
const useStyles = makeStyles(
@ -119,6 +120,7 @@ const AlbumSongs = (props) => {
/>
{isDesktop && <TextField source="artist" sortable={false} />}
<DurationField source="duration" sortable={false} />
<QualityInfo source="quality" sortable={false} />
<SongContextMenu
source={'starred'}
sortable={false}

View File

@ -4,6 +4,7 @@ import { useGetOne } from 'react-admin'
import { GlobalHotKeys } from 'react-hotkeys'
import { LoveButton, useToggleLove } from '../common'
import { keyMap } from '../hotkeys'
import { QualityInfo } from '../common/QualityInfo'
import config from '../config'
const Placeholder = () =>
@ -18,9 +19,9 @@ const Toolbar = ({ id }) => {
const handlers = {
TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),
}
return (
<>
{data && <QualityInfo record={data} sortable={false} />}
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
{config.enableFavourites && (
<LoveButton

View File

@ -0,0 +1,24 @@
import React from 'react'
import PropTypes from 'prop-types'
import Chip from '@material-ui/core/Chip'
import { LOSSLESS_FORMATS } from '../consts'
export const QualityInfo = ({ record, size, ...rest }) => {
let { suffix = 'NO_SUFFIX', bitRate = 'NO_BITRATE' } = record
suffix = suffix.toUpperCase()
let info = suffix
if (!LOSSLESS_FORMATS.includes(suffix)) {
info += ' ' + bitRate
}
return <Chip {...rest} size={size} variant="outlined" label={info} />
}
QualityInfo.propTypes = {
record: PropTypes.object.isRequired,
size: PropTypes.string,
}
QualityInfo.defaultProps = {
size: 'small',
record: {},
}

View File

@ -0,0 +1,80 @@
import * as React from 'react'
import { cleanup, render } from '@testing-library/react'
import { QualityInfo } from './QualityInfo'
describe('<QualityInfo />', () => {
afterEach(cleanup)
it('only render FLAC', () => {
const info = { suffix: 'FLAC', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('FLAC')
expect(format.innerHTML).toEqual('FLAC')
})
it('only render WAV', () => {
const info = { suffix: 'WAV', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('WAV')
expect(format.innerHTML).toEqual('WAV')
})
it('only render DSF', () => {
const info = { suffix: 'DSF', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('DSF')
expect(format.innerHTML).toEqual('DSF')
})
it('only render ALAC', () => {
const info = { suffix: 'ALAC', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('ALAC')
expect(format.innerHTML).toEqual('ALAC')
})
it('only render TTA', () => {
const info = { suffix: 'TTA', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('TTA')
expect(format.innerHTML).toEqual('TTA')
})
it('only render ATRAC', () => {
const info = { suffix: 'ATRAC', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('ATRAC')
expect(format.innerHTML).toEqual('ATRAC')
})
it('only render SHN', () => {
const info = { suffix: 'SHN', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('SHN')
expect(format.innerHTML).toEqual('SHN')
})
it('only render OCG 108', () => {
const info = { suffix: 'OCG', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('OCG 108')
expect(format.innerHTML).toEqual('OCG 108')
})
it('only render MP3 108', () => {
const info = { suffix: 'MP3', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('MP3 108')
expect(format.innerHTML).toEqual('MP3 108')
})
it('only render AAC 108', () => {
const info = { suffix: 'AAC', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('AAC 108')
expect(format.innerHTML).toEqual('AAC 108')
})
it('only render OPUS 108', () => {
const info = { suffix: 'OPUS', bitRate: 108 }
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('OPUS 108')
expect(format.innerHTML).toEqual('OPUS 108')
})
it('render nothing', () => {
const info = {}
const { getByText } = render(<QualityInfo record={info} />)
const format = getByText('NO_SUFFIX NO_BITRATE')
expect(format.innerHTML).toEqual('NO_SUFFIX NO_BITRATE')
})
})

View File

@ -3,3 +3,13 @@ export const REST_URL = '/app/api'
export const M3U_MIME_TYPE = 'audio/x-mpegurl'
export const AUTO_THEME_ID = 'AUTO_THEME_ID'
export const LOSSLESS_FORMATS = [
'FLAC',
'WAV',
'DSF',
'ALAC',
'TTA',
'ATRAC',
'SHN',
]

View File

@ -20,7 +20,8 @@
"bitRate": "Bit rate",
"discSubtitle": "Disc Subtitle",
"starred": "Favourite",
"comment": "Comment"
"comment": "Comment",
"quality": "Quality"
},
"actions": {
"addToQueue": "Play Later",

View File

@ -26,6 +26,7 @@ import { AddToPlaylistDialog } from '../dialogs'
import { AlbumLinkField } from '../song/AlbumLinkField'
import { playTracks } from '../actions'
import PlaylistSongBulkActions from './PlaylistSongBulkActions'
import { QualityInfo } from '../common/QualityInfo'
const useStyles = makeStyles(
(theme) => ({
@ -164,6 +165,7 @@ const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
{isDesktop && <AlbumLinkField source="album" />}
{isDesktop && <TextField source="artist" />}
<DurationField source="duration" className={classes.draggable} />
<QualityInfo source="quality" sortable={false} />
<SongContextMenu
onAddToPlaylist={onAddToPlaylist}
showLove={false}

View File

@ -27,6 +27,7 @@ import { AddToPlaylistDialog } from '../dialogs'
import { makeStyles } from '@material-ui/core/styles'
import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'
import config from '../config'
import { QualityInfo } from '../common/QualityInfo'
const useStyles = makeStyles({
contextHeader: {
@ -111,6 +112,7 @@ const SongList = (props) => {
sortByOrder={'DESC'}
/>
)}
<QualityInfo source="quality" sortable={false} />
<DurationField source="duration" />
<SongContextMenu
source={'starred'}