From a8695959f1fb1fdce1aaacb3db669d09ffa0c95e Mon Sep 17 00:00:00 2001 From: Qstick Date: Thu, 2 Jun 2022 19:32:08 -0500 Subject: [PATCH] Cleanup Collections UI Options --- .../Overview/CollectionMovieLabel.css | 50 +++++++++++ .../Overview/CollectionMovieLabel.js | 84 +++++++++++++++++++ .../Overview/CollectionMovieLabelConnector.js | 59 +++++++++++++ .../Overview/CollectionOverview.css | 5 ++ .../Collection/Overview/CollectionOverview.js | 71 ++++++++++------ .../Overview/CollectionOverviews.js | 2 +- .../CollectionOverviewOptionsModalContent.js | 28 ++++++- .../Store/Actions/movieCollectionActions.js | 3 +- src/NzbDrone.Core/Localization/Core/en.json | 5 ++ 9 files changed, 276 insertions(+), 31 deletions(-) create mode 100644 frontend/src/Collection/Overview/CollectionMovieLabel.css create mode 100644 frontend/src/Collection/Overview/CollectionMovieLabel.js create mode 100644 frontend/src/Collection/Overview/CollectionMovieLabelConnector.js diff --git a/frontend/src/Collection/Overview/CollectionMovieLabel.css b/frontend/src/Collection/Overview/CollectionMovieLabel.css new file mode 100644 index 000000000..ec553ec3e --- /dev/null +++ b/frontend/src/Collection/Overview/CollectionMovieLabel.css @@ -0,0 +1,50 @@ +.movie { + display: flex; + align-items: stretch; + overflow: hidden; + margin: 2px 4px; + border: 1px solid $borderColor; + border-radius: 4px; + background-color: #eee; + cursor: default; +} + +.movieTitle { + padding: 0 4px; +} + +.movieStatus { + padding: 0 4px; + border-left: 4px; + border-left-style: solid; + background-color: $white; + color: $defaultColor; +} + +.primary { + border-color: $primaryColor; +} + +.danger { + border-color: $dangerColor; +} + +.success { + border-color: $successColor; +} + +.purple { + border-color: $purple; +} + +.warning { + border-color: $warningColor; +} + +.info { + border-color: $infoColor; +} + +.queue { + border-color: $queueColor; +} diff --git a/frontend/src/Collection/Overview/CollectionMovieLabel.js b/frontend/src/Collection/Overview/CollectionMovieLabel.js new file mode 100644 index 000000000..f528b7860 --- /dev/null +++ b/frontend/src/Collection/Overview/CollectionMovieLabel.js @@ -0,0 +1,84 @@ +import classNames from 'classnames'; +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import MonitorToggleButton from 'Components/MonitorToggleButton'; +import getStatusStyle from 'Utilities/Movie/getStatusStyle'; +import translate from 'Utilities/String/translate'; +import styles from './CollectionMovieLabel.css'; + +class CollectionMovieLabel extends Component { + // + // Render + + render() { + const { + id, + title, + status, + monitored, + isAvailable, + hasFile, + onMonitorTogglePress, + isSaving + } = this.props; + + return ( +
+
+ { + id && + + } + + + { + title + } + +
+ + { + id && +
+ { + hasFile ? translate('Downloaded') : translate('Missing') + } +
+ } +
+ ); + } +} + +CollectionMovieLabel.propTypes = { + id: PropTypes.number, + title: PropTypes.string.isRequired, + status: PropTypes.string, + isAvailable: PropTypes.bool, + monitored: PropTypes.bool, + hasFile: PropTypes.bool, + isSaving: PropTypes.bool.isRequired, + movieFile: PropTypes.object, + movieFileId: PropTypes.number, + onMonitorTogglePress: PropTypes.func.isRequired +}; + +CollectionMovieLabel.defaultProps = { + isSaving: false, + statistics: { + episodeFileCount: 0, + totalEpisodeCount: 0, + percentOfEpisodes: 0 + } +}; + +export default CollectionMovieLabel; diff --git a/frontend/src/Collection/Overview/CollectionMovieLabelConnector.js b/frontend/src/Collection/Overview/CollectionMovieLabelConnector.js new file mode 100644 index 000000000..3b982db9d --- /dev/null +++ b/frontend/src/Collection/Overview/CollectionMovieLabelConnector.js @@ -0,0 +1,59 @@ +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import { createSelector } from 'reselect'; +import { toggleMovieMonitored } from 'Store/Actions/movieActions'; +import createCollectionExistingMovieSelector from 'Store/Selectors/createCollectionExistingMovieSelector'; +import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; +import CollectionMovieLabel from './CollectionMovieLabel'; + +function createMapStateToProps() { + return createSelector( + createDimensionsSelector(), + createCollectionExistingMovieSelector(), + (dimensions, existingMovie) => { + return { + isSmallScreen: dimensions.isSmallScreen, + isExistingMovie: !!existingMovie, + ...existingMovie + }; + } + ); +} + +const mapDispatchToProps = { + toggleMovieMonitored +}; + +class CollectionMovieLabelConnector extends Component { + + // + // Listeners + + onMonitorTogglePress = (monitored) => { + this.props.toggleMovieMonitored({ + movieId: this.props.id, + monitored + }); + }; + + // + // Render + + render() { + return ( + + ); + } +} + +CollectionMovieLabelConnector.propTypes = { + id: PropTypes.number, + monitored: PropTypes.bool, + toggleMovieMonitored: PropTypes.func.isRequired +}; + +export default connect(createMapStateToProps, mapDispatchToProps)(CollectionMovieLabelConnector); diff --git a/frontend/src/Collection/Overview/CollectionOverview.css b/frontend/src/Collection/Overview/CollectionOverview.css index fc7eef288..e9467fbb3 100644 --- a/frontend/src/Collection/Overview/CollectionOverview.css +++ b/frontend/src/Collection/Overview/CollectionOverview.css @@ -32,6 +32,11 @@ $hoverScale: 1.05; display: block; } +.labelsContainer { + display: flex; + flex-wrap: wrap; +} + .moviesContainer { margin-bottom: 5px; } diff --git a/frontend/src/Collection/Overview/CollectionOverview.js b/frontend/src/Collection/Overview/CollectionOverview.js index 1931140ef..f45004614 100644 --- a/frontend/src/Collection/Overview/CollectionOverview.js +++ b/frontend/src/Collection/Overview/CollectionOverview.js @@ -14,6 +14,7 @@ import dimensions from 'Styles/Variables/dimensions'; import fonts from 'Styles/Variables/fonts'; import translate from 'Utilities/String/translate'; import CollectionMovieConnector from './CollectionMovieConnector'; +import CollectionMovieLabelConnector from './CollectionMovieLabelConnector'; import styles from './CollectionOverview.css'; import 'slick-carousel/slick/slick.css'; @@ -108,6 +109,7 @@ class CollectionOverview extends Component { const { showDetails, showOverview, + showPosters, detailedProgressBar } = this.props.overviewOptions; @@ -161,21 +163,25 @@ class CollectionOverview extends Component { /> -
- + { + showPosters && +
+ + + +
+ } - -
{ @@ -261,22 +267,35 @@ class CollectionOverview extends Component { } -
- - {movies.map((movie) => ( -
- + + {movies.map((movie) => ( +
+ +
+ ))} +
+
: +
+ {movies.map((movie) => ( + -
- ))} -
-
+ ))} + + } + diff --git a/frontend/src/Collection/Overview/CollectionOverviews.js b/frontend/src/Collection/Overview/CollectionOverviews.js index 01c5d9c64..d803e339e 100644 --- a/frontend/src/Collection/Overview/CollectionOverviews.js +++ b/frontend/src/Collection/Overview/CollectionOverviews.js @@ -30,7 +30,7 @@ function calculatePosterWidth(posterSize, isSmallScreen) { function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) { const heights = [ - posterHeight, + overviewOptions.showPosters ? posterHeight : 75, isSmallScreen ? columnPaddingSmallScreen : columnPadding ]; diff --git a/frontend/src/Collection/Overview/Options/CollectionOverviewOptionsModalContent.js b/frontend/src/Collection/Overview/Options/CollectionOverviewOptionsModalContent.js index 881826e1a..deb3cd7a3 100644 --- a/frontend/src/Collection/Overview/Options/CollectionOverviewOptionsModalContent.js +++ b/frontend/src/Collection/Overview/Options/CollectionOverviewOptionsModalContent.js @@ -31,7 +31,8 @@ class CollectionOverviewOptionsModalContent extends Component { detailedProgressBar: props.detailedProgressBar, size: props.size, showDetails: props.showDetails, - showOverview: props.showOverview + showOverview: props.showOverview, + showPosters: props.showPosters }; } @@ -40,7 +41,8 @@ class CollectionOverviewOptionsModalContent extends Component { detailedProgressBar, size, showDetails, - showOverview + showOverview, + showPosters } = this.props; const state = {}; @@ -61,6 +63,10 @@ class CollectionOverviewOptionsModalContent extends Component { state.showOverview = showOverview; } + if (showPosters !== prevProps.showPosters) { + state.showPosters = showPosters; + } + if (!_.isEmpty(state)) { this.setState(state); } @@ -99,13 +105,14 @@ class CollectionOverviewOptionsModalContent extends Component { size, detailedProgressBar, showDetails, + showPosters, showOverview } = this.state; return ( - Overview Options + {translate('CollectionOptions')} @@ -141,6 +148,7 @@ class CollectionOverviewOptionsModalContent extends Component { type={inputTypes.CHECK} name="showDetails" value={showDetails} + helpText={translate('CollectionShowDetailsHelpText')} onChange={this.onChangeOverviewOption} /> @@ -152,6 +160,19 @@ class CollectionOverviewOptionsModalContent extends Component { type={inputTypes.CHECK} name="showOverview" value={showOverview} + helpText={translate('CollectionShowOverviewsHelpText')} + onChange={this.onChangeOverviewOption} + /> + + + + {translate('ShowPosters')} + + @@ -175,6 +196,7 @@ CollectionOverviewOptionsModalContent.propTypes = { size: PropTypes.string.isRequired, showDetails: PropTypes.bool.isRequired, showOverview: PropTypes.bool.isRequired, + showPosters: PropTypes.bool.isRequired, onChangeOverviewOption: PropTypes.func.isRequired, onChangeOption: PropTypes.func.isRequired, onModalClose: PropTypes.func.isRequired diff --git a/frontend/src/Store/Actions/movieCollectionActions.js b/frontend/src/Store/Actions/movieCollectionActions.js index d9c836acb..be21a6aa5 100644 --- a/frontend/src/Store/Actions/movieCollectionActions.js +++ b/frontend/src/Store/Actions/movieCollectionActions.js @@ -40,7 +40,8 @@ export const defaultState = { detailedProgressBar: false, size: 'medium', showDetails: true, - showOverview: true + showOverview: true, + showPosters: true }, defaults: { diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index eba606f46..a7aaf472a 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -138,7 +138,11 @@ "Close": "Close", "CloseCurrentModal": "Close Current Modal", "Collection": "Collection", + "CollectionOptions": "Collection Options", "Collections": "Collections", + "CollectionShowDetailsHelpText": "Show collection status and properties", + "CollectionShowOverviewsHelpText": "Show collection overviews", + "CollectionShowPostersHelpText": "Show Collection item posters", "CollectionsSelectedInterp": "{0} Collections(s) Selected", "ColonReplacement": "Colon Replacement", "ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement", @@ -932,6 +936,7 @@ "ShownClickToHide": "Shown, click to hide", "ShowOverview": "Show Overview", "ShowPath": "Show Path", + "ShowPosters": "Show Posters", "ShowQualityProfile": "Show Quality Profile", "ShowQualityProfileHelpText": "Show quality profile under poster", "ShowRatings": "Show Ratings",