mirror of
https://github.com/Radarr/Radarr.git
synced 2024-10-02 06:07:19 +02:00
New: Trending and Popular Movies in Discovery
This commit is contained in:
parent
3b1d4460ad
commit
0be449033f
@ -19,7 +19,7 @@ function ImportListList({ lists, importListList }) {
|
||||
return (
|
||||
<Label
|
||||
key={list.id}
|
||||
kind={kinds.INFO}
|
||||
kind={kinds.SUCCESS}
|
||||
size={sizes.MEDIUM}
|
||||
>
|
||||
{list.name}
|
||||
|
@ -97,6 +97,8 @@ class DiscoverMovieOverview extends Component {
|
||||
isExisting,
|
||||
isExcluded,
|
||||
isRecommendation,
|
||||
isPopular,
|
||||
isTrending,
|
||||
isSelected,
|
||||
overviewOptions,
|
||||
...otherProps
|
||||
@ -214,6 +216,26 @@ class DiscoverMovieOverview extends Component {
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
isPopular ?
|
||||
<Label
|
||||
kind={kinds.INFO}
|
||||
>
|
||||
{translate('Popular')}
|
||||
</Label> :
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
isTrending ?
|
||||
<Label
|
||||
kind={kinds.INFO}
|
||||
>
|
||||
{translate('Trending')}
|
||||
</Label> :
|
||||
null
|
||||
}
|
||||
|
||||
<ImportListListConnector
|
||||
lists={lists}
|
||||
/>
|
||||
@ -283,6 +305,8 @@ DiscoverMovieOverview.propTypes = {
|
||||
isExisting: PropTypes.bool.isRequired,
|
||||
isExcluded: PropTypes.bool.isRequired,
|
||||
isRecommendation: PropTypes.bool.isRequired,
|
||||
isPopular: PropTypes.bool.isRequired,
|
||||
isTrending: PropTypes.bool.isRequired,
|
||||
isSelected: PropTypes.bool,
|
||||
lists: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
onSelectedChange: PropTypes.func.isRequired
|
||||
|
@ -57,10 +57,12 @@
|
||||
flex: 0 0 115px;
|
||||
}
|
||||
|
||||
.isTrending,
|
||||
.isPopular,
|
||||
.isRecommendation {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
flex: 0 0 50px;
|
||||
flex: 0 0 30px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
|
@ -7,7 +7,9 @@ interface CssExports {
|
||||
'digitalRelease': string;
|
||||
'genres': string;
|
||||
'inCinemas': string;
|
||||
'isPopular': string;
|
||||
'isRecommendation': string;
|
||||
'isTrending': string;
|
||||
'lists': string;
|
||||
'originalLanguage': string;
|
||||
'physicalRelease': string;
|
||||
|
@ -103,6 +103,40 @@ class DiscoverMovieHeader extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'isTrending') {
|
||||
return (
|
||||
<VirtualTableHeaderCell
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
name={name}
|
||||
isSortable={true}
|
||||
{...otherProps}
|
||||
>
|
||||
<Icon
|
||||
name={icons.TRENDING}
|
||||
size={12}
|
||||
/>
|
||||
</VirtualTableHeaderCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'isPopular') {
|
||||
return (
|
||||
<VirtualTableHeaderCell
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
name={name}
|
||||
isSortable={true}
|
||||
{...otherProps}
|
||||
>
|
||||
<Icon
|
||||
name={icons.POPULAR}
|
||||
size={12}
|
||||
/>
|
||||
</VirtualTableHeaderCell>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<VirtualTableHeaderCell
|
||||
key={name}
|
||||
|
@ -76,10 +76,12 @@
|
||||
flex: 1 0 110px;
|
||||
}
|
||||
|
||||
.isTrending,
|
||||
.isPopular,
|
||||
.isRecommendation {
|
||||
composes: cell;
|
||||
|
||||
flex: 0 0 50px;
|
||||
flex: 0 0 30px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
@ -95,6 +97,11 @@
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.statusIcon {
|
||||
width: 20px !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.externalLinks {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ interface CssExports {
|
||||
'externalLinks': string;
|
||||
'genres': string;
|
||||
'inCinemas': string;
|
||||
'isPopular': string;
|
||||
'isRecommendation': string;
|
||||
'isTrending': string;
|
||||
'lists': string;
|
||||
'originalLanguage': string;
|
||||
'physicalRelease': string;
|
||||
@ -21,6 +23,7 @@ interface CssExports {
|
||||
'runtime': string;
|
||||
'sortTitle': string;
|
||||
'status': string;
|
||||
'statusIcon': string;
|
||||
'studio': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
|
@ -82,6 +82,8 @@ class DiscoverMovieRow extends Component {
|
||||
isExisting,
|
||||
isExcluded,
|
||||
isRecommendation,
|
||||
isTrending,
|
||||
isPopular,
|
||||
isSelected,
|
||||
lists,
|
||||
onSelectedChange
|
||||
@ -305,6 +307,7 @@ class DiscoverMovieRow extends Component {
|
||||
{
|
||||
isRecommendation ?
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.RECOMMENDED}
|
||||
size={12}
|
||||
title={translate('MovieIsRecommend')}
|
||||
@ -315,6 +318,46 @@ class DiscoverMovieRow extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'isTrending') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
>
|
||||
{
|
||||
isTrending ?
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.TRENDING}
|
||||
size={12}
|
||||
title={translate('MovieIsTrending')}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
</VirtualTableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'isPopular') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
key={name}
|
||||
className={styles[name]}
|
||||
>
|
||||
{
|
||||
isPopular ?
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={icons.POPULAR}
|
||||
size={12}
|
||||
title={translate('MovieIsPopular')}
|
||||
/> :
|
||||
null
|
||||
}
|
||||
</VirtualTableRowCell>
|
||||
);
|
||||
}
|
||||
|
||||
if (name === 'actions') {
|
||||
return (
|
||||
<VirtualTableRowCell
|
||||
@ -404,6 +447,8 @@ DiscoverMovieRow.propTypes = {
|
||||
isExcluded: PropTypes.bool.isRequired,
|
||||
isSelected: PropTypes.bool,
|
||||
isRecommendation: PropTypes.bool.isRequired,
|
||||
isPopular: PropTypes.bool.isRequired,
|
||||
isTrending: PropTypes.bool.isRequired,
|
||||
lists: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||
onSelectedChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
import {
|
||||
faArrowCircleLeft as fasArrowCircleLeft,
|
||||
faArrowCircleRight as fasArrowCircleRight,
|
||||
faArrowTrendUp as fasArrowTrendUp,
|
||||
faAsterisk as fasAsterisk,
|
||||
faBackward as fasBackward,
|
||||
faBan as fasBan,
|
||||
@ -233,6 +234,7 @@ export const TAGS = fasTags;
|
||||
export const TBA = fasQuestionCircle;
|
||||
export const TEST = fasVial;
|
||||
export const TRANSLATE = fasLanguage;
|
||||
export const TRENDING = fasArrowTrendUp;
|
||||
export const UNGROUP = farObjectUngroup;
|
||||
export const UNKNOWN = fasQuestion;
|
||||
export const UNMONITORED = farBookmark;
|
||||
|
@ -88,6 +88,20 @@ export const defaultState = {
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'isTrending',
|
||||
columnLabel: 'Trending',
|
||||
isSortable: true,
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'isPopular',
|
||||
columnLabel: 'Popular',
|
||||
isSortable: true,
|
||||
isVisible: true,
|
||||
isModifiable: false
|
||||
},
|
||||
{
|
||||
name: 'sortTitle',
|
||||
label: () => translate('MovieTitle'),
|
||||
@ -267,6 +281,28 @@ export const defaultState = {
|
||||
label: () => translate('All'),
|
||||
filters: []
|
||||
},
|
||||
{
|
||||
key: 'popular',
|
||||
label: 'Popular',
|
||||
filters: [
|
||||
{
|
||||
key: 'isPopular',
|
||||
value: true,
|
||||
type: filterTypes.EQUAL
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'trending',
|
||||
label: 'Trending',
|
||||
filters: [
|
||||
{
|
||||
key: 'isTrending',
|
||||
value: true,
|
||||
type: filterTypes.EQUAL
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'newNotExcluded',
|
||||
label: 'New Non-Excluded',
|
||||
@ -456,6 +492,18 @@ export const defaultState = {
|
||||
label: 'Recommended',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.BOOL
|
||||
},
|
||||
{
|
||||
name: 'isTrending',
|
||||
label: 'Trending',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.BOOL
|
||||
},
|
||||
{
|
||||
name: 'isPopular',
|
||||
label: 'Popular',
|
||||
type: filterBuilderTypes.EXACT,
|
||||
valueType: filterBuilderValueTypes.BOOL
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@ -877,7 +877,9 @@
|
||||
"MovieIsDownloading": "Movie is downloading",
|
||||
"MovieIsMonitored": "Movie is monitored",
|
||||
"MovieIsOnImportExclusionList": "Movie is on Import Exclusion List",
|
||||
"MovieIsPopular": "Movie is Popular on TMDb",
|
||||
"MovieIsRecommend": "Movie is recommended based on recent addition",
|
||||
"MovieIsTrending": "Movie is Trending on TMDb",
|
||||
"MovieIsUnmonitored": "Movie is unmonitored",
|
||||
"MovieMatchType": "Movie Match Type",
|
||||
"MovieNaming": "Movie Naming",
|
||||
|
@ -12,6 +12,8 @@ public interface IProvideMovieInfo
|
||||
Tuple<MovieMetadata, List<Credit>> GetMovieInfo(int tmdbId);
|
||||
MovieCollection GetCollectionInfo(int tmdbId);
|
||||
List<MovieMetadata> GetBulkMovieInfo(List<int> tmdbIds);
|
||||
List<MovieMetadata> GetTrendingMovies();
|
||||
List<MovieMetadata> GetPopularMovies();
|
||||
|
||||
HashSet<int> GetChangedMovies(DateTime startTime);
|
||||
}
|
||||
|
@ -70,6 +70,34 @@ public HashSet<int> GetChangedMovies(DateTime startTime)
|
||||
return new HashSet<int>(response.Resource);
|
||||
}
|
||||
|
||||
public List<MovieMetadata> GetTrendingMovies()
|
||||
{
|
||||
var request = _radarrMetadata.Create()
|
||||
.SetSegment("route", "list/tmdb/trending")
|
||||
.Build();
|
||||
|
||||
request.AllowAutoRedirect = true;
|
||||
request.SuppressHttpError = true;
|
||||
|
||||
var response = _httpClient.Get<List<MovieResource>>(request);
|
||||
|
||||
return response.Resource.DistinctBy(x => x.TmdbId).Select(MapMovie).ToList();
|
||||
}
|
||||
|
||||
public List<MovieMetadata> GetPopularMovies()
|
||||
{
|
||||
var request = _radarrMetadata.Create()
|
||||
.SetSegment("route", "list/tmdb/popular")
|
||||
.Build();
|
||||
|
||||
request.AllowAutoRedirect = true;
|
||||
request.SuppressHttpError = true;
|
||||
|
||||
var response = _httpClient.Get<List<MovieResource>>(request);
|
||||
|
||||
return response.Resource.DistinctBy(x => x.TmdbId).Select(MapMovie).ToList();
|
||||
}
|
||||
|
||||
public Tuple<MovieMetadata, List<Credit>> GetMovieInfo(int tmdbId)
|
||||
{
|
||||
var httpRequest = _radarrMetadata.Create()
|
||||
|
@ -54,7 +54,7 @@ public ImportListMoviesController(IMovieService movieService,
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public object GetDiscoverMovies(bool includeRecommendations = false)
|
||||
public object GetDiscoverMovies(bool includeRecommendations = false, bool includeTrending = false, bool includePopular = false)
|
||||
{
|
||||
var movieLanguage = (Language)_configService.MovieInfoLanguage;
|
||||
|
||||
@ -77,6 +77,17 @@ public object GetDiscoverMovies(bool includeRecommendations = false)
|
||||
realResults.ForEach(x => x.IsRecommendation = true);
|
||||
}
|
||||
|
||||
// Add TMDB Trending
|
||||
var trendingResults = _movieInfo.GetTrendingMovies();
|
||||
|
||||
realResults.AddRange(MapToResource(trendingResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, true));
|
||||
|
||||
// Add TMDB Popular
|
||||
var popularResults = _movieInfo.GetPopularMovies();
|
||||
|
||||
realResults.AddRange(MapToResource(popularResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, false, true));
|
||||
|
||||
// Add List Movies
|
||||
var listMovies = MapToResource(_listMovieService.GetAllForLists(_importListFactory.Enabled().Select(x => x.Definition.Id).ToList()), movieLanguage).ToList();
|
||||
|
||||
realResults.AddRange(listMovies);
|
||||
@ -92,6 +103,8 @@ public object GetDiscoverMovies(bool includeRecommendations = false)
|
||||
movie.IsExcluded = listExclusions.Any(e => e.TmdbId == movie.TmdbId);
|
||||
movie.IsExisting = existingTmdbIds.Any(e => e == movie.TmdbId);
|
||||
movie.IsRecommendation = x.Any(m => m.IsRecommendation);
|
||||
movie.IsPopular = x.Any(m => m.IsPopular);
|
||||
movie.IsTrending = x.Any(m => m.IsTrending);
|
||||
|
||||
return movie;
|
||||
}).ToList();
|
||||
@ -107,7 +120,7 @@ public object AddMovies([FromBody] List<MovieResource> resource)
|
||||
return _addMovieService.AddMovies(newMovies, true).ToResource(0);
|
||||
}
|
||||
|
||||
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language)
|
||||
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language, bool isTrending = false, bool isPopular = false)
|
||||
{
|
||||
// Avoid calling for naming spec on every movie in filenamebuilder
|
||||
var namingConfig = _namingService.GetConfig();
|
||||
@ -127,6 +140,8 @@ private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> m
|
||||
resource.Title = translation?.Title ?? resource.Title;
|
||||
resource.Overview = translation?.Overview ?? resource.Overview;
|
||||
resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie, namingConfig);
|
||||
resource.IsTrending = isTrending;
|
||||
resource.IsPopular = isPopular;
|
||||
|
||||
yield return resource;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ public ImportListMoviesResource()
|
||||
public MovieCollection Collection { get; set; }
|
||||
public bool IsExcluded { get; set; }
|
||||
public bool IsExisting { get; set; }
|
||||
public bool IsTrending { get; set; }
|
||||
public bool IsPopular { get; set; }
|
||||
|
||||
public bool IsRecommendation { get; set; }
|
||||
public HashSet<int> Lists { get; set; }
|
||||
|
Loading…
Reference in New Issue
Block a user