diff --git a/persistence/album_repository.go b/persistence/album_repository.go index 7cf4f2691..8259533fd 100644 --- a/persistence/album_repository.go +++ b/persistence/album_repository.go @@ -29,11 +29,23 @@ func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository "name": fullTextFilter, "compilation": booleanFilter, "artist_id": artistFilter, + "year": yearFilter, } 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 { return Exists("media_file", And{ ConcatExpr("album_id=album.id"), diff --git a/ui/src/album/AlbumDetails.js b/ui/src/album/AlbumDetails.js index 719f4155d..dc218e4a0 100644 --- a/ui/src/album/AlbumDetails.js +++ b/ui/src/album/AlbumDetails.js @@ -2,7 +2,7 @@ import React from 'react' import { Card, CardContent, CardMedia, Typography } from '@material-ui/core' import { useTranslate } from 'react-admin' import { subsonicUrl } from '../subsonic' -import { DurationField } from '../common' +import { DurationField, formatRange } from '../common' const AlbumDetails = ({ classes, record }) => { const translate = useTranslate() @@ -11,8 +11,9 @@ const AlbumDetails = ({ classes, record }) => { if (record.genre) { genreDateLine.push(record.genre) } - if (record.maxYear) { - genreDateLine.push(record.maxYear) + const year = formatRange(record, 'year') + if (year) { + genreDateLine.push(year) } return genreDateLine.join(' ยท ') } diff --git a/ui/src/album/AlbumList.js b/ui/src/album/AlbumList.js index 0d1c96ecc..8ece0d642 100644 --- a/ui/src/album/AlbumList.js +++ b/ui/src/album/AlbumList.js @@ -16,7 +16,7 @@ import { AutocompleteInput, TextField } from 'react-admin' -import { DurationField, Pagination, Title } from '../common' +import { DurationField, Pagination, Title, RangeField } from '../common' import { useMediaQuery } from '@material-ui/core' const AlbumFilter = (props) => ( @@ -31,7 +31,7 @@ const AlbumFilter = (props) => ( - + ) @@ -68,7 +68,7 @@ const AlbumList = (props) => { render={(r) => (r.albumArtist ? r.albumArtist : r.artist)} /> {isDesktop && } - + {isDesktop && } diff --git a/ui/src/common/RangeField.js b/ui/src/common/RangeField.js new file mode 100644 index 000000000..c57e5432f --- /dev/null +++ b/ui/src/common/RangeField.js @@ -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 {formatRange(record, source)} +} + +RangeField.propTypes = { + label: PropTypes.string, + record: PropTypes.object, + source: PropTypes.string.isRequired +} + +RangeField.defaultProps = { + addLabel: true +} + +export { formatRange } +export default RangeField diff --git a/ui/src/common/index.js b/ui/src/common/index.js index 3189a5fa5..790ba7981 100644 --- a/ui/src/common/index.js +++ b/ui/src/common/index.js @@ -4,6 +4,7 @@ import BitrateField from './BitrateField' import Pagination from './Pagination' import PlayButton from './PlayButton' import SimpleList from './SimpleList' +import RangeField, { formatRange } from './RangeField' export { Title, @@ -11,5 +12,7 @@ export { BitrateField, Pagination, PlayButton, - SimpleList + SimpleList, + RangeField, + formatRange }