Update movie list for next/previous on details to use the filtered index results instead of all movies

Fixes: #4977
This commit is contained in:
nitsua 2022-03-27 23:52:59 -04:00
parent 4f512c5cdf
commit 8f41adfe29
8 changed files with 103 additions and 25 deletions

View File

@ -20,7 +20,7 @@ import RottenTomatoRating from 'Components/RottenTomatoRating';
import TmdbRating from 'Components/TmdbRating'; import TmdbRating from 'Components/TmdbRating';
import Popover from 'Components/Tooltip/Popover'; import Popover from 'Components/Tooltip/Popover';
import Tooltip from 'Components/Tooltip/Tooltip'; import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; import { align, icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal';
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector'; import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable'; import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
@ -36,6 +36,7 @@ import fonts from 'Styles/Variables/fonts';
import * as keyCodes from 'Utilities/Constants/keyCodes'; import * as keyCodes from 'Utilities/Constants/keyCodes';
import formatRuntime from 'Utilities/Date/formatRuntime'; import formatRuntime from 'Utilities/Date/formatRuntime';
import formatBytes from 'Utilities/Number/formatBytes'; import formatBytes from 'Utilities/Number/formatBytes';
import titleCase from 'Utilities/String/titleCase';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll'; import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected'; import toggleSelected from 'Utilities/Table/toggleSelected';
@ -290,7 +291,9 @@ class MovieDetails extends Component {
onRefreshPress, onRefreshPress,
onSearchPress, onSearchPress,
queueItems, queueItems,
movieRuntimeFormat movieRuntimeFormat,
indexFilter,
nextPrev
} = this.props; } = this.props;
const { const {
@ -355,6 +358,16 @@ class MovieDetails extends Component {
onPress={this.onDeleteMoviePress} onPress={this.onDeleteMoviePress}
/> />
</PageToolbarSection> </PageToolbarSection>
<PageToolbarSection
alignContent={align.RIGHT}
collapseButtons={false}
>
<PageToolbarButton
label={titleCase(indexFilter)}
iconName={icons.FILTER}
/>
</PageToolbarSection>
</PageToolbar> </PageToolbar>
<PageContentBody innerClassName={styles.innerContentBody}> <PageContentBody innerClassName={styles.innerContentBody}>
@ -395,23 +408,26 @@ class MovieDetails extends Component {
</div> </div>
</div> </div>
<div className={styles.movieNavigationButtons}> {
<IconButton nextPrev &&
className={styles.movieNavigationButton} <div className={styles.movieNavigationButtons}>
name={icons.ARROW_LEFT} <IconButton
size={30} className={styles.movieNavigationButton}
title={translate('GoToInterp', [previousMovie.title])} name={icons.ARROW_LEFT}
to={`/movie/${previousMovie.titleSlug}`} size={30}
/> title={translate('GoToInterp', [previousMovie.title])}
to={`/movie/${previousMovie.titleSlug}`}
/>
<IconButton <IconButton
className={styles.movieNavigationButton} className={styles.movieNavigationButton}
name={icons.ARROW_RIGHT} name={icons.ARROW_RIGHT}
size={30} size={30}
title={translate('GoToInterp', [nextMovie.title])} title={translate('GoToInterp', [nextMovie.title])}
to={`/movie/${nextMovie.titleSlug}`} to={`/movie/${nextMovie.titleSlug}`}
/> />
</div> </div>
}
</div> </div>
</Measure> </Measure>
@ -830,7 +846,9 @@ MovieDetails.propTypes = {
onSearchPress: PropTypes.func.isRequired, onSearchPress: PropTypes.func.isRequired,
onGoToMovie: PropTypes.func.isRequired, onGoToMovie: PropTypes.func.isRequired,
queueItems: PropTypes.arrayOf(PropTypes.object), queueItems: PropTypes.arrayOf(PropTypes.object),
movieRuntimeFormat: PropTypes.string.isRequired movieRuntimeFormat: PropTypes.string.isRequired,
indexFilter: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
nextPrev: PropTypes.bool.isRequired
}; };
MovieDetails.defaultProps = { MovieDetails.defaultProps = {

View File

@ -18,6 +18,7 @@ import { fetchImportListSchema } from 'Store/Actions/settingsActions';
import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector'; import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector';
import createCommandsSelector from 'Store/Selectors/createCommandsSelector'; import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
import createMovieClientSideCollectionItemsSelector from 'Store/Selectors/createMovieClientSideCollectionItemsSelector';
import { findCommand, isCommandExecuting } from 'Utilities/Command'; import { findCommand, isCommandExecuting } from 'Utilities/Command';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator'; import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import MovieDetails from './MovieDetails'; import MovieDetails from './MovieDetails';
@ -86,16 +87,37 @@ function createMapStateToProps() {
selectMovieFiles, selectMovieFiles,
selectMovieCredits, selectMovieCredits,
selectExtraFiles, selectExtraFiles,
createMovieClientSideCollectionItemsSelector('movieIndex'),
createAllMoviesSelector(), createAllMoviesSelector(),
createCommandsSelector(), createCommandsSelector(),
createDimensionsSelector(), createDimensionsSelector(),
(state) => state.queue.details.items, (state) => state.queue.details.items,
(state) => state.app.isSidebarVisible, (state) => state.app.isSidebarVisible,
(state) => state.settings.ui.item.movieRuntimeFormat, (state) => state.settings.ui.item.movieRuntimeFormat,
(titleSlug, movieFiles, movieCredits, extraFiles, allMovies, commands, dimensions, queueItems, isSidebarVisible, movieRuntimeFormat) => { (state) => state.settings.ui.item.movieDetailsNextPrevBehavior,
const sortedMovies = _.orderBy(allMovies, 'sortTitle'); (state) => state.movieIndex.selectedFilterKey,
const movieIndex = _.findIndex(sortedMovies, { titleSlug }); (state) => state.customFilters.items.filter((s) => s.type === 'movieIndex'),
(titleSlug, movieFiles, movieCredits, extraFiles, collectionMovies, allMovies, commands, dimensions, queueItems, isSidebarVisible, movieRuntimeFormat, movieDetailsNextPrevBehavior, indexFilter, customFilters) => {
let sortedMovies = [];
if (movieDetailsNextPrevBehavior === 'filter') {
collectionMovies.items.forEach((c) => sortedMovies.push(allMovies.find((a) => a.id === c.id)));
} else {
sortedMovies = _.orderBy(allMovies, 'sortTitle');
}
let movieIndex = _.findIndex(sortedMovies, { titleSlug });
if (customFilters.length && Number.isInteger(indexFilter)) {
indexFilter = customFilters.find((filter) => (filter.id === indexFilter)).label;
}
if (movieIndex === -1) {
sortedMovies.push(allMovies.find((a) => a.titleSlug === titleSlug));
movieIndex = sortedMovies.length - 1;
}
const movie = sortedMovies[movieIndex]; const movie = sortedMovies[movieIndex];
const nextPrev = sortedMovies.length > 1;
if (!movie) { if (!movie) {
return {}; return {};
@ -166,7 +188,9 @@ function createMapStateToProps() {
isSmallScreen: dimensions.isSmallScreen, isSmallScreen: dimensions.isSmallScreen,
isSidebarVisible, isSidebarVisible,
queueItems, queueItems,
movieRuntimeFormat movieRuntimeFormat,
indexFilter,
nextPrev
}; };
} }
); );

View File

@ -12,6 +12,11 @@ import { inputTypes } from 'Helpers/Props';
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
export const movieDetailsNextPrevBehaviorOption = [
{ key: 'all', value: translate('All') },
{ key: 'filter', value: translate('Filter') }
];
export const firstDayOfWeekOptions = [ export const firstDayOfWeekOptions = [
{ key: 0, value: translate('Sunday') }, { key: 0, value: translate('Sunday') },
{ key: 1, value: translate('Monday') } { key: 1, value: translate('Monday') }
@ -132,6 +137,18 @@ class UISettings extends Component {
{...settings.movieRuntimeFormat} {...settings.movieRuntimeFormat}
/> />
</FormGroup> </FormGroup>
<FormGroup>
<FormLabel>{translate('NextPrevBehavior')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="movieDetailsNextPrevBehavior"
values={movieDetailsNextPrevBehaviorOption}
helpText={translate('DetailsNextPrevBehavior')}
onChange={onInputChange}
{...settings.movieDetailsNextPrevBehavior}
/>
</FormGroup>
</FieldSet> </FieldSet>
<FieldSet legend={translate('Dates')}> <FieldSet legend={translate('Dates')}>

View File

@ -81,6 +81,12 @@ namespace NzbDrone.Core.Configuration
return _repository.Get(key.ToLower()) != null; return _repository.Get(key.ToLower()) != null;
} }
public MovieDetailsNextPrevBehaviorOption MovieDetailsNextPrevBehavior
{
get { return GetValueEnum("MovieDetailsNextPrevBehavior", MovieDetailsNextPrevBehaviorOption.All); }
set { SetValue("MovieDetailsNextPrevBehavior", value); }
}
public bool AutoUnmonitorPreviouslyDownloadedMovies public bool AutoUnmonitorPreviouslyDownloadedMovies
{ {
get { return GetValueBoolean("AutoUnmonitorPreviouslyDownloadedMovies"); } get { return GetValueBoolean("AutoUnmonitorPreviouslyDownloadedMovies"); }

View File

@ -70,6 +70,7 @@ namespace NzbDrone.Core.Configuration
int FirstDayOfWeek { get; set; } int FirstDayOfWeek { get; set; }
string CalendarWeekColumnHeader { get; set; } string CalendarWeekColumnHeader { get; set; }
MovieRuntimeFormatType MovieRuntimeFormat { get; set; } MovieRuntimeFormatType MovieRuntimeFormat { get; set; }
MovieDetailsNextPrevBehaviorOption MovieDetailsNextPrevBehavior { get; set; }
string ShortDateFormat { get; set; } string ShortDateFormat { get; set; }
string LongDateFormat { get; set; } string LongDateFormat { get; set; }

View File

@ -0,0 +1,8 @@
namespace NzbDrone.Core.Configuration
{
public enum MovieDetailsNextPrevBehaviorOption
{
All,
Filter
}
}

View File

@ -227,6 +227,7 @@
"DetailedProgressBar": "Detailed Progress Bar", "DetailedProgressBar": "Detailed Progress Bar",
"DetailedProgressBarHelpText": "Show text on progress bar", "DetailedProgressBarHelpText": "Show text on progress bar",
"Details": "Details", "Details": "Details",
"DetailsNextPrevBehavior": "What should be used to control Next/Prev buttons on the movie details page",
"DigitalRelease": "Digital Release", "DigitalRelease": "Digital Release",
"Disabled": "Disabled", "Disabled": "Disabled",
"Discord": "Discord", "Discord": "Discord",
@ -593,6 +594,7 @@
"Never": "Never", "Never": "Never",
"New": "New", "New": "New",
"NextExecution": "Next Execution", "NextExecution": "Next Execution",
"NextPrevBehavior": "Next/Prev Behavior",
"No": "No", "No": "No",
"NoAltTitle": "No alternative titles.", "NoAltTitle": "No alternative titles.",
"NoBackupsAreAvailable": "No backups are available", "NoBackupsAreAvailable": "No backups are available",
@ -645,8 +647,6 @@
"OpenThisModal": "Open This Modal", "OpenThisModal": "Open This Modal",
"Options": "Options", "Options": "Options",
"Organize": "Organize", "Organize": "Organize",
"OriginalTitle": "Original Title",
"OriginalLanguage": "Original Language",
"OrganizeAndRename": "Organize & Rename", "OrganizeAndRename": "Organize & Rename",
"OrganizeConfirm": "Are you sure you want to organize all files in the {0} selected movie(s)?", "OrganizeConfirm": "Are you sure you want to organize all files in the {0} selected movie(s)?",
"OrganizeModalAllPathsRelative": "All paths are relative to:", "OrganizeModalAllPathsRelative": "All paths are relative to:",
@ -655,6 +655,8 @@
"OrganizeModalSuccess": "Success! My work is done, no files to rename.", "OrganizeModalSuccess": "Success! My work is done, no files to rename.",
"OrganizeSelectedMovies": "Organize Selected Movies", "OrganizeSelectedMovies": "Organize Selected Movies",
"Original": "Original", "Original": "Original",
"OriginalLanguage": "Original Language",
"OriginalTitle": "Original Title",
"OutputPath": "Output Path", "OutputPath": "Output Path",
"Overview": "Overview", "Overview": "Overview",
"OverviewOptions": "Overview Options", "OverviewOptions": "Overview Options",

View File

@ -11,6 +11,7 @@ namespace Radarr.Api.V3.Config
// Movies // Movies
public MovieRuntimeFormatType MovieRuntimeFormat { get; set; } public MovieRuntimeFormatType MovieRuntimeFormat { get; set; }
public MovieDetailsNextPrevBehaviorOption MovieDetailsNextPrevBehavior { get; set; }
//Dates //Dates
public string ShortDateFormat { get; set; } public string ShortDateFormat { get; set; }
@ -33,6 +34,7 @@ namespace Radarr.Api.V3.Config
CalendarWeekColumnHeader = model.CalendarWeekColumnHeader, CalendarWeekColumnHeader = model.CalendarWeekColumnHeader,
MovieRuntimeFormat = model.MovieRuntimeFormat, MovieRuntimeFormat = model.MovieRuntimeFormat,
MovieDetailsNextPrevBehavior = model.MovieDetailsNextPrevBehavior,
ShortDateFormat = model.ShortDateFormat, ShortDateFormat = model.ShortDateFormat,
LongDateFormat = model.LongDateFormat, LongDateFormat = model.LongDateFormat,