mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-16 20:12:22 +03:00
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:
parent
c57fa7a8fc
commit
52812fa48b
@ -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}
|
||||
|
@ -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
|
||||
|
24
ui/src/common/QualityInfo.js
Normal file
24
ui/src/common/QualityInfo.js
Normal 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: {},
|
||||
}
|
80
ui/src/common/QualityInfo.test.js
Normal file
80
ui/src/common/QualityInfo.test.js
Normal 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')
|
||||
})
|
||||
})
|
@ -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',
|
||||
]
|
||||
|
@ -20,7 +20,8 @@
|
||||
"bitRate": "Bit rate",
|
||||
"discSubtitle": "Disc Subtitle",
|
||||
"starred": "Favourite",
|
||||
"comment": "Comment"
|
||||
"comment": "Comment",
|
||||
"quality": "Quality"
|
||||
},
|
||||
"actions": {
|
||||
"addToQueue": "Play Later",
|
||||
|
@ -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}
|
||||
|
@ -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'}
|
||||
|
Loading…
x
Reference in New Issue
Block a user