mirror of
https://github.com/Radarr/Radarr.git
synced 2024-11-19 17:32:38 +01:00
Fixed: Improve sorting movies by release dates
This commit is contained in:
parent
bf84471509
commit
df77474314
@ -106,7 +106,7 @@ function MovieIndexSortMenu(props: MovieIndexSortMenuProps) {
|
||||
sortDirection={sortDirection}
|
||||
onPress={onSortSelect}
|
||||
>
|
||||
{translate('ReleaseDates')}
|
||||
{translate('ReleaseDate')}
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
|
@ -75,6 +75,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
inCinemas,
|
||||
physicalRelease,
|
||||
digitalRelease,
|
||||
releaseDate,
|
||||
path,
|
||||
movieFile,
|
||||
ratings,
|
||||
@ -142,20 +143,6 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
height: `${posterHeight}px`,
|
||||
};
|
||||
|
||||
let releaseDate = '';
|
||||
let releaseDateType = '';
|
||||
if (physicalRelease && digitalRelease) {
|
||||
releaseDate =
|
||||
physicalRelease < digitalRelease ? physicalRelease : digitalRelease;
|
||||
releaseDateType = physicalRelease < digitalRelease ? 'Released' : 'Digital';
|
||||
} else if (physicalRelease && !digitalRelease) {
|
||||
releaseDate = physicalRelease;
|
||||
releaseDateType = 'Released';
|
||||
} else if (digitalRelease && !physicalRelease) {
|
||||
releaseDate = digitalRelease;
|
||||
releaseDateType = 'Digital';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.content}>
|
||||
<div className={styles.posterContainer} title={title}>
|
||||
@ -262,10 +249,8 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
) : null}
|
||||
|
||||
{showReleaseDate && releaseDate ? (
|
||||
<div className={styles.title}>
|
||||
<Icon
|
||||
name={releaseDateType === 'Digital' ? icons.MOVIE_FILE : icons.DISC}
|
||||
/>{' '}
|
||||
<div className={styles.title} title={translate('ReleaseDate')}>
|
||||
<Icon name={icons.CALENDAR} />{' '}
|
||||
{getRelativeDate(releaseDate, shortDateFormat, showRelativeDates, {
|
||||
timeFormat,
|
||||
timeForToday: false,
|
||||
@ -314,6 +299,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
|
||||
inCinemas={inCinemas}
|
||||
physicalRelease={physicalRelease}
|
||||
digitalRelease={digitalRelease}
|
||||
releaseDate={releaseDate}
|
||||
ratings={ratings}
|
||||
sizeOnDisk={sizeOnDisk}
|
||||
sortKey={sortKey}
|
||||
|
@ -23,6 +23,7 @@ interface MovieIndexPosterInfoProps {
|
||||
inCinemas?: string;
|
||||
digitalRelease?: string;
|
||||
physicalRelease?: string;
|
||||
releaseDate?: string;
|
||||
path: string;
|
||||
ratings: Ratings;
|
||||
certification: string;
|
||||
@ -53,6 +54,7 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
inCinemas,
|
||||
digitalRelease,
|
||||
physicalRelease,
|
||||
releaseDate,
|
||||
path,
|
||||
ratings,
|
||||
certification,
|
||||
@ -152,7 +154,7 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.info} title={translate('DigitalRelease')}>
|
||||
<Icon name={icons.MOVIE_FILE} /> {digitalReleaseDate}
|
||||
</div>
|
||||
);
|
||||
@ -170,12 +172,24 @@ function MovieIndexPosterInfo(props: MovieIndexPosterInfoProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.info} title={translate('PhysicalRelease')}>
|
||||
<Icon name={icons.DISC} /> {physicalReleaseDate}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (sortKey === 'releaseDate' && releaseDate && !showReleaseDate) {
|
||||
return (
|
||||
<div className={styles.info} title={translate('ReleaseDate')}>
|
||||
<Icon name={icons.CALENDAR} />{' '}
|
||||
{getRelativeDate(releaseDate, shortDateFormat, showRelativeDates, {
|
||||
timeFormat,
|
||||
timeForToday: false,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!showTmdbRating && sortKey === 'tmdbRating' && !!ratings.tmdb) {
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
|
@ -218,6 +218,7 @@ export default function MovieIndexPosters(props: MovieIndexPostersProps) {
|
||||
break;
|
||||
case 'digitalRelease':
|
||||
case 'physicalRelease':
|
||||
case 'releaseDate':
|
||||
if (!showReleaseDate) {
|
||||
heights.push(19);
|
||||
}
|
||||
|
@ -42,6 +42,7 @@
|
||||
.inCinemas,
|
||||
.physicalRelease,
|
||||
.digitalRelease,
|
||||
.releaseDate,
|
||||
.genres {
|
||||
composes: cell;
|
||||
|
||||
|
@ -20,6 +20,7 @@ interface CssExports {
|
||||
'physicalRelease': string;
|
||||
'popularity': string;
|
||||
'qualityProfileId': string;
|
||||
'releaseDate': string;
|
||||
'releaseGroups': string;
|
||||
'rottenTomatoesRating': string;
|
||||
'runtime': string;
|
||||
|
@ -66,6 +66,7 @@ function MovieIndexRow(props: MovieIndexRowProps) {
|
||||
inCinemas,
|
||||
digitalRelease,
|
||||
physicalRelease,
|
||||
releaseDate,
|
||||
runtime,
|
||||
minimumAvailability,
|
||||
path,
|
||||
@ -278,6 +279,19 @@ function MovieIndexRow(props: MovieIndexRowProps) {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'releaseDate') {
|
||||
return (
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore ts(2739)
|
||||
<RelativeDateCellConnector
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
date={releaseDate}
|
||||
component={VirtualTableRowCell}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'runtime') {
|
||||
return (
|
||||
<VirtualTableRowCell key={name} className={styles[name]}>
|
||||
|
@ -35,6 +35,7 @@
|
||||
.inCinemas,
|
||||
.physicalRelease,
|
||||
.digitalRelease,
|
||||
.releaseDate,
|
||||
.genres {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
|
@ -17,6 +17,7 @@ interface CssExports {
|
||||
'physicalRelease': string;
|
||||
'popularity': string;
|
||||
'qualityProfileId': string;
|
||||
'releaseDate': string;
|
||||
'releaseGroups': string;
|
||||
'rottenTomatoesRating': string;
|
||||
'runtime': string;
|
||||
|
@ -42,16 +42,17 @@ interface Movie extends ModelBase {
|
||||
status: MovieStatus;
|
||||
title: string;
|
||||
titleSlug: string;
|
||||
originalTitle: string;
|
||||
originalLanguage: Language;
|
||||
collection: Collection;
|
||||
studio: string;
|
||||
qualityProfileId: number;
|
||||
added: string;
|
||||
year: number;
|
||||
inCinemas: string;
|
||||
physicalRelease: string;
|
||||
originalLanguage: Language;
|
||||
originalTitle: string;
|
||||
digitalRelease: string;
|
||||
inCinemas?: string;
|
||||
physicalRelease?: string;
|
||||
digitalRelease?: string;
|
||||
releaseDate?: string;
|
||||
runtime: number;
|
||||
minimumAvailability: string;
|
||||
path: string;
|
||||
|
@ -258,8 +258,10 @@ export const sortPredicates = {
|
||||
},
|
||||
|
||||
inCinemas: function(item, direction) {
|
||||
if (item.inCinemas) {
|
||||
return moment(item.inCinemas).unix();
|
||||
const { inCinemas } = item;
|
||||
|
||||
if (inCinemas) {
|
||||
return moment(inCinemas).unix();
|
||||
}
|
||||
|
||||
if (direction === sortDirections.DESCENDING) {
|
||||
@ -270,8 +272,10 @@ export const sortPredicates = {
|
||||
},
|
||||
|
||||
physicalRelease: function(item, direction) {
|
||||
if (item.physicalRelease) {
|
||||
return moment(item.physicalRelease).unix();
|
||||
const { physicalRelease } = item;
|
||||
|
||||
if (physicalRelease) {
|
||||
return moment(physicalRelease).unix();
|
||||
}
|
||||
|
||||
if (direction === sortDirections.DESCENDING) {
|
||||
@ -282,8 +286,10 @@ export const sortPredicates = {
|
||||
},
|
||||
|
||||
digitalRelease: function(item, direction) {
|
||||
if (item.digitalRelease) {
|
||||
return moment(item.digitalRelease).unix();
|
||||
const { digitalRelease } = item;
|
||||
|
||||
if (digitalRelease) {
|
||||
return moment(digitalRelease).unix();
|
||||
}
|
||||
|
||||
if (direction === sortDirections.DESCENDING) {
|
||||
@ -294,8 +300,7 @@ export const sortPredicates = {
|
||||
},
|
||||
|
||||
releaseDate: function(item, direction) {
|
||||
const { inCinemas, digitalRelease, physicalRelease } = item;
|
||||
const releaseDate = digitalRelease || physicalRelease || inCinemas;
|
||||
const { releaseDate } = item;
|
||||
|
||||
if (releaseDate) {
|
||||
return moment(releaseDate).unix();
|
||||
|
@ -142,6 +142,12 @@ export const defaultState = {
|
||||
isSortable: true,
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'releaseDate',
|
||||
label: () => translate('ReleaseDate'),
|
||||
isSortable: true,
|
||||
isVisible: false
|
||||
},
|
||||
{
|
||||
name: 'runtime',
|
||||
label: () => translate('Runtime'),
|
||||
@ -433,6 +439,12 @@ export const defaultState = {
|
||||
type: filterBuilderTypes.DATE,
|
||||
valueType: filterBuilderValueTypes.DATE
|
||||
},
|
||||
{
|
||||
name: 'releaseDate',
|
||||
label: () => translate('ReleaseDate'),
|
||||
type: filterBuilderTypes.DATE,
|
||||
valueType: filterBuilderValueTypes.DATE
|
||||
},
|
||||
{
|
||||
name: 'runtime',
|
||||
label: () => translate('Runtime'),
|
||||
|
@ -1380,6 +1380,7 @@
|
||||
"RelativePath": "Relative Path",
|
||||
"Release": "Release",
|
||||
"ReleaseBranchCheckOfficialBranchMessage": "Branch {0} is not a valid {appName} release branch, you will not receive updates",
|
||||
"ReleaseDate": "Release Date",
|
||||
"ReleaseDates": "Release Dates",
|
||||
"ReleaseGroup": "Release Group",
|
||||
"ReleaseGroupFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Release Group:30}`) or the beginning (e.g. `{Release Group:-30}`) are both supported.`).",
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.MediaFiles;
|
||||
@ -117,6 +118,30 @@ public bool IsAvailable(int delay = 0)
|
||||
return DateTime.UtcNow >= minimumAvailabilityDate.AddDays(delay);
|
||||
}
|
||||
|
||||
public DateTime? GetReleaseDate()
|
||||
{
|
||||
if (MinimumAvailability is MovieStatusType.TBA or MovieStatusType.Announced)
|
||||
{
|
||||
return new[] { MovieMetadata.Value.InCinemas, MovieMetadata.Value.DigitalRelease, MovieMetadata.Value.PhysicalRelease }
|
||||
.Where(x => x.HasValue)
|
||||
.Min();
|
||||
}
|
||||
|
||||
if (MinimumAvailability == MovieStatusType.InCinemas && MovieMetadata.Value.InCinemas.HasValue)
|
||||
{
|
||||
return MovieMetadata.Value.InCinemas.Value;
|
||||
}
|
||||
|
||||
if (MovieMetadata.Value.DigitalRelease.HasValue || MovieMetadata.Value.PhysicalRelease.HasValue)
|
||||
{
|
||||
return new[] { MovieMetadata.Value.DigitalRelease, MovieMetadata.Value.PhysicalRelease }
|
||||
.Where(x => x.HasValue)
|
||||
.Min();
|
||||
}
|
||||
|
||||
return MovieMetadata.Value.InCinemas?.AddDays(90);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[{1} ({2})][{0}, {3}]", MovieMetadata.Value.ImdbId, MovieMetadata.Value.Title.NullSafe(), MovieMetadata.Value.Year.NullSafe(), MovieMetadata.Value.TmdbId);
|
||||
|
@ -42,6 +42,7 @@ public MovieResource()
|
||||
public DateTime? InCinemas { get; set; }
|
||||
public DateTime? PhysicalRelease { get; set; }
|
||||
public DateTime? DigitalRelease { get; set; }
|
||||
public DateTime? ReleaseDate { get; set; }
|
||||
public string PhysicalReleaseNote { get; set; }
|
||||
public List<MediaCover> Images { get; set; }
|
||||
public string Website { get; set; }
|
||||
@ -122,6 +123,7 @@ public static MovieResource ToResource(this Movie model, int availDelay, MovieTr
|
||||
InCinemas = model.MovieMetadata.Value.InCinemas,
|
||||
PhysicalRelease = model.MovieMetadata.Value.PhysicalRelease,
|
||||
DigitalRelease = model.MovieMetadata.Value.DigitalRelease,
|
||||
ReleaseDate = model.GetReleaseDate(),
|
||||
|
||||
Status = model.MovieMetadata.Value.Status,
|
||||
Overview = translatedOverview,
|
||||
|
Loading…
Reference in New Issue
Block a user