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:
@@ -21,6 +21,7 @@ import {
|
|||||||
SongTitleField,
|
SongTitleField,
|
||||||
} from '../common'
|
} from '../common'
|
||||||
import { AddToPlaylistDialog } from '../dialogs'
|
import { AddToPlaylistDialog } from '../dialogs'
|
||||||
|
import { QualityInfo } from '../common/QualityInfo'
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
@@ -119,6 +120,7 @@ const AlbumSongs = (props) => {
|
|||||||
/>
|
/>
|
||||||
{isDesktop && <TextField source="artist" sortable={false} />}
|
{isDesktop && <TextField source="artist" sortable={false} />}
|
||||||
<DurationField source="duration" sortable={false} />
|
<DurationField source="duration" sortable={false} />
|
||||||
|
<QualityInfo source="quality" sortable={false} />
|
||||||
<SongContextMenu
|
<SongContextMenu
|
||||||
source={'starred'}
|
source={'starred'}
|
||||||
sortable={false}
|
sortable={false}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useGetOne } from 'react-admin'
|
|||||||
import { GlobalHotKeys } from 'react-hotkeys'
|
import { GlobalHotKeys } from 'react-hotkeys'
|
||||||
import { LoveButton, useToggleLove } from '../common'
|
import { LoveButton, useToggleLove } from '../common'
|
||||||
import { keyMap } from '../hotkeys'
|
import { keyMap } from '../hotkeys'
|
||||||
|
import { QualityInfo } from '../common/QualityInfo'
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
|
|
||||||
const Placeholder = () =>
|
const Placeholder = () =>
|
||||||
@@ -18,9 +19,9 @@ const Toolbar = ({ id }) => {
|
|||||||
const handlers = {
|
const handlers = {
|
||||||
TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),
|
TOGGLE_LOVE: useCallback(() => toggleLove(), [toggleLove]),
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{data && <QualityInfo record={data} sortable={false} />}
|
||||||
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
|
<GlobalHotKeys keyMap={keyMap} handlers={handlers} allowChanges />
|
||||||
{config.enableFavourites && (
|
{config.enableFavourites && (
|
||||||
<LoveButton
|
<LoveButton
|
||||||
|
|||||||
@@ -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: {},
|
||||||
|
}
|
||||||
@@ -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')
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -3,3 +3,13 @@ export const REST_URL = '/app/api'
|
|||||||
export const M3U_MIME_TYPE = 'audio/x-mpegurl'
|
export const M3U_MIME_TYPE = 'audio/x-mpegurl'
|
||||||
|
|
||||||
export const AUTO_THEME_ID = 'AUTO_THEME_ID'
|
export const AUTO_THEME_ID = 'AUTO_THEME_ID'
|
||||||
|
|
||||||
|
export const LOSSLESS_FORMATS = [
|
||||||
|
'FLAC',
|
||||||
|
'WAV',
|
||||||
|
'DSF',
|
||||||
|
'ALAC',
|
||||||
|
'TTA',
|
||||||
|
'ATRAC',
|
||||||
|
'SHN',
|
||||||
|
]
|
||||||
|
|||||||
+2
-1
@@ -20,7 +20,8 @@
|
|||||||
"bitRate": "Bit rate",
|
"bitRate": "Bit rate",
|
||||||
"discSubtitle": "Disc Subtitle",
|
"discSubtitle": "Disc Subtitle",
|
||||||
"starred": "Favourite",
|
"starred": "Favourite",
|
||||||
"comment": "Comment"
|
"comment": "Comment",
|
||||||
|
"quality": "Quality"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"addToQueue": "Play Later",
|
"addToQueue": "Play Later",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { AddToPlaylistDialog } from '../dialogs'
|
|||||||
import { AlbumLinkField } from '../song/AlbumLinkField'
|
import { AlbumLinkField } from '../song/AlbumLinkField'
|
||||||
import { playTracks } from '../actions'
|
import { playTracks } from '../actions'
|
||||||
import PlaylistSongBulkActions from './PlaylistSongBulkActions'
|
import PlaylistSongBulkActions from './PlaylistSongBulkActions'
|
||||||
|
import { QualityInfo } from '../common/QualityInfo'
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
(theme) => ({
|
(theme) => ({
|
||||||
@@ -164,6 +165,7 @@ const PlaylistSongs = ({ playlistId, readOnly, actions, ...props }) => {
|
|||||||
{isDesktop && <AlbumLinkField source="album" />}
|
{isDesktop && <AlbumLinkField source="album" />}
|
||||||
{isDesktop && <TextField source="artist" />}
|
{isDesktop && <TextField source="artist" />}
|
||||||
<DurationField source="duration" className={classes.draggable} />
|
<DurationField source="duration" className={classes.draggable} />
|
||||||
|
<QualityInfo source="quality" sortable={false} />
|
||||||
<SongContextMenu
|
<SongContextMenu
|
||||||
onAddToPlaylist={onAddToPlaylist}
|
onAddToPlaylist={onAddToPlaylist}
|
||||||
showLove={false}
|
showLove={false}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { AddToPlaylistDialog } from '../dialogs'
|
|||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'
|
import FavoriteBorderIcon from '@material-ui/icons/FavoriteBorder'
|
||||||
import config from '../config'
|
import config from '../config'
|
||||||
|
import { QualityInfo } from '../common/QualityInfo'
|
||||||
|
|
||||||
const useStyles = makeStyles({
|
const useStyles = makeStyles({
|
||||||
contextHeader: {
|
contextHeader: {
|
||||||
@@ -111,6 +112,7 @@ const SongList = (props) => {
|
|||||||
sortByOrder={'DESC'}
|
sortByOrder={'DESC'}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<QualityInfo source="quality" sortable={false} />
|
||||||
<DurationField source="duration" />
|
<DurationField source="duration" />
|
||||||
<SongContextMenu
|
<SongContextMenu
|
||||||
source={'starred'}
|
source={'starred'}
|
||||||
|
|||||||
Reference in New Issue
Block a user