mirror of
https://github.com/lidarr/lidarr.git
synced 2025-07-16 10:03:51 -07:00
Artist index poster improvements
This commit is contained in:
parent
f0fceb1499
commit
bd5aaf9839
11 changed files with 155 additions and 30 deletions
|
@ -14,6 +14,7 @@ function createMapStateToProps() {
|
|||
bannerOptions,
|
||||
showRelativeDates: uiSettings.showRelativeDates,
|
||||
shortDateFormat: uiSettings.shortDateFormat,
|
||||
longDateFormat: uiSettings.longDateFormat,
|
||||
timeFormat: uiSettings.timeFormat,
|
||||
isSmallScreen: dimensions.isSmallScreen
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@ $hoverScale: 1.05;
|
|||
font-size: 20px;
|
||||
}
|
||||
|
||||
.nextAiring {
|
||||
.nextAlbum {
|
||||
background-color: var(--artistBackgroundColor);
|
||||
text-align: center;
|
||||
font-size: $smallFontSize;
|
||||
|
|
|
@ -7,7 +7,7 @@ interface CssExports {
|
|||
'controls': string;
|
||||
'ended': string;
|
||||
'link': string;
|
||||
'nextAiring': string;
|
||||
'nextAlbum': string;
|
||||
'overlayTitle': string;
|
||||
'posterContainer': string;
|
||||
'title': string;
|
||||
|
|
|
@ -73,7 +73,8 @@ class ArtistIndexPoster extends Component {
|
|||
monitored,
|
||||
foreignArtistId,
|
||||
status,
|
||||
nextAiring,
|
||||
nextAlbum,
|
||||
lastAlbum,
|
||||
statistics,
|
||||
images,
|
||||
posterWidth,
|
||||
|
@ -83,9 +84,11 @@ class ArtistIndexPoster extends Component {
|
|||
showMonitored,
|
||||
showQualityProfile,
|
||||
qualityProfile,
|
||||
showNextAlbum,
|
||||
showSearchAction,
|
||||
showRelativeDates,
|
||||
shortDateFormat,
|
||||
longDateFormat,
|
||||
timeFormat,
|
||||
isRefreshingArtist,
|
||||
isSearchingArtist,
|
||||
|
@ -118,7 +121,7 @@ class ArtistIndexPoster extends Component {
|
|||
return (
|
||||
<div>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.posterContainer}>
|
||||
<div className={styles.posterContainer} title={artistName}>
|
||||
<Label className={styles.controls}>
|
||||
<SpinnerIconButton
|
||||
className={styles.action}
|
||||
|
@ -193,7 +196,7 @@ class ArtistIndexPoster extends Component {
|
|||
|
||||
{
|
||||
showTitle &&
|
||||
<div className={styles.title}>
|
||||
<div className={styles.title} title={artistName}>
|
||||
{artistName}
|
||||
</div>
|
||||
}
|
||||
|
@ -207,16 +210,17 @@ class ArtistIndexPoster extends Component {
|
|||
|
||||
{
|
||||
showQualityProfile &&
|
||||
<div className={styles.title}>
|
||||
<div className={styles.title} title={translate('QualityProfile')}>
|
||||
{qualityProfile.name}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
nextAiring &&
|
||||
<div className={styles.nextAiring}>
|
||||
showNextAlbum && !!nextAlbum?.releaseDate &&
|
||||
<div className={styles.nextAlbum} title={translate('NextAlbum')}>
|
||||
{
|
||||
getRelativeDate(
|
||||
nextAiring,
|
||||
nextAlbum.releaseDate,
|
||||
shortDateFormat,
|
||||
showRelativeDates,
|
||||
{
|
||||
|
@ -228,12 +232,16 @@ class ArtistIndexPoster extends Component {
|
|||
</div>
|
||||
}
|
||||
<ArtistIndexPosterInfo
|
||||
nextAlbum={nextAlbum}
|
||||
lastAlbum={lastAlbum}
|
||||
albumCount={albumCount}
|
||||
sizeOnDisk={sizeOnDisk}
|
||||
qualityProfile={qualityProfile}
|
||||
showQualityProfile={showQualityProfile}
|
||||
showNextAlbum={showNextAlbum}
|
||||
showRelativeDates={showRelativeDates}
|
||||
shortDateFormat={shortDateFormat}
|
||||
longDateFormat={longDateFormat}
|
||||
timeFormat={timeFormat}
|
||||
{...otherProps}
|
||||
/>
|
||||
|
@ -262,7 +270,8 @@ ArtistIndexPoster.propTypes = {
|
|||
monitored: PropTypes.bool.isRequired,
|
||||
status: PropTypes.string.isRequired,
|
||||
foreignArtistId: PropTypes.string.isRequired,
|
||||
nextAiring: PropTypes.string,
|
||||
nextAlbum: PropTypes.object,
|
||||
lastAlbum: PropTypes.object,
|
||||
statistics: PropTypes.object.isRequired,
|
||||
images: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
posterWidth: PropTypes.number.isRequired,
|
||||
|
@ -272,9 +281,11 @@ ArtistIndexPoster.propTypes = {
|
|||
showMonitored: PropTypes.bool.isRequired,
|
||||
showQualityProfile: PropTypes.bool.isRequired,
|
||||
qualityProfile: PropTypes.object.isRequired,
|
||||
showNextAlbum: PropTypes.bool.isRequired,
|
||||
showSearchAction: PropTypes.bool.isRequired,
|
||||
showRelativeDates: PropTypes.bool.isRequired,
|
||||
shortDateFormat: PropTypes.string.isRequired,
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired,
|
||||
isRefreshingArtist: PropTypes.bool.isRequired,
|
||||
isSearchingArtist: PropTypes.bool.isRequired,
|
||||
|
|
|
@ -1,38 +1,86 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import TagListConnector from 'Components/TagListConnector';
|
||||
import formatDateTime from 'Utilities/Date/formatDateTime';
|
||||
import getRelativeDate from 'Utilities/Date/getRelativeDate';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import styles from './ArtistIndexPosterInfo.css';
|
||||
|
||||
function ArtistIndexPosterInfo(props) {
|
||||
const {
|
||||
artistType,
|
||||
qualityProfile,
|
||||
showQualityProfile,
|
||||
previousAiring,
|
||||
showNextAlbum,
|
||||
nextAlbum,
|
||||
lastAlbum,
|
||||
added,
|
||||
albumCount,
|
||||
path,
|
||||
sizeOnDisk,
|
||||
tags,
|
||||
sortKey,
|
||||
showRelativeDates,
|
||||
shortDateFormat,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
} = props;
|
||||
|
||||
if (sortKey === 'artistType' && artistType) {
|
||||
return (
|
||||
<div className={styles.info} title={translate('ArtistType')}>
|
||||
{artistType}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'qualityProfileId' && !showQualityProfile) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.info} title={translate('QualityProfile')}>
|
||||
{qualityProfile.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'previousAiring' && previousAiring) {
|
||||
if (sortKey === 'nextAlbum' && !showNextAlbum && !!nextAlbum?.releaseDate) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div
|
||||
className={styles.info}
|
||||
title={`${translate('NextAlbum')}: ${formatDateTime(
|
||||
nextAlbum.releaseDate,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
)}`}
|
||||
>
|
||||
{
|
||||
getRelativeDate(
|
||||
previousAiring,
|
||||
nextAlbum.releaseDate,
|
||||
shortDateFormat,
|
||||
showRelativeDates,
|
||||
{
|
||||
timeFormat,
|
||||
timeForToday: true
|
||||
}
|
||||
)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'lastAlbum' && !!lastAlbum?.releaseDate) {
|
||||
return (
|
||||
<div
|
||||
className={styles.info}
|
||||
title={`${translate('LastAlbum')}: ${formatDateTime(
|
||||
lastAlbum.releaseDate,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
)}`}
|
||||
>
|
||||
{
|
||||
getRelativeDate(
|
||||
lastAlbum.releaseDate,
|
||||
shortDateFormat,
|
||||
showRelativeDates,
|
||||
{
|
||||
|
@ -57,19 +105,22 @@ function ArtistIndexPosterInfo(props) {
|
|||
);
|
||||
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
{`Added ${addedDate}`}
|
||||
<div
|
||||
className={styles.info}
|
||||
title={formatDateTime(added, longDateFormat, timeFormat)}
|
||||
>
|
||||
{translate('Added')}: {addedDate}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'albumCount') {
|
||||
let albums = '1 album';
|
||||
let albums = translate('OneAlbum');
|
||||
|
||||
if (albumCount === 0) {
|
||||
albums = 'No albums';
|
||||
albums = translate('NoAlbums');
|
||||
} else if (albumCount > 1) {
|
||||
albums = `${albumCount} albums`;
|
||||
albums = translate('CountAlbums', [albumCount]);
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -81,7 +132,7 @@ function ArtistIndexPosterInfo(props) {
|
|||
|
||||
if (sortKey === 'path') {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.info} title={translate('Path')}>
|
||||
{path}
|
||||
</div>
|
||||
);
|
||||
|
@ -89,26 +140,41 @@ function ArtistIndexPosterInfo(props) {
|
|||
|
||||
if (sortKey === 'sizeOnDisk') {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.info} title={translate('SizeOnDisk')}>
|
||||
{formatBytes(sizeOnDisk)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'tags') {
|
||||
return (
|
||||
<div className={styles.info} title={translate('Tags')}>
|
||||
<TagListConnector
|
||||
tags={tags}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
ArtistIndexPosterInfo.propTypes = {
|
||||
artistType: PropTypes.string,
|
||||
qualityProfile: PropTypes.object.isRequired,
|
||||
showQualityProfile: PropTypes.bool.isRequired,
|
||||
previousAiring: PropTypes.string,
|
||||
showNextAlbum: PropTypes.bool.isRequired,
|
||||
nextAlbum: PropTypes.object,
|
||||
lastAlbum: PropTypes.object,
|
||||
added: PropTypes.string,
|
||||
albumCount: PropTypes.number.isRequired,
|
||||
path: PropTypes.string.isRequired,
|
||||
sizeOnDisk: PropTypes.number,
|
||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
sortKey: PropTypes.string.isRequired,
|
||||
showRelativeDates: PropTypes.bool.isRequired,
|
||||
shortDateFormat: PropTypes.string.isRequired,
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -38,7 +38,8 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
|
|||
detailedProgressBar,
|
||||
showTitle,
|
||||
showMonitored,
|
||||
showQualityProfile
|
||||
showQualityProfile,
|
||||
showNextAlbum
|
||||
} = posterOptions;
|
||||
|
||||
const nextAiringHeight = 19;
|
||||
|
@ -62,12 +63,19 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
|
|||
heights.push(19);
|
||||
}
|
||||
|
||||
if (showNextAlbum) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
||||
switch (sortKey) {
|
||||
case 'artistType':
|
||||
case 'lastAlbum':
|
||||
case 'seasons':
|
||||
case 'previousAiring':
|
||||
case 'added':
|
||||
case 'albumCount':
|
||||
case 'path':
|
||||
case 'sizeOnDisk':
|
||||
case 'tags':
|
||||
heights.push(19);
|
||||
break;
|
||||
case 'qualityProfileId':
|
||||
|
@ -75,6 +83,11 @@ function calculateRowHeight(posterHeight, sortKey, isSmallScreen, posterOptions)
|
|||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
case 'nextAlbum':
|
||||
if (!showNextAlbum) {
|
||||
heights.push(19);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// No need to add a height of 0
|
||||
}
|
||||
|
@ -197,6 +210,7 @@ class ArtistIndexPosters extends Component {
|
|||
posterOptions,
|
||||
showRelativeDates,
|
||||
shortDateFormat,
|
||||
longDateFormat,
|
||||
timeFormat
|
||||
} = this.props;
|
||||
|
||||
|
@ -210,7 +224,8 @@ class ArtistIndexPosters extends Component {
|
|||
detailedProgressBar,
|
||||
showTitle,
|
||||
showMonitored,
|
||||
showQualityProfile
|
||||
showQualityProfile,
|
||||
showNextAlbum
|
||||
} = posterOptions;
|
||||
|
||||
const artist = items[rowIndex * columnCount + columnIndex];
|
||||
|
@ -237,8 +252,10 @@ class ArtistIndexPosters extends Component {
|
|||
showTitle={showTitle}
|
||||
showMonitored={showMonitored}
|
||||
showQualityProfile={showQualityProfile}
|
||||
showNextAlbum={showNextAlbum}
|
||||
showRelativeDates={showRelativeDates}
|
||||
shortDateFormat={shortDateFormat}
|
||||
longDateFormat={longDateFormat}
|
||||
timeFormat={timeFormat}
|
||||
style={style}
|
||||
artistId={artist.id}
|
||||
|
@ -326,8 +343,9 @@ ArtistIndexPosters.propTypes = {
|
|||
scroller: PropTypes.instanceOf(Element).isRequired,
|
||||
showRelativeDates: PropTypes.bool.isRequired,
|
||||
shortDateFormat: PropTypes.string.isRequired,
|
||||
isSmallScreen: PropTypes.bool.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired
|
||||
longDateFormat: PropTypes.string.isRequired,
|
||||
timeFormat: PropTypes.string.isRequired,
|
||||
isSmallScreen: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
export default ArtistIndexPosters;
|
||||
|
|
|
@ -14,6 +14,7 @@ function createMapStateToProps() {
|
|||
posterOptions,
|
||||
showRelativeDates: uiSettings.showRelativeDates,
|
||||
shortDateFormat: uiSettings.shortDateFormat,
|
||||
longDateFormat: uiSettings.longDateFormat,
|
||||
timeFormat: uiSettings.timeFormat,
|
||||
isSmallScreen: dimensions.isSmallScreen
|
||||
};
|
||||
|
|
|
@ -33,6 +33,7 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
showTitle: props.showTitle,
|
||||
showMonitored: props.showMonitored,
|
||||
showQualityProfile: props.showQualityProfile,
|
||||
showNextAlbum: props.showNextAlbum,
|
||||
showSearchAction: props.showSearchAction
|
||||
};
|
||||
}
|
||||
|
@ -44,6 +45,7 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
showTitle,
|
||||
showMonitored,
|
||||
showQualityProfile,
|
||||
showNextAlbum,
|
||||
showSearchAction
|
||||
} = this.props;
|
||||
|
||||
|
@ -69,6 +71,10 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
state.showQualityProfile = showQualityProfile;
|
||||
}
|
||||
|
||||
if (showNextAlbum !== prevProps.showNextAlbum) {
|
||||
state.showNextAlbum = showNextAlbum;
|
||||
}
|
||||
|
||||
if (showSearchAction !== prevProps.showSearchAction) {
|
||||
state.showSearchAction = showSearchAction;
|
||||
}
|
||||
|
@ -103,6 +109,7 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
showTitle,
|
||||
showMonitored,
|
||||
showQualityProfile,
|
||||
showNextAlbum,
|
||||
showSearchAction
|
||||
} = this.state;
|
||||
|
||||
|
@ -184,6 +191,20 @@ class ArtistIndexPosterOptionsModalContent extends Component {
|
|||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>
|
||||
{translate('ShowNextAlbum')}
|
||||
</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="showNextAlbum"
|
||||
value={showNextAlbum}
|
||||
helpText={translate('ShowNextAlbumHelpText')}
|
||||
onChange={this.onChangePosterOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>
|
||||
{translate('ShowSearch')}
|
||||
|
@ -217,6 +238,7 @@ ArtistIndexPosterOptionsModalContent.propTypes = {
|
|||
showTitle: PropTypes.bool.isRequired,
|
||||
showMonitored: PropTypes.bool.isRequired,
|
||||
showQualityProfile: PropTypes.bool.isRequired,
|
||||
showNextAlbum: PropTypes.bool.isRequired,
|
||||
detailedProgressBar: PropTypes.bool.isRequired,
|
||||
showSearchAction: PropTypes.bool.isRequired,
|
||||
onChangePosterOption: PropTypes.func.isRequired,
|
||||
|
|
|
@ -89,11 +89,11 @@ export const filterPredicates = {
|
|||
},
|
||||
|
||||
nextAlbum: function(item, filterValue, type) {
|
||||
return dateFilterPredicate(item.nextAlbum, filterValue, type);
|
||||
return dateFilterPredicate(item.nextAlbum?.releaseDate, filterValue, type);
|
||||
},
|
||||
|
||||
lastAlbum: function(item, filterValue, type) {
|
||||
return dateFilterPredicate(item.lastAlbum, filterValue, type);
|
||||
return dateFilterPredicate(item.lastAlbum?.releaseDate, filterValue, type);
|
||||
},
|
||||
|
||||
added: function(item, filterValue, type) {
|
||||
|
|
|
@ -29,6 +29,7 @@ export const defaultState = {
|
|||
showTitle: true,
|
||||
showMonitored: true,
|
||||
showQualityProfile: true,
|
||||
showNextAlbum: true,
|
||||
showSearchAction: false
|
||||
},
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue