1
0
mirror of https://github.com/Radarr/Radarr.git synced 2024-07-07 04:19:25 +02:00

Cleanup Collections UI Options

This commit is contained in:
Qstick 2022-06-02 19:32:08 -05:00
parent 696bb845a5
commit a8695959f1
9 changed files with 276 additions and 31 deletions

View File

@ -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;
}

View File

@ -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 (
<div className={styles.movie}>
<div className={styles.movieTitle}>
{
id &&
<MonitorToggleButton
monitored={monitored}
isSaving={isSaving}
onPress={onMonitorTogglePress}
/>
}
<span>
{
title
}
</span>
</div>
{
id &&
<div
className={classNames(
styles.movieStatus,
styles[getStatusStyle(status, monitored, hasFile, isAvailable, 'kinds')]
)}
>
{
hasFile ? translate('Downloaded') : translate('Missing')
}
</div>
}
</div>
);
}
}
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;

View File

@ -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 (
<CollectionMovieLabel
{...this.props}
onMonitorTogglePress={this.onMonitorTogglePress}
/>
);
}
}
CollectionMovieLabelConnector.propTypes = {
id: PropTypes.number,
monitored: PropTypes.bool,
toggleMovieMonitored: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(CollectionMovieLabelConnector);

View File

@ -32,6 +32,11 @@ $hoverScale: 1.05;
display: block; display: block;
} }
.labelsContainer {
display: flex;
flex-wrap: wrap;
}
.moviesContainer { .moviesContainer {
margin-bottom: 5px; margin-bottom: 5px;
} }

View File

@ -14,6 +14,7 @@ import dimensions from 'Styles/Variables/dimensions';
import fonts from 'Styles/Variables/fonts'; import fonts from 'Styles/Variables/fonts';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import CollectionMovieConnector from './CollectionMovieConnector'; import CollectionMovieConnector from './CollectionMovieConnector';
import CollectionMovieLabelConnector from './CollectionMovieLabelConnector';
import styles from './CollectionOverview.css'; import styles from './CollectionOverview.css';
import 'slick-carousel/slick/slick.css'; import 'slick-carousel/slick/slick.css';
@ -108,6 +109,7 @@ class CollectionOverview extends Component {
const { const {
showDetails, showDetails,
showOverview, showOverview,
showPosters,
detailedProgressBar detailedProgressBar
} = this.props.overviewOptions; } = this.props.overviewOptions;
@ -161,21 +163,25 @@ class CollectionOverview extends Component {
/> />
</div> </div>
<div className={styles.navigationButtons}> {
<IconButton showPosters &&
name={icons.ARROW_LEFT} <div className={styles.navigationButtons}>
title={translate('ScrollMovies')} <IconButton
onPress={this.state.slider?.slickPrev} name={icons.ARROW_LEFT}
size={20} title={translate('ScrollMovies')}
/> onPress={this.state.slider?.slickPrev}
size={20}
/>
<IconButton
name={icons.ARROW_RIGHT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickNext}
size={20}
/>
</div>
}
<IconButton
name={icons.ARROW_RIGHT}
title={translate('ScrollMovies')}
onPress={this.state.slider?.slickNext}
size={20}
/>
</div>
</div> </div>
{ {
@ -261,22 +267,35 @@ class CollectionOverview extends Component {
</div> </div>
} }
<div className={styles.sliderContainer}> {
<Slider ref={this.setSliderRef} {...sliderSettings}> showPosters ?
{movies.map((movie) => ( <div className={styles.sliderContainer}>
<div className={styles.movie} key={movie.tmdbId}> <Slider ref={this.setSliderRef} {...sliderSettings}>
<CollectionMovieConnector {movies.map((movie) => (
<div className={styles.movie} key={movie.tmdbId}>
<CollectionMovieConnector
key={movie.tmdbId}
posterWidth={posterWidth}
posterHeight={posterHeight}
detailedProgressBar={detailedProgressBar}
collectionId={id}
{...movie}
/>
</div>
))}
</Slider>
</div> :
<div className={styles.labelsContainer}>
{movies.map((movie) => (
<CollectionMovieLabelConnector
key={movie.tmdbId} key={movie.tmdbId}
posterWidth={posterWidth}
posterHeight={posterHeight}
detailedProgressBar={detailedProgressBar}
collectionId={id} collectionId={id}
{...movie} {...movie}
/> />
</div> ))}
))} </div>
</Slider> }
</div>
</div> </div>
</div> </div>

View File

@ -30,7 +30,7 @@ function calculatePosterWidth(posterSize, isSmallScreen) {
function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) { function calculateRowHeight(posterHeight, sortKey, isSmallScreen, overviewOptions) {
const heights = [ const heights = [
posterHeight, overviewOptions.showPosters ? posterHeight : 75,
isSmallScreen ? columnPaddingSmallScreen : columnPadding isSmallScreen ? columnPaddingSmallScreen : columnPadding
]; ];

View File

@ -31,7 +31,8 @@ class CollectionOverviewOptionsModalContent extends Component {
detailedProgressBar: props.detailedProgressBar, detailedProgressBar: props.detailedProgressBar,
size: props.size, size: props.size,
showDetails: props.showDetails, showDetails: props.showDetails,
showOverview: props.showOverview showOverview: props.showOverview,
showPosters: props.showPosters
}; };
} }
@ -40,7 +41,8 @@ class CollectionOverviewOptionsModalContent extends Component {
detailedProgressBar, detailedProgressBar,
size, size,
showDetails, showDetails,
showOverview showOverview,
showPosters
} = this.props; } = this.props;
const state = {}; const state = {};
@ -61,6 +63,10 @@ class CollectionOverviewOptionsModalContent extends Component {
state.showOverview = showOverview; state.showOverview = showOverview;
} }
if (showPosters !== prevProps.showPosters) {
state.showPosters = showPosters;
}
if (!_.isEmpty(state)) { if (!_.isEmpty(state)) {
this.setState(state); this.setState(state);
} }
@ -99,13 +105,14 @@ class CollectionOverviewOptionsModalContent extends Component {
size, size,
detailedProgressBar, detailedProgressBar,
showDetails, showDetails,
showPosters,
showOverview showOverview
} = this.state; } = this.state;
return ( return (
<ModalContent onModalClose={onModalClose}> <ModalContent onModalClose={onModalClose}>
<ModalHeader> <ModalHeader>
Overview Options {translate('CollectionOptions')}
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody>
@ -141,6 +148,7 @@ class CollectionOverviewOptionsModalContent extends Component {
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showDetails" name="showDetails"
value={showDetails} value={showDetails}
helpText={translate('CollectionShowDetailsHelpText')}
onChange={this.onChangeOverviewOption} onChange={this.onChangeOverviewOption}
/> />
</FormGroup> </FormGroup>
@ -152,6 +160,19 @@ class CollectionOverviewOptionsModalContent extends Component {
type={inputTypes.CHECK} type={inputTypes.CHECK}
name="showOverview" name="showOverview"
value={showOverview} value={showOverview}
helpText={translate('CollectionShowOverviewsHelpText')}
onChange={this.onChangeOverviewOption}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('ShowPosters')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="showPosters"
value={showPosters}
helpText={translate('CollectionShowPostersHelpText')}
onChange={this.onChangeOverviewOption} onChange={this.onChangeOverviewOption}
/> />
</FormGroup> </FormGroup>
@ -175,6 +196,7 @@ CollectionOverviewOptionsModalContent.propTypes = {
size: PropTypes.string.isRequired, size: PropTypes.string.isRequired,
showDetails: PropTypes.bool.isRequired, showDetails: PropTypes.bool.isRequired,
showOverview: PropTypes.bool.isRequired, showOverview: PropTypes.bool.isRequired,
showPosters: PropTypes.bool.isRequired,
onChangeOverviewOption: PropTypes.func.isRequired, onChangeOverviewOption: PropTypes.func.isRequired,
onChangeOption: PropTypes.func.isRequired, onChangeOption: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired onModalClose: PropTypes.func.isRequired

View File

@ -40,7 +40,8 @@ export const defaultState = {
detailedProgressBar: false, detailedProgressBar: false,
size: 'medium', size: 'medium',
showDetails: true, showDetails: true,
showOverview: true showOverview: true,
showPosters: true
}, },
defaults: { defaults: {

View File

@ -138,7 +138,11 @@
"Close": "Close", "Close": "Close",
"CloseCurrentModal": "Close Current Modal", "CloseCurrentModal": "Close Current Modal",
"Collection": "Collection", "Collection": "Collection",
"CollectionOptions": "Collection Options",
"Collections": "Collections", "Collections": "Collections",
"CollectionShowDetailsHelpText": "Show collection status and properties",
"CollectionShowOverviewsHelpText": "Show collection overviews",
"CollectionShowPostersHelpText": "Show Collection item posters",
"CollectionsSelectedInterp": "{0} Collections(s) Selected", "CollectionsSelectedInterp": "{0} Collections(s) Selected",
"ColonReplacement": "Colon Replacement", "ColonReplacement": "Colon Replacement",
"ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement", "ColonReplacementFormatHelpText": "Change how Radarr handles colon replacement",
@ -932,6 +936,7 @@
"ShownClickToHide": "Shown, click to hide", "ShownClickToHide": "Shown, click to hide",
"ShowOverview": "Show Overview", "ShowOverview": "Show Overview",
"ShowPath": "Show Path", "ShowPath": "Show Path",
"ShowPosters": "Show Posters",
"ShowQualityProfile": "Show Quality Profile", "ShowQualityProfile": "Show Quality Profile",
"ShowQualityProfileHelpText": "Show quality profile under poster", "ShowQualityProfileHelpText": "Show quality profile under poster",
"ShowRatings": "Show Ratings", "ShowRatings": "Show Ratings",