feat: show year range in album view and match ranges in year filter. #118
This commit is contained in:
@@ -29,11 +29,23 @@ func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository
|
|||||||
"name": fullTextFilter,
|
"name": fullTextFilter,
|
||||||
"compilation": booleanFilter,
|
"compilation": booleanFilter,
|
||||||
"artist_id": artistFilter,
|
"artist_id": artistFilter,
|
||||||
|
"year": yearFilter,
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func yearFilter(field string, value interface{}) Sqlizer {
|
||||||
|
return Or{
|
||||||
|
And{
|
||||||
|
Gt{"min_year": 0},
|
||||||
|
LtOrEq{"min_year": value},
|
||||||
|
GtOrEq{"max_year": value},
|
||||||
|
},
|
||||||
|
Eq{"max_year": value},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func artistFilter(field string, value interface{}) Sqlizer {
|
func artistFilter(field string, value interface{}) Sqlizer {
|
||||||
return Exists("media_file", And{
|
return Exists("media_file", And{
|
||||||
ConcatExpr("album_id=album.id"),
|
ConcatExpr("album_id=album.id"),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import { Card, CardContent, CardMedia, Typography } from '@material-ui/core'
|
import { Card, CardContent, CardMedia, Typography } from '@material-ui/core'
|
||||||
import { useTranslate } from 'react-admin'
|
import { useTranslate } from 'react-admin'
|
||||||
import { subsonicUrl } from '../subsonic'
|
import { subsonicUrl } from '../subsonic'
|
||||||
import { DurationField } from '../common'
|
import { DurationField, formatRange } from '../common'
|
||||||
|
|
||||||
const AlbumDetails = ({ classes, record }) => {
|
const AlbumDetails = ({ classes, record }) => {
|
||||||
const translate = useTranslate()
|
const translate = useTranslate()
|
||||||
@@ -11,8 +11,9 @@ const AlbumDetails = ({ classes, record }) => {
|
|||||||
if (record.genre) {
|
if (record.genre) {
|
||||||
genreDateLine.push(record.genre)
|
genreDateLine.push(record.genre)
|
||||||
}
|
}
|
||||||
if (record.maxYear) {
|
const year = formatRange(record, 'year')
|
||||||
genreDateLine.push(record.maxYear)
|
if (year) {
|
||||||
|
genreDateLine.push(year)
|
||||||
}
|
}
|
||||||
return genreDateLine.join(' · ')
|
return genreDateLine.join(' · ')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
AutocompleteInput,
|
AutocompleteInput,
|
||||||
TextField
|
TextField
|
||||||
} from 'react-admin'
|
} from 'react-admin'
|
||||||
import { DurationField, Pagination, Title } from '../common'
|
import { DurationField, Pagination, Title, RangeField } from '../common'
|
||||||
import { useMediaQuery } from '@material-ui/core'
|
import { useMediaQuery } from '@material-ui/core'
|
||||||
|
|
||||||
const AlbumFilter = (props) => (
|
const AlbumFilter = (props) => (
|
||||||
@@ -31,7 +31,7 @@ const AlbumFilter = (props) => (
|
|||||||
<AutocompleteInput emptyText="-- None --" />
|
<AutocompleteInput emptyText="-- None --" />
|
||||||
</ReferenceInput>
|
</ReferenceInput>
|
||||||
<NullableBooleanInput source="compilation" />
|
<NullableBooleanInput source="compilation" />
|
||||||
<NumberInput source="max_year" />
|
<NumberInput source="year" />
|
||||||
</Filter>
|
</Filter>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ const AlbumList = (props) => {
|
|||||||
render={(r) => (r.albumArtist ? r.albumArtist : r.artist)}
|
render={(r) => (r.albumArtist ? r.albumArtist : r.artist)}
|
||||||
/>
|
/>
|
||||||
{isDesktop && <NumberField source="songCount" />}
|
{isDesktop && <NumberField source="songCount" />}
|
||||||
<TextField source="maxYear" />
|
<RangeField source={'year'} sortBy={'maxYear'} />
|
||||||
{isDesktop && <DurationField source="duration" />}
|
{isDesktop && <DurationField source="duration" />}
|
||||||
</Datagrid>
|
</Datagrid>
|
||||||
</List>
|
</List>
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
const formatRange = (record, source) => {
|
||||||
|
const nameCapitalized = source.charAt(0).toUpperCase() + source.slice(1)
|
||||||
|
const min = record[`min${nameCapitalized}`]
|
||||||
|
const max = record[`max${nameCapitalized}`]
|
||||||
|
let range = []
|
||||||
|
if (min) {
|
||||||
|
range.push(min)
|
||||||
|
}
|
||||||
|
if (max && max !== min) {
|
||||||
|
range.push(max)
|
||||||
|
}
|
||||||
|
return range.join('-')
|
||||||
|
}
|
||||||
|
|
||||||
|
const RangeField = ({ record = {}, source }) => {
|
||||||
|
return <span>{formatRange(record, source)}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeField.propTypes = {
|
||||||
|
label: PropTypes.string,
|
||||||
|
record: PropTypes.object,
|
||||||
|
source: PropTypes.string.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeField.defaultProps = {
|
||||||
|
addLabel: true
|
||||||
|
}
|
||||||
|
|
||||||
|
export { formatRange }
|
||||||
|
export default RangeField
|
||||||
@@ -4,6 +4,7 @@ import BitrateField from './BitrateField'
|
|||||||
import Pagination from './Pagination'
|
import Pagination from './Pagination'
|
||||||
import PlayButton from './PlayButton'
|
import PlayButton from './PlayButton'
|
||||||
import SimpleList from './SimpleList'
|
import SimpleList from './SimpleList'
|
||||||
|
import RangeField, { formatRange } from './RangeField'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Title,
|
Title,
|
||||||
@@ -11,5 +12,7 @@ export {
|
|||||||
BitrateField,
|
BitrateField,
|
||||||
Pagination,
|
Pagination,
|
||||||
PlayButton,
|
PlayButton,
|
||||||
SimpleList
|
SimpleList,
|
||||||
|
RangeField,
|
||||||
|
formatRange
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user