DiscreteSelectInput component implemented

This commit is contained in:
nklhrstv 2020-03-10 14:34:53 +02:00
parent 4e28aebc33
commit bd428e3ec1
5 changed files with 123 additions and 86 deletions

View file

@ -0,0 +1,45 @@
const React = require('react');
const PropTypes = require('prop-types');
const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Button } = require('stremio/common');
const styles = require('./styles');
const DiscreteSelectInput = ({ className, value, label, disabled, dataset, onChange }) => {
const buttonOnClick = React.useCallback((event) => {
if (typeof onChange === 'function') {
onChange({
type: 'change',
value: event.currentTarget.dataset.type,
dataset: dataset,
reactEvent: event,
nativeEvent: event.nativeEvent
});
}
}, [dataset, onChange]);
return (
<div className={classnames(className, styles['discrete-input-container'], { 'disabled': disabled })}>
<div className={styles['header']}>{label}</div>
<div className={styles['input-container']} title={disabled ? `${label} is not configurable` : null}>
<Button className={classnames(styles['button-container'], { 'disabled': disabled })} data-type={'decrement'} onClick={buttonOnClick}>
<Icon className={styles['icon']} icon={'ic_minus'} />
</Button>
<div className={styles['option-label']} title={value}>{value}</div>
<Button className={classnames(styles['button-container'], { 'disabled': disabled })} data-type={'increment'} onClick={buttonOnClick}>
<Icon className={styles['icon']} icon={'ic_plus'} />
</Button>
</div>
</div>
);
};
DiscreteSelectInput.propTypes = {
className: PropTypes.string,
value: PropTypes.string,
label: PropTypes.string,
disabled: PropTypes.bool,
dataset: PropTypes.object,
onChange: PropTypes.func
};
module.exports = DiscreteSelectInput;

View file

@ -0,0 +1,3 @@
const DiscreteSelectInput = require('./DiscreteSelectInput');
module.exports = DiscreteSelectInput;

View file

@ -0,0 +1,49 @@
@import (reference) '~stremio-colors/dist/less/stremio-colors.less';
.discrete-input-container {
&:global(.disabled) {
.header {
color: @color-surface-90;
}
.input-container {
opacity: 0.4;
}
}
.header {
max-height: 2.4em;
margin-bottom: 0.5rem;
color: @color-surface-light5-90;
}
.input-container {
display: flex;
flex-direction: row;
align-items: center;
background: @color-background-dark1;
.button-container {
flex: none;
width: 3rem;
height: 3rem;
padding: 1rem;
background-color: @color-background-light2;
.icon {
display: block;
width: 100%;
height: 100%;
fill: @color-surface-light5;
}
}
.option-label {
flex: 1;
max-height: 2.4em;
font-weight: 500;
text-align: center;
color: @color-surface-light5-90;
}
}
}

View file

@ -3,6 +3,7 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Button, ColorInput } = require('stremio/common');
const DiscreteSelectInput = require('./DiscreteSelectInput');
const styles = require('./styles');
const SUBTITLES_SIZES = [75, 100, 125, 150, 175, 200, 250];
@ -57,11 +58,6 @@ const SubtitlesPicker = (props) => {
:
[];
}, [props.tracks, selectedLanguage]);
const offsetDisabled = React.useMemo(() => {
return typeof selectedLanguage !== 'string' ||
props.offset === null ||
isNaN(props.offset);
}, [selectedLanguage, props.offset]);
const onMouseDown = React.useCallback((event) => {
event.nativeEvent.subtitlesPickerClosePrevented = true;
}, []);
@ -81,9 +77,10 @@ const SubtitlesPicker = (props) => {
const trackOnClick = React.useCallback((event) => {
props.onTrackSelected(event.currentTarget.dataset.trackId);
}, [props.onTrackSelected]);
const onOffsetButtonClicked = React.useCallback((event) => {
const onOffsetChange = React.useCallback((event) => {
if (props.offset !== null && !isNaN(props.offset)) {
const offset = props.offset + parseInt(event.currentTarget.dataset.offset);
const delta = event.value === 'increment' ? 1 : -1;
const offset = props.offset + delta;
if (typeof props.onOffsetChanged === 'function') {
props.onOffsetChanged(offset);
}
@ -143,38 +140,25 @@ const SubtitlesPicker = (props) => {
</div>
<div className={styles['subtitles-settings-container']}>
<div className={styles['settings-header']}>Settings</div>
<div className={styles['option-header']}>Delay</div>
<div className={styles['option-container']}>
<Button className={styles['button-container']}>
<Icon className={styles['icon']} icon={'ic_minus'} />
</Button>
<div className={styles['option-label']} title={'150s'}>150s</div>
<Button className={styles['button-container']}>
<Icon className={styles['icon']} icon={'ic_plus'} />
</Button>
</div>
<div className={styles['option-header']}>Size</div>
<div className={styles['option-container']}>
<Button className={styles['button-container']}>
<Icon className={styles['icon']} icon={'ic_minus'} />
</Button>
<div className={styles['option-label']} title={'100%'}>100%</div>
<Button className={styles['button-container']}>
<Icon className={styles['icon']} icon={'ic_plus'} />
</Button>
</div>
<div className={classnames(styles['option-header'], { 'disabled': offsetDisabled })}>Vertical position</div>
<div className={classnames(styles['option-container'], { 'disabled': offsetDisabled })} title={offsetDisabled ? 'Vertical position is not configurable' : null}>
<Button className={classnames(styles['button-container'], { 'disabled': offsetDisabled })} data-offset={-1} onClick={onOffsetButtonClicked}>
<Icon className={styles['icon']} icon={'ic_minus'} />
</Button>
<div className={styles['option-label']} title={props.offset !== null && !isNaN(props.offset) ? `${props.offset}%` : null}>
{props.offset !== null && !isNaN(props.offset) ? `${props.offset}%` : '--'}
</div>
<Button className={classnames(styles['button-container'], { 'disabled': offsetDisabled })} data-offset={1} onClick={onOffsetButtonClicked}>
<Icon className={styles['icon']} icon={'ic_plus'} />
</Button>
</div>
<DiscreteSelectInput
className={styles['discrete-input']}
label={'Delay'}
value={props.delay !== null && !isNaN(props.delay) ? `${props.delay}ms` : '--'}
disabled={typeof selectedLanguage !== 'string' || props.delay === null || isNaN(props.delay)}
/>
<DiscreteSelectInput
className={styles['discrete-input']}
label={'Size'}
value={props.size !== null && !isNaN(props.size) ? `${props.size}ms` : '--'}
disabled={typeof selectedLanguage !== 'string' || props.size === null || isNaN(props.size)}
/>
<DiscreteSelectInput
className={styles['discrete-input']}
label={'Vertical position'}
value={props.offset !== null && !isNaN(props.offset) ? `${props.offset}%` : '--'}
disabled={typeof selectedLanguage !== 'string' || props.offset === null || isNaN(props.offset)}
onChange={onOffsetChange}
/>
<div className={styles['spacing']} />
<Button className={styles['advanced-button']}>Advanced</Button>
</div>
@ -192,7 +176,7 @@ SubtitlesPicker.propTypes = {
selectedTrackId: PropTypes.string,
offset: PropTypes.number,
size: PropTypes.number,
felay: PropTypes.number,
delay: PropTypes.number,
textColor: PropTypes.string,
backgroundColor: PropTypes.string,
outlineColor: PropTypes.string,

View file

@ -92,53 +92,9 @@
flex: 1;
}
.option-header {
flex: none;
align-self: stretch;
max-height: 2.4em;
margin: 0 3rem;
color: @color-surface-light5-90;
.discrete-input {
margin: 0 3rem 1rem;
&:global(.disabled) {
color: @color-surface-90;
}
}
.option-container {
flex: none;
align-self: stretch;
margin: 0.5rem 3rem 1rem;
display: flex;
flex-direction: row;
align-items: center;
background: @color-background-dark1;
&:global(.disabled) {
opacity: 0.4;
}
.button-container {
flex: none;
width: 3rem;
height: 3rem;
padding: 1rem;
background-color: @color-background-light2;
.icon {
display: block;
width: 100%;
height: 100%;
fill: @color-surface-light5;
}
}
.option-label {
flex: 1;
max-height: 2.4em;
font-weight: 500;
text-align: center;
color: @color-surface-light5-90;
}
}
.advanced-button {