2017-09-04 02:20:56 +00:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
import ReactSlider from 'react-slider';
|
|
|
|
import NumberInput from 'Components/Form/NumberInput';
|
|
|
|
import TextInput from 'Components/Form/TextInput';
|
2020-09-07 01:33:10 +00:00
|
|
|
import Label from 'Components/Label';
|
2019-05-11 01:56:04 +00:00
|
|
|
import Popover from 'Components/Tooltip/Popover';
|
2020-09-07 01:33:10 +00:00
|
|
|
import { kinds, tooltipPositions } from 'Helpers/Props';
|
|
|
|
import formatBytes from 'Utilities/Number/formatBytes';
|
|
|
|
import roundNumber from 'Utilities/Number/roundNumber';
|
2019-05-11 01:56:04 +00:00
|
|
|
import QualityDefinitionLimits from './QualityDefinitionLimits';
|
2017-09-04 02:20:56 +00:00
|
|
|
import styles from './QualityDefinition.css';
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
const MIN = 0;
|
|
|
|
const MAX = 1500;
|
2021-01-07 06:01:30 +00:00
|
|
|
const MIN_DISTANCE = 1;
|
2019-02-23 22:39:11 +00:00
|
|
|
|
2017-09-04 02:20:56 +00:00
|
|
|
const slider = {
|
2019-02-23 22:39:11 +00:00
|
|
|
min: MIN,
|
|
|
|
max: roundNumber(Math.pow(MAX, 1 / 1.1)),
|
|
|
|
step: 0.1
|
2017-09-04 02:20:56 +00:00
|
|
|
};
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
function getValue(inputValue) {
|
|
|
|
if (inputValue < MIN) {
|
|
|
|
return MIN;
|
2017-09-04 02:20:56 +00:00
|
|
|
}
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
if (inputValue > MAX) {
|
|
|
|
return MAX;
|
2017-09-04 02:20:56 +00:00
|
|
|
}
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
return roundNumber(inputValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getSliderValue(value, defaultValue) {
|
|
|
|
const sliderValue = value ? Math.pow(value, 1 / 1.1) : defaultValue;
|
|
|
|
|
|
|
|
return roundNumber(sliderValue);
|
2017-09-04 02:20:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class QualityDefinition extends Component {
|
|
|
|
|
2018-01-26 03:01:53 +00:00
|
|
|
//
|
|
|
|
// Lifecycle
|
|
|
|
|
|
|
|
constructor(props, context) {
|
|
|
|
super(props, context);
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
this.state = {
|
|
|
|
sliderMinSize: getSliderValue(props.minSize, slider.min),
|
|
|
|
sliderMaxSize: getSliderValue(props.maxSize, slider.max)
|
|
|
|
};
|
2018-01-26 03:01:53 +00:00
|
|
|
}
|
|
|
|
|
2017-09-04 02:20:56 +00:00
|
|
|
//
|
|
|
|
// Listeners
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
onSliderChange = ([sliderMinSize, sliderMaxSize]) => {
|
|
|
|
this.setState({
|
|
|
|
sliderMinSize,
|
|
|
|
sliderMaxSize
|
|
|
|
});
|
|
|
|
|
|
|
|
this.props.onSizeChange({
|
|
|
|
minSize: roundNumber(Math.pow(sliderMinSize, 1.1)),
|
|
|
|
maxSize: sliderMaxSize === slider.max ? null : roundNumber(Math.pow(sliderMaxSize, 1.1))
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
onAfterSliderChange = () => {
|
|
|
|
const {
|
|
|
|
minSize,
|
|
|
|
maxSize
|
|
|
|
} = this.props;
|
2017-09-04 02:20:56 +00:00
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
this.setState({
|
|
|
|
sliderMiSize: getSliderValue(minSize, slider.min),
|
|
|
|
sliderMaxSize: getSliderValue(maxSize, slider.max)
|
|
|
|
});
|
2017-09-04 02:20:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onMinSizeChange = ({ value }) => {
|
|
|
|
const minSize = getValue(value);
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
this.setState({
|
|
|
|
sliderMinSize: getSliderValue(minSize, slider.min)
|
|
|
|
});
|
|
|
|
|
2017-09-04 02:20:56 +00:00
|
|
|
this.props.onSizeChange({
|
|
|
|
minSize,
|
|
|
|
maxSize: this.props.maxSize
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
onMaxSizeChange = ({ value }) => {
|
2019-02-23 22:39:11 +00:00
|
|
|
const maxSize = value === MAX ? null : getValue(value);
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
sliderMaxSize: getSliderValue(maxSize, slider.max)
|
|
|
|
});
|
2017-09-04 02:20:56 +00:00
|
|
|
|
|
|
|
this.props.onSizeChange({
|
|
|
|
minSize: this.props.minSize,
|
|
|
|
maxSize
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Render
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
id,
|
|
|
|
quality,
|
|
|
|
title,
|
|
|
|
minSize,
|
|
|
|
maxSize,
|
|
|
|
advancedSettings,
|
|
|
|
onTitleChange
|
|
|
|
} = this.props;
|
|
|
|
|
2019-02-23 22:39:11 +00:00
|
|
|
const {
|
|
|
|
sliderMinSize,
|
|
|
|
sliderMaxSize
|
|
|
|
} = this.state;
|
|
|
|
|
2017-12-28 02:41:11 +00:00
|
|
|
const minBytes = minSize * 128;
|
|
|
|
const maxBytes = maxSize && maxSize * 128;
|
2017-09-04 02:20:56 +00:00
|
|
|
|
2019-05-11 01:56:04 +00:00
|
|
|
const minRate = `${formatBytes(minBytes, true)}/s`;
|
|
|
|
const maxRate = maxBytes ? `${formatBytes(maxBytes, true)}/s` : 'Unlimited';
|
2017-09-04 02:20:56 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={styles.qualityDefinition}>
|
|
|
|
<div className={styles.quality}>
|
|
|
|
{quality.name}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className={styles.title}>
|
|
|
|
<TextInput
|
|
|
|
name={`${id}.${title}`}
|
|
|
|
value={title}
|
|
|
|
onChange={onTitleChange}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className={styles.sizeLimit}>
|
|
|
|
<ReactSlider
|
|
|
|
min={slider.min}
|
|
|
|
max={slider.max}
|
|
|
|
step={slider.step}
|
2021-01-07 06:01:30 +00:00
|
|
|
minDistance={MIN_DISTANCE * 5}
|
2019-02-23 22:39:11 +00:00
|
|
|
value={[sliderMinSize, sliderMaxSize]}
|
2020-03-04 01:54:11 +00:00
|
|
|
withTracks={true}
|
2017-09-04 02:20:56 +00:00
|
|
|
snapDragDisabled={true}
|
|
|
|
className={styles.slider}
|
2020-03-04 01:54:11 +00:00
|
|
|
trackClassName={styles.bar}
|
|
|
|
thumbClassName={styles.handle}
|
2019-02-23 22:39:11 +00:00
|
|
|
onChange={this.onSliderChange}
|
|
|
|
onAfterChange={this.onAfterSliderChange}
|
2017-09-04 02:20:56 +00:00
|
|
|
/>
|
|
|
|
|
|
|
|
<div className={styles.sizes}>
|
|
|
|
<div>
|
2019-05-11 01:56:04 +00:00
|
|
|
<Popover
|
|
|
|
anchor={
|
|
|
|
<Label kind={kinds.INFO}>{minRate}</Label>
|
|
|
|
}
|
|
|
|
title="Minimum Limits"
|
|
|
|
body={
|
|
|
|
<QualityDefinitionLimits
|
|
|
|
bytes={minBytes}
|
|
|
|
message="No minimum for any runtime"
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
position={tooltipPositions.BOTTOM}
|
|
|
|
/>
|
2017-09-04 02:20:56 +00:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div>
|
2019-05-11 01:56:04 +00:00
|
|
|
<Popover
|
|
|
|
anchor={
|
|
|
|
<Label kind={kinds.WARNING}>{maxRate}</Label>
|
|
|
|
}
|
|
|
|
title="Maximum Limits"
|
|
|
|
body={
|
|
|
|
<QualityDefinitionLimits
|
|
|
|
bytes={maxBytes}
|
|
|
|
message="No limit for any runtime"
|
|
|
|
/>
|
|
|
|
}
|
|
|
|
position={tooltipPositions.BOTTOM}
|
|
|
|
/>
|
2017-09-04 02:20:56 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{
|
|
|
|
advancedSettings &&
|
2017-12-28 02:41:11 +00:00
|
|
|
<div className={styles.kilobitsPerSecond}>
|
2017-09-04 02:20:56 +00:00
|
|
|
<div>
|
|
|
|
Min
|
|
|
|
|
|
|
|
<NumberInput
|
|
|
|
className={styles.sizeInput}
|
|
|
|
name={`${id}.min`}
|
2019-02-23 22:39:11 +00:00
|
|
|
value={minSize || MIN}
|
|
|
|
min={MIN}
|
2021-01-07 06:01:30 +00:00
|
|
|
max={maxSize ? maxSize - MIN_DISTANCE : MAX - MIN_DISTANCE}
|
2019-02-23 22:39:11 +00:00
|
|
|
step={0.1}
|
2017-09-04 02:20:56 +00:00
|
|
|
isFloat={true}
|
|
|
|
onChange={this.onMinSizeChange}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div>
|
|
|
|
Max
|
|
|
|
|
|
|
|
<NumberInput
|
|
|
|
className={styles.sizeInput}
|
2017-12-28 02:41:11 +00:00
|
|
|
name={`${id}.max`}
|
2019-02-23 22:39:11 +00:00
|
|
|
value={maxSize || MAX}
|
2021-01-07 06:01:30 +00:00
|
|
|
min={minSize + MIN_DISTANCE}
|
2019-02-23 22:39:11 +00:00
|
|
|
max={MAX}
|
|
|
|
step={0.1}
|
2017-09-04 02:20:56 +00:00
|
|
|
isFloat={true}
|
|
|
|
onChange={this.onMaxSizeChange}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QualityDefinition.propTypes = {
|
|
|
|
id: PropTypes.number.isRequired,
|
|
|
|
quality: PropTypes.object.isRequired,
|
|
|
|
title: PropTypes.string.isRequired,
|
|
|
|
minSize: PropTypes.number,
|
|
|
|
maxSize: PropTypes.number,
|
|
|
|
advancedSettings: PropTypes.bool.isRequired,
|
|
|
|
onTitleChange: PropTypes.func.isRequired,
|
|
|
|
onSizeChange: PropTypes.func.isRequired
|
|
|
|
};
|
|
|
|
|
|
|
|
export default QualityDefinition;
|