Artist index poster improvements

This commit is contained in:
Bogdan 2023-05-30 04:21:15 +03:00
parent f0fceb1499
commit bd5aaf9839
11 changed files with 155 additions and 30 deletions

View file

@ -14,6 +14,7 @@ function createMapStateToProps() {
bannerOptions,
showRelativeDates: uiSettings.showRelativeDates,
shortDateFormat: uiSettings.shortDateFormat,
longDateFormat: uiSettings.longDateFormat,
timeFormat: uiSettings.timeFormat,
isSmallScreen: dimensions.isSmallScreen
};

View file

@ -43,7 +43,7 @@ $hoverScale: 1.05;
font-size: 20px;
}
.nextAiring {
.nextAlbum {
background-color: var(--artistBackgroundColor);
text-align: center;
font-size: $smallFontSize;

View file

@ -7,7 +7,7 @@ interface CssExports {
'controls': string;
'ended': string;
'link': string;
'nextAiring': string;
'nextAlbum': string;
'overlayTitle': string;
'posterContainer': string;
'title': string;

View file

@ -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,

View file

@ -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
};

View file

@ -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;

View file

@ -14,6 +14,7 @@ function createMapStateToProps() {
posterOptions,
showRelativeDates: uiSettings.showRelativeDates,
shortDateFormat: uiSettings.shortDateFormat,
longDateFormat: uiSettings.longDateFormat,
timeFormat: uiSettings.timeFormat,
isSmallScreen: dimensions.isSmallScreen
};

View file

@ -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,

View file

@ -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) {

View file

@ -29,6 +29,7 @@ export const defaultState = {
showTitle: true,
showMonitored: true,
showQualityProfile: true,
showNextAlbum: true,
showSearchAction: false
},