mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-25 22:46:31 -04:00
Convert Quality Settings to TypeScript
This commit is contained in:
@@ -60,6 +60,7 @@ class QualityDefinitionConnector extends Component {
|
||||
|
||||
QualityDefinitionConnector.propTypes = {
|
||||
id: PropTypes.number.isRequired,
|
||||
advancedSettings: PropTypes.bool.isRequired,
|
||||
minSize: PropTypes.number,
|
||||
maxSize: PropTypes.number,
|
||||
preferredSize: PropTypes.number,
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
function QualityDefinitionLimits(props) {
|
||||
const {
|
||||
bytes,
|
||||
message
|
||||
} = props;
|
||||
|
||||
if (!bytes) {
|
||||
return <div>{message}</div>;
|
||||
}
|
||||
|
||||
const thirty = formatBytes(bytes * 30);
|
||||
const fortyFive = formatBytes(bytes * 45);
|
||||
const sixty = formatBytes(bytes * 60);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{translate('MinutesThirty', { thirty })}
|
||||
</div>
|
||||
<div>
|
||||
{translate('MinutesFortyFive', { fortyFive })}
|
||||
</div>
|
||||
<div>
|
||||
{translate('MinutesSixty', { sixty })}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
QualityDefinitionLimits.propTypes = {
|
||||
bytes: PropTypes.number,
|
||||
message: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default QualityDefinitionLimits;
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
interface QualityDefinitionLimitsProps {
|
||||
bytes?: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
function QualityDefinitionLimits(props: QualityDefinitionLimitsProps) {
|
||||
const { bytes, message } = props;
|
||||
|
||||
if (!bytes) {
|
||||
return <div>{message}</div>;
|
||||
}
|
||||
|
||||
const thirty = formatBytes(bytes * 30);
|
||||
const fortyFive = formatBytes(bytes * 45);
|
||||
const sixty = formatBytes(bytes * 60);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>{translate('MinutesThirty', { thirty })}</div>
|
||||
<div>{translate('MinutesFortyFive', { fortyFive })}</div>
|
||||
<div>{translate('MinutesSixty', { sixty })}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default QualityDefinitionLimits;
|
||||
@@ -1,80 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QualityDefinitionConnector from './QualityDefinitionConnector';
|
||||
import styles from './QualityDefinitions.css';
|
||||
|
||||
class QualityDefinitions extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
items,
|
||||
advancedSettings,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FieldSet legend={translate('QualityDefinitions')}>
|
||||
<PageSectionContent
|
||||
errorMessage={translate('QualityDefinitionsLoadError')}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.quality}>
|
||||
{translate('Quality')}
|
||||
</div>
|
||||
<div className={styles.title}>
|
||||
{translate('Title')}
|
||||
</div>
|
||||
<div className={styles.sizeLimit}>
|
||||
{translate('SizeLimit')}
|
||||
</div>
|
||||
|
||||
{
|
||||
advancedSettings ?
|
||||
<div className={styles.megabytesPerMinute}>
|
||||
{translate('MegabytesPerMinute')}
|
||||
</div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className={styles.definitions}>
|
||||
{
|
||||
items.map((item) => {
|
||||
return (
|
||||
<QualityDefinitionConnector
|
||||
key={item.id}
|
||||
{...item}
|
||||
advancedSettings={advancedSettings}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className={styles.sizeLimitHelpTextContainer}>
|
||||
<div className={styles.sizeLimitHelpText}>
|
||||
{translate('QualityLimitsSeriesRuntimeHelpText')}
|
||||
</div>
|
||||
</div>
|
||||
</PageSectionContent>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
QualityDefinitions.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
defaultProfile: PropTypes.object,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
advancedSettings: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
export default QualityDefinitions;
|
||||
@@ -0,0 +1,124 @@
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import AppState from 'App/State/AppState';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import usePrevious from 'Helpers/Hooks/usePrevious';
|
||||
import useShowAdvancedSettings from 'Helpers/Hooks/useShowAdvancedSettings';
|
||||
import {
|
||||
fetchQualityDefinitions,
|
||||
saveQualityDefinitions,
|
||||
} from 'Store/Actions/settingsActions';
|
||||
import {
|
||||
OnChildStateChange,
|
||||
SetChildSave,
|
||||
} from 'typings/Settings/SettingsState';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QualityDefinitionConnector from './QualityDefinitionConnector';
|
||||
import styles from './QualityDefinitions.css';
|
||||
|
||||
function createQualityDefinitionsSelector() {
|
||||
return createSelector(
|
||||
(state: AppState) => state.settings.qualityDefinitions,
|
||||
(qualityDefinitions) => {
|
||||
const items = qualityDefinitions.items.map((item) => {
|
||||
const pendingChanges = qualityDefinitions.pendingChanges[item.id] || {};
|
||||
|
||||
return Object.assign({}, item, pendingChanges);
|
||||
});
|
||||
|
||||
return {
|
||||
...qualityDefinitions,
|
||||
items,
|
||||
hasPendingChanges: !isEmpty(qualityDefinitions.pendingChanges),
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
interface QualityDefinitionsProps {
|
||||
isResettingQualityDefinitions: boolean;
|
||||
setChildSave: SetChildSave;
|
||||
onChildStateChange: OnChildStateChange;
|
||||
}
|
||||
|
||||
function QualityDefinitions({
|
||||
isResettingQualityDefinitions,
|
||||
setChildSave,
|
||||
onChildStateChange,
|
||||
}: QualityDefinitionsProps) {
|
||||
const dispatch = useDispatch();
|
||||
const showAdvancedSettings = useShowAdvancedSettings();
|
||||
const { items, isFetching, isPopulated, isSaving, error, hasPendingChanges } =
|
||||
useSelector(createQualityDefinitionsSelector());
|
||||
|
||||
const wasResettingQualityDefinitions = usePrevious(
|
||||
isResettingQualityDefinitions
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchQualityDefinitions());
|
||||
|
||||
setChildSave(() => {
|
||||
dispatch(saveQualityDefinitions());
|
||||
});
|
||||
}, [dispatch, setChildSave]);
|
||||
|
||||
useEffect(() => {
|
||||
onChildStateChange({
|
||||
isSaving,
|
||||
hasPendingChanges,
|
||||
});
|
||||
}, [hasPendingChanges, isSaving, onChildStateChange]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wasResettingQualityDefinitions && !isResettingQualityDefinitions) {
|
||||
dispatch(fetchQualityDefinitions());
|
||||
}
|
||||
}, [isResettingQualityDefinitions, wasResettingQualityDefinitions, dispatch]);
|
||||
|
||||
return (
|
||||
<FieldSet legend={translate('QualityDefinitions')}>
|
||||
<PageSectionContent
|
||||
errorMessage={translate('QualityDefinitionsLoadError')}
|
||||
isFetching={isFetching}
|
||||
isPopulated={isPopulated}
|
||||
error={error}
|
||||
>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.quality}>{translate('Quality')}</div>
|
||||
<div className={styles.title}>{translate('Title')}</div>
|
||||
<div className={styles.sizeLimit}>{translate('SizeLimit')}</div>
|
||||
|
||||
{showAdvancedSettings ? (
|
||||
<div className={styles.megabytesPerMinute}>
|
||||
{translate('MegabytesPerMinute')}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className={styles.definitions}>
|
||||
{items.map((item) => {
|
||||
return (
|
||||
<QualityDefinitionConnector
|
||||
key={item.id}
|
||||
{...item}
|
||||
advancedSettings={showAdvancedSettings}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className={styles.sizeLimitHelpTextContainer}>
|
||||
<div className={styles.sizeLimitHelpText}>
|
||||
{translate('QualityLimitsSeriesRuntimeHelpText')}
|
||||
</div>
|
||||
</div>
|
||||
</PageSectionContent>
|
||||
</FieldSet>
|
||||
);
|
||||
}
|
||||
|
||||
export default QualityDefinitions;
|
||||
@@ -1,90 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { fetchQualityDefinitions, saveQualityDefinitions } from 'Store/Actions/settingsActions';
|
||||
import QualityDefinitions from './QualityDefinitions';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.settings.qualityDefinitions,
|
||||
(state) => state.settings.advancedSettings,
|
||||
(qualityDefinitions, advancedSettings) => {
|
||||
const items = qualityDefinitions.items.map((item) => {
|
||||
const pendingChanges = qualityDefinitions.pendingChanges[item.id] || {};
|
||||
|
||||
return Object.assign({}, item, pendingChanges);
|
||||
});
|
||||
|
||||
return {
|
||||
...qualityDefinitions,
|
||||
items,
|
||||
hasPendingChanges: !_.isEmpty(qualityDefinitions.pendingChanges),
|
||||
advancedSettings
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchFetchQualityDefinitions: fetchQualityDefinitions,
|
||||
dispatchSaveQualityDefinitions: saveQualityDefinitions
|
||||
};
|
||||
|
||||
class QualityDefinitionsConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
dispatchFetchQualityDefinitions,
|
||||
dispatchSaveQualityDefinitions,
|
||||
onChildMounted
|
||||
} = this.props;
|
||||
|
||||
dispatchFetchQualityDefinitions();
|
||||
onChildMounted(dispatchSaveQualityDefinitions);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
hasPendingChanges,
|
||||
isSaving,
|
||||
onChildStateChange
|
||||
} = this.props;
|
||||
|
||||
if (
|
||||
prevProps.isSaving !== isSaving ||
|
||||
prevProps.hasPendingChanges !== hasPendingChanges
|
||||
) {
|
||||
onChildStateChange({
|
||||
isSaving,
|
||||
hasPendingChanges
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<QualityDefinitions
|
||||
{...this.props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
QualityDefinitionsConnector.propTypes = {
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
hasPendingChanges: PropTypes.bool.isRequired,
|
||||
dispatchFetchQualityDefinitions: PropTypes.func.isRequired,
|
||||
dispatchSaveQualityDefinitions: PropTypes.func.isRequired,
|
||||
onChildMounted: PropTypes.func.isRequired,
|
||||
onChildStateChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps, null)(QualityDefinitionsConnector);
|
||||
Reference in New Issue
Block a user