mirror of
https://github.com/Radarr/Radarr.git
synced 2025-04-23 22:17:15 -04:00
New: Include trending and popular options for Discover Movies
This commit is contained in:
parent
7be8a34130
commit
685f462959
8 changed files with 198 additions and 44 deletions
|
@ -75,9 +75,19 @@ class DiscoverMovie extends Component {
|
|||
const {
|
||||
items,
|
||||
sortKey,
|
||||
sortDirection
|
||||
sortDirection,
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.props;
|
||||
|
||||
if (includeRecommendations !== prevProps.includeRecommendations ||
|
||||
includeTrending !== prevProps.includeTrending ||
|
||||
includePopular !== prevProps.includePopular
|
||||
) {
|
||||
this.props.dispatchFetchListMovies();
|
||||
}
|
||||
|
||||
if (sortKey !== prevProps.sortKey ||
|
||||
sortDirection !== prevProps.sortDirection ||
|
||||
hasDifferentItemsOrOrder(prevProps.items, items)
|
||||
|
@ -443,6 +453,9 @@ DiscoverMovie.propTypes = {
|
|||
sortKey: PropTypes.string,
|
||||
sortDirection: PropTypes.oneOf(sortDirections.all),
|
||||
view: PropTypes.string.isRequired,
|
||||
includeRecommendations: PropTypes.bool.isRequired,
|
||||
includeTrending: PropTypes.bool.isRequired,
|
||||
includePopular: PropTypes.bool.isRequired,
|
||||
isSyncingLists: PropTypes.bool.isRequired,
|
||||
isSmallScreen: PropTypes.bool.isRequired,
|
||||
onSortSelect: PropTypes.func.isRequired,
|
||||
|
@ -451,7 +464,8 @@ DiscoverMovie.propTypes = {
|
|||
onScroll: PropTypes.func.isRequired,
|
||||
onAddMoviesPress: PropTypes.func.isRequired,
|
||||
onExcludeMoviesPress: PropTypes.func.isRequired,
|
||||
onImportListSyncPress: PropTypes.func.isRequired
|
||||
onImportListSyncPress: PropTypes.func.isRequired,
|
||||
dispatchFetchListMovies: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default DiscoverMovie;
|
||||
|
|
|
@ -17,15 +17,18 @@ import DiscoverMovie from './DiscoverMovie';
|
|||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.discoverMovie,
|
||||
createDiscoverMovieClientSideCollectionItemsSelector('discoverMovie'),
|
||||
createCommandExecutingSelector(commandNames.IMPORT_LIST_SYNC),
|
||||
createDimensionsSelector(),
|
||||
(
|
||||
discoverMovie,
|
||||
movies,
|
||||
isSyncingLists,
|
||||
dimensionsState
|
||||
) => {
|
||||
return {
|
||||
...discoverMovie.options,
|
||||
...movies,
|
||||
isSyncingLists,
|
||||
isSmallScreen: dimensionsState.isSmallScreen
|
||||
|
|
|
@ -49,7 +49,9 @@ class DiscoverMovieOverviewOptionsModalContent extends Component {
|
|||
showRatings: props.showRatings,
|
||||
showYear: props.showYear,
|
||||
showGenres: props.showGenres,
|
||||
includeRecommendations: props.includeRecommendations
|
||||
includeRecommendations: props.includeRecommendations,
|
||||
includeTrending: props.includeTrending,
|
||||
includePopular: props.includePopular
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -61,7 +63,9 @@ class DiscoverMovieOverviewOptionsModalContent extends Component {
|
|||
showRatings,
|
||||
showCertification,
|
||||
showGenres,
|
||||
includeRecommendations
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.props;
|
||||
|
||||
const state = {};
|
||||
|
@ -94,6 +98,14 @@ class DiscoverMovieOverviewOptionsModalContent extends Component {
|
|||
state.includeRecommendations = includeRecommendations;
|
||||
}
|
||||
|
||||
if (includeTrending !== prevProps.includeTrending) {
|
||||
state.includeTrending = includeTrending;
|
||||
}
|
||||
|
||||
if (includePopular !== prevProps.includePopular) {
|
||||
state.includePopular = includePopular;
|
||||
}
|
||||
|
||||
if (!_.isEmpty(state)) {
|
||||
this.setState(state);
|
||||
}
|
||||
|
@ -135,19 +147,22 @@ class DiscoverMovieOverviewOptionsModalContent extends Component {
|
|||
showRatings,
|
||||
showYear,
|
||||
showGenres,
|
||||
includeRecommendations
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
Overview Options
|
||||
{translate('OverviewOptions')}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeRadarrRecommendations')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeRecommendations"
|
||||
|
@ -157,6 +172,30 @@ class DiscoverMovieOverviewOptionsModalContent extends Component {
|
|||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeTrending')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeTrending"
|
||||
value={includeTrending}
|
||||
helpText={translate('IncludeTrendingMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludePopular')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includePopular"
|
||||
value={includePopular}
|
||||
helpText={translate('IncludePopularMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('PosterSize')}</FormLabel>
|
||||
|
||||
|
@ -246,6 +285,8 @@ DiscoverMovieOverviewOptionsModalContent.propTypes = {
|
|||
showCertification: PropTypes.bool.isRequired,
|
||||
showGenres: PropTypes.bool.isRequired,
|
||||
includeRecommendations: PropTypes.bool.isRequired,
|
||||
includeTrending: PropTypes.bool.isRequired,
|
||||
includePopular: PropTypes.bool.isRequired,
|
||||
onChangeOverviewOption: PropTypes.func.isRequired,
|
||||
onChangeOption: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
|
|
|
@ -45,7 +45,9 @@ class DiscoverMoviePosterOptionsModalContent extends Component {
|
|||
this.state = {
|
||||
size: props.size,
|
||||
showTitle: props.showTitle,
|
||||
includeRecommendations: props.includeRecommendations
|
||||
includeRecommendations: props.includeRecommendations,
|
||||
includeTrending: props.includeTrending,
|
||||
includePopular: props.includePopular
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -53,7 +55,9 @@ class DiscoverMoviePosterOptionsModalContent extends Component {
|
|||
const {
|
||||
size,
|
||||
showTitle,
|
||||
includeRecommendations
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.props;
|
||||
|
||||
const state = {};
|
||||
|
@ -70,6 +74,14 @@ class DiscoverMoviePosterOptionsModalContent extends Component {
|
|||
state.includeRecommendations = includeRecommendations;
|
||||
}
|
||||
|
||||
if (includeTrending !== prevProps.includeTrending) {
|
||||
state.includeTrending = includeTrending;
|
||||
}
|
||||
|
||||
if (includePopular !== prevProps.includePopular) {
|
||||
state.includePopular = includePopular;
|
||||
}
|
||||
|
||||
if (!_.isEmpty(state)) {
|
||||
this.setState(state);
|
||||
}
|
||||
|
@ -107,13 +119,15 @@ class DiscoverMoviePosterOptionsModalContent extends Component {
|
|||
const {
|
||||
size,
|
||||
showTitle,
|
||||
includeRecommendations
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
<ModalHeader>
|
||||
Poster Options
|
||||
{translate('PosterOptions')}
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
|
@ -130,6 +144,30 @@ class DiscoverMoviePosterOptionsModalContent extends Component {
|
|||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeTrending')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeTrending"
|
||||
value={includeTrending}
|
||||
helpText={translate('IncludeTrendingMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludePopular')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includePopular"
|
||||
value={includePopular}
|
||||
helpText={translate('IncludePopularMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('PosterSize')}</FormLabel>
|
||||
|
||||
|
@ -172,6 +210,8 @@ DiscoverMoviePosterOptionsModalContent.propTypes = {
|
|||
size: PropTypes.string.isRequired,
|
||||
showTitle: PropTypes.bool.isRequired,
|
||||
includeRecommendations: PropTypes.bool.isRequired,
|
||||
includeTrending: PropTypes.bool.isRequired,
|
||||
includePopular: PropTypes.bool.isRequired,
|
||||
onChangePosterOption: PropTypes.func.isRequired,
|
||||
onChangeOption: PropTypes.func.isRequired,
|
||||
onModalClose: PropTypes.func.isRequired
|
||||
|
|
|
@ -15,17 +15,29 @@ class DiscoverMovieTableOptions extends Component {
|
|||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
includeRecommendations: props.includeRecommendations
|
||||
includeRecommendations: props.includeRecommendations,
|
||||
includeTrending: props.includeTrending,
|
||||
includePopular: props.includePopular
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { includeRecommendations } = this.props;
|
||||
const {
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.props;
|
||||
|
||||
if (includeRecommendations !== prevProps.includeRecommendations) {
|
||||
this.setState({
|
||||
includeRecommendations
|
||||
});
|
||||
this.setState({ includeRecommendations });
|
||||
}
|
||||
|
||||
if (includeTrending !== prevProps.includeTrending) {
|
||||
this.setState({ includeTrending });
|
||||
}
|
||||
|
||||
if (includePopular !== prevProps.includePopular) {
|
||||
this.setState({ includePopular });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,27 +59,57 @@ class DiscoverMovieTableOptions extends Component {
|
|||
|
||||
render() {
|
||||
const {
|
||||
includeRecommendations
|
||||
includeRecommendations,
|
||||
includeTrending,
|
||||
includePopular
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeRadarrRecommendations')}</FormLabel>
|
||||
<>
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeRadarrRecommendations')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeRecommendations"
|
||||
value={includeRecommendations}
|
||||
helpText={translate('IncludeRecommendationsHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeRecommendations"
|
||||
value={includeRecommendations}
|
||||
helpText={translate('IncludeRecommendationsHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludeTrending')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includeTrending"
|
||||
value={includeTrending}
|
||||
helpText={translate('IncludeTrendingMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup>
|
||||
<FormLabel>{translate('IncludePopular')}</FormLabel>
|
||||
|
||||
<FormInputGroup
|
||||
type={inputTypes.CHECK}
|
||||
name="includePopular"
|
||||
value={includePopular}
|
||||
helpText={translate('IncludePopularMoviesHelpText')}
|
||||
onChange={this.onChangeOption}
|
||||
/>
|
||||
</FormGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
DiscoverMovieTableOptions.propTypes = {
|
||||
includeRecommendations: PropTypes.bool.isRequired,
|
||||
includeTrending: PropTypes.bool.isRequired,
|
||||
includePopular: PropTypes.bool.isRequired,
|
||||
onChangeOption: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ export const defaultState = {
|
|||
view: 'overview',
|
||||
|
||||
options: {
|
||||
includeRecommendations: true
|
||||
includeRecommendations: true,
|
||||
includeTrending: true,
|
||||
includePopular: true
|
||||
},
|
||||
|
||||
defaults: {
|
||||
|
@ -583,10 +585,14 @@ export const actionHandlers = handleThunks({
|
|||
...otherPayload
|
||||
} = payload;
|
||||
|
||||
const includeRecommendations = getState().discoverMovie.options.includeRecommendations;
|
||||
const {
|
||||
includeRecommendations = false,
|
||||
includeTrending = false,
|
||||
includePopular = false
|
||||
} = getState().discoverMovie.options;
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: `/importlist/movie?includeRecommendations=${includeRecommendations}`,
|
||||
url: `/importlist/movie?includeRecommendations=${includeRecommendations}&includeTrending=${includeTrending}&includePopular=${includePopular}`,
|
||||
data: otherPayload,
|
||||
traditional: true
|
||||
}).request;
|
||||
|
|
|
@ -731,8 +731,12 @@
|
|||
"IncludeCustomFormatWhenRenaming": "Include Custom Format when Renaming",
|
||||
"IncludeCustomFormatWhenRenamingHelpText": "Include in {Custom Formats} renaming format",
|
||||
"IncludeHealthWarnings": "Include Health Warnings",
|
||||
"IncludePopular": "Include Popular",
|
||||
"IncludePopularMoviesHelpText": "Include popular movies on TMDb",
|
||||
"IncludeRadarrRecommendations": "Include {appName} Recommendations",
|
||||
"IncludeRecommendationsHelpText": "Include {appName} recommended movies in discovery view",
|
||||
"IncludeTrending": "Include Trending",
|
||||
"IncludeTrendingMoviesHelpText": "Include trending movies on TMDb",
|
||||
"IncludeUnmonitored": "Include Unmonitored",
|
||||
"Indexer": "Indexer",
|
||||
"IndexerDownloadClientHealthCheckMessage": "Indexers with invalid download clients: {0}.",
|
||||
|
|
|
@ -64,28 +64,31 @@ namespace Radarr.Api.V3.ImportLists
|
|||
|
||||
if (includeRecommendations)
|
||||
{
|
||||
var mapped = new List<Movie>();
|
||||
var recommendedResults = _movieService.GetRecommendedTmdbIds();
|
||||
|
||||
var results = _movieService.GetRecommendedTmdbIds();
|
||||
|
||||
if (results.Count > 0)
|
||||
if (recommendedResults.Count > 0)
|
||||
{
|
||||
mapped = _movieInfo.GetBulkMovieInfo(results).Select(m => new Movie { MovieMetadata = m }).ToList();
|
||||
}
|
||||
var mapped = _movieInfo.GetBulkMovieInfo(recommendedResults).Select(m => new Movie { MovieMetadata = m }).ToList();
|
||||
|
||||
realResults.AddRange(MapToResource(mapped.Where(x => x != null), movieLanguage));
|
||||
realResults.ForEach(x => x.IsRecommendation = true);
|
||||
realResults.AddRange(MapToResource(mapped.Where(x => x != null), movieLanguage, isRecommendation: true));
|
||||
}
|
||||
}
|
||||
|
||||
// Add TMDB Trending
|
||||
var trendingResults = _movieInfo.GetTrendingMovies();
|
||||
if (includeTrending)
|
||||
{
|
||||
// Add TMDB Trending
|
||||
var trendingResults = _movieInfo.GetTrendingMovies();
|
||||
|
||||
realResults.AddRange(MapToResource(trendingResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, true));
|
||||
realResults.AddRange(MapToResource(trendingResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, isTrending: true));
|
||||
}
|
||||
|
||||
// Add TMDB Popular
|
||||
var popularResults = _movieInfo.GetPopularMovies();
|
||||
if (includePopular)
|
||||
{
|
||||
// Add TMDB Popular
|
||||
var popularResults = _movieInfo.GetPopularMovies();
|
||||
|
||||
realResults.AddRange(MapToResource(popularResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, false, true));
|
||||
realResults.AddRange(MapToResource(popularResults.Select(m => new Movie { MovieMetadata = m }).Where(x => x != null), movieLanguage, isPopular: true));
|
||||
}
|
||||
|
||||
// Add List Movies
|
||||
var listMovies = MapToResource(_listMovieService.GetAllForLists(_importListFactory.Enabled().Select(x => x.Definition.Id).ToList()), movieLanguage).ToList();
|
||||
|
@ -120,7 +123,7 @@ namespace Radarr.Api.V3.ImportLists
|
|||
return _addMovieService.AddMovies(newMovies, true).ToResource(0);
|
||||
}
|
||||
|
||||
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language, bool isTrending = false, bool isPopular = false)
|
||||
private IEnumerable<ImportListMoviesResource> MapToResource(IEnumerable<Movie> movies, Language language, bool isRecommendation = false, bool isTrending = false, bool isPopular = false)
|
||||
{
|
||||
// Avoid calling for naming spec on every movie in filenamebuilder
|
||||
var namingConfig = _namingService.GetConfig();
|
||||
|
@ -140,6 +143,7 @@ namespace Radarr.Api.V3.ImportLists
|
|||
resource.Title = translation?.Title ?? resource.Title;
|
||||
resource.Overview = translation?.Overview ?? resource.Overview;
|
||||
resource.Folder = _fileNameBuilder.GetMovieFolder(currentMovie, namingConfig);
|
||||
resource.IsRecommendation = isRecommendation;
|
||||
resource.IsTrending = isTrending;
|
||||
resource.IsPopular = isPopular;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue