New: Monitor Collections from Movie Details Page

This commit is contained in:
Qstick 2020-07-09 21:43:21 -04:00
parent 9bf50d4493
commit ac79c51196
5 changed files with 181 additions and 3 deletions

View File

@ -36,6 +36,7 @@ import MovieHistoryTable from 'Movie/History/MovieHistoryTable';
import MovieTitlesTable from './Titles/MovieTitlesTable';
import MovieCastPostersConnector from './Credits/Cast/MovieCastPostersConnector';
import MovieCrewPostersConnector from './Credits/Crew/MovieCrewPostersConnector';
import MovieCollectionConnector from './../MovieCollectionConnector';
import MovieDetailsLinks from './MovieDetailsLinks';
import InteractiveSearchTable from 'InteractiveSearch/InteractiveSearchTable';
import InteractiveSearchFilterMenuConnector from 'InteractiveSearch/InteractiveSearchFilterMenuConnector';
@ -538,9 +539,11 @@ class MovieDetails extends Component {
title="Collection"
size={sizes.LARGE}
>
<span className={styles.collection}>
{collection.name}
</span>
<MovieCollectionConnector
tmdbId={collection.tmdbId}
name={collection.name}
movieId={id}
/>
</InfoLabel>
}

View File

@ -0,0 +1,9 @@
.monitorToggleButton {
composes: toggleButton from '~Components/MonitorToggleButton.css';
width: 15px;
&:hover {
color: $iconButtonHoverLightColor;
}
}

View File

@ -0,0 +1,38 @@
import PropTypes from 'prop-types';
import React from 'react';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import styles from './MovieCollection.css';
function MovieCollection(props) {
const {
name,
collectionList,
isSaving,
onMonitorTogglePress
} = props;
const monitored = collectionList !== undefined && collectionList.enabled && collectionList.enableAuto;
return (
<div>
<MonitorToggleButton
className={styles.monitorToggleButton}
monitored={monitored}
isSaving={isSaving}
size={15}
onPress={onMonitorTogglePress}
/>
{name}
</div>
);
}
MovieCollection.propTypes = {
tmdbId: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
collectionList: PropTypes.object,
isSaving: PropTypes.bool.isRequired,
onMonitorTogglePress: PropTypes.func.isRequired
};
export default MovieCollection;

View File

@ -0,0 +1,95 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { createSelector } from 'reselect';
import { connect } from 'react-redux';
import createMovieSelector from 'Store/Selectors/createMovieSelector';
import createMovieCollectionListSelector from 'Store/Selectors/createMovieCollectionListSelector';
import { selectNetImportSchema, setNetImportValue, setNetImportFieldValue, saveNetImport } from 'Store/Actions/settingsActions';
import MovieCollection from './MovieCollection';
function createMapStateToProps() {
return createSelector(
createMovieSelector(),
createMovieCollectionListSelector(),
(state) => state.settings.netImports,
(movie, collectionList, netImports) => {
const {
monitored,
qualityProfileId,
path,
minimumAvailability
} = movie;
return {
collectionList,
monitored,
qualityProfileId,
path,
minimumAvailability,
isSaving: netImports.isSaving
};
}
);
}
const mapDispatchToProps = {
selectNetImportSchema,
setNetImportFieldValue,
setNetImportValue,
saveNetImport
};
class MovieCollectionConnector extends Component {
//
// Listeners
onMonitorTogglePress = (monitored) => {
if (this.props.collectionList) {
this.props.setNetImportValue({ name: 'enabled', value: monitored });
this.props.setNetImportValue({ name: 'enableAuto', value: monitored });
this.props.saveNetImport({ id: this.props.collectionList.id });
} else {
this.props.selectNetImportSchema({ implementation: 'TMDbCollectionImport', presetName: undefined });
this.props.setNetImportFieldValue({ name: 'collectionId', value: this.props.tmdbId.toString() });
this.props.setNetImportValue({ name: 'enabled', value: true });
this.props.setNetImportValue({ name: 'enableAuto', value: true });
this.props.setNetImportValue({ name: 'name', value: `${this.props.name} - ${this.props.tmdbId}` });
this.props.setNetImportValue({ name: 'rootFolderPath', value: this.props.path });
this.props.setNetImportValue({ name: 'qualityProfileId', value: this.props.qualityProfileId });
this.props.setNetImportValue({ name: 'monitored', value: this.props.monitored });
this.props.setNetImportValue({ name: 'minimumAvailability', value: this.props.minimumAvailability });
this.props.saveNetImport();
}
}
//
// Render
render() {
return (
<MovieCollection
{...this.props}
onMonitorTogglePress={this.onMonitorTogglePress}
/>
);
}
}
MovieCollectionConnector.propTypes = {
tmdbId: PropTypes.number.isRequired,
movieId: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
collectionList: PropTypes.object,
monitored: PropTypes.bool.isRequired,
qualityProfileId: PropTypes.number.isRequired,
path: PropTypes.string.isRequired,
minimumAvailability: PropTypes.string.isRequired,
isSaving: PropTypes.bool.isRequired,
selectNetImportSchema: PropTypes.func.isRequired,
setNetImportFieldValue: PropTypes.func.isRequired,
setNetImportValue: PropTypes.func.isRequired,
saveNetImport: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(MovieCollectionConnector);

View File

@ -0,0 +1,33 @@
import _ from 'lodash';
import { createSelector } from 'reselect';
function createMovieCollectionListSelector() {
return createSelector(
(state, { tmdbId }) => tmdbId,
(state) => state.settings.netImports.items,
(tmdbId, netImports) => {
const netImportIds = _.reduce(netImports, (acc, list) => {
if (list.implementation === 'TMDbCollectionImport') {
const collectionIdField = list.fields.find((field) => {
return field.name === 'collectionId';
});
if (collectionIdField && parseInt(collectionIdField.value) === tmdbId) {
acc.push(list);
return acc;
}
}
return acc;
}, []);
if (netImportIds.length === 0) {
return undefined;
}
return netImportIds[0];
}
);
}
export default createMovieCollectionListSelector;