subtitles picker adapted to latest changes in common

This commit is contained in:
NikolaBorislavovHristov 2019-10-05 12:27:28 +03:00
parent ae4bfda554
commit 671873aeb3
2 changed files with 109 additions and 188 deletions

View file

@ -3,13 +3,16 @@ const PropTypes = require('prop-types');
const classnames = require('classnames');
const Icon = require('stremio-icons/dom');
const { Modal } = require('stremio-router');
const { ColorPicker } = require('stremio/common');
const { ColorInput } = require('stremio/common');
const styles = require('./styles');
const ORIGIN_PRIORITIES = Object.freeze({
'LOCAL': 1,
'EMBEDDED': 2
});
const LANGUAGE_PRIORITIES = Object.freeze({
'English': 1
});
const SUBTITLES_SIZE_LABELS = Object.freeze({
1: '75%',
2: '100%',
@ -27,13 +30,9 @@ const comparatorWithPriorities = (priorities) => {
if (!isNaN(valueB)) return 1;
return a - b;
};
}
};
const NumberInput = ({ value, label, delta, onChange }) => {
if (value === null) {
return null;
}
return (
<div className={styles['number-input-container']}>
<div className={styles['number-input-button']} data-value={value - delta} onClick={onChange}>
@ -47,100 +46,55 @@ const NumberInput = ({ value, label, delta, onChange }) => {
);
};
const SubtitlesColorPicker = ({ label, value, onChange }) => {
const [open, setOpen] = React.useState(false);
const onOpen = () => setOpen(true);
const onClose = () => setOpen(false);
if (value === null) {
return null;
}
return (
<React.Fragment>
<div className={styles['color-picker-button-container']}>
<div style={{ backgroundColor: value }} className={styles['color-picker-indicator']} onClick={onOpen} />
<div className={styles['color-picker-label']}>{label}</div>
</div>
{
open ?
<Modal>
<div className={styles['color-picker-modal-container']} onClick={onClose}>
<ColorPicker className={styles['color-picker-container']} value={value} onChange={onChange} />
</div>
</Modal>
:
null
}
</React.Fragment>
);
};
class SubtitlesPicker extends React.Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.className !== this.props.className ||
nextProps.subtitlesTracks !== this.props.subtitlesTracks ||
nextProps.selectedSubtitlesTrackId !== this.props.selectedSubtitlesTrackId ||
nextProps.subtitlesSize !== this.props.subtitlesSize ||
nextProps.subtitlesDelay !== this.props.subtitlesDelay ||
nextProps.subtitlesTextColor !== this.props.subtitlesTextColor ||
nextProps.subtitlesBackgroundColor !== this.props.subtitlesBackgroundColor ||
nextProps.subtitlesOutlineColor !== this.props.subtitlesOutlineColor;
}
toggleSubtitleEnabled = () => {
const selectedSubtitlesTrackId = this.props.selectedSubtitlesTrackId === null && this.props.subtitlesTracks.length > 0 ?
this.props.subtitlesTracks[0].id
const SubtitlesPicker = (props) => {
const toggleSubtitleEnabled = React.useCallback(() => {
const selectedSubtitlesTrackId = props.selectedSubtitlesTrackId === null && props.subtitlesTracks.length > 0 ?
props.subtitlesTracks[0].id
:
null;
this.props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: selectedSubtitlesTrackId });
}
labelOnClick = (event) => {
const subtitleTrack = this.props.subtitlesTracks.find(({ label, origin }) => {
props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: selectedSubtitlesTrackId });
}, [props.selectedSubtitlesTrackId, props.subtitlesTracks, props.dispatch]);
const labelOnClick = React.useCallback((event) => {
const subtitleTrack = props.subtitlesTracks.find(({ label, origin }) => {
return label === event.currentTarget.dataset.label &&
origin === event.currentTarget.dataset.origin;
});
if (subtitleTrack) {
this.props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: subtitleTrack.id });
props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: subtitleTrack.id });
}
}
variantOnClick = (event) => {
this.props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: event.currentTarget.dataset.trackId });
}
setsubtitlesSize = (event) => {
this.props.dispatch({ propName: 'subtitlesSize', propValue: event.currentTarget.dataset.value });
}
setSubtitlesDelay = (event) => {
this.props.dispatch({ propName: 'subtitlesDelay', propValue: event.currentTarget.dataset.value });
}
setSubtitlesTextColor = (color) => {
this.props.dispatch({ propName: 'subtitlesTextColor', propValue: color });
}
setSubtitlesBackgroundColor = (color) => {
this.props.dispatch({ propName: 'subtitlesBackgroundColor', propValue: color });
}
setSubtitlesOutlineColor = (color) => {
this.props.dispatch({ propName: 'subtitlesOutlineColor', propValue: color });
}
renderToggleButton({ selectedTrack }) {
return (
<div className={styles['toggle-button-container']} onClick={this.toggleSubtitleEnabled}>
}, [props.subtitlesTracks, props.dispatch]);
const variantOnClick = React.useCallback((event) => {
props.dispatch({ propName: 'selectedSubtitlesTrackId', propValue: event.currentTarget.dataset.trackId });
}, [props.dispatch]);
const setsubtitlesSize = React.useCallback((event) => {
props.dispatch({ propName: 'subtitlesSize', propValue: event.currentTarget.dataset.value });
}, [props.dispatch]);
const setSubtitlesDelay = React.useCallback((event) => {
props.dispatch({ propName: 'subtitlesDelay', propValue: event.currentTarget.dataset.value });
}, [props.dispatch]);
const setSubtitlesTextColor = React.useCallback((event) => {
props.dispatch({ propName: 'subtitlesTextColor', propValue: event.nativeEvent.value });
}, [props.dispatch]);
const setSubtitlesBackgroundColor = React.useCallback((color) => {
props.dispatch({ propName: 'subtitlesBackgroundColor', propValue: color });
}, [props.dispatch]);
const setSubtitlesOutlineColor = React.useCallback((color) => {
props.dispatch({ propName: 'subtitlesOutlineColor', propValue: color });
}, [props.dispatch]);
const selectedTrack = props.subtitlesTracks.find(({ id }) => id === props.selectedSubtitlesTrackId);
const groupedTracks = props.subtitlesTracks.reduce((result, track) => {
result[track.origin] = result[track.origin] || {};
result[track.origin][track.label] = result[track.origin][track.label] || [];
result[track.origin][track.label].push(track);
return result;
}, {});
return (
<div className={classnames(props.className, styles['subtitles-picker-container'])}>
<div className={styles['toggle-button-container']} onClick={toggleSubtitleEnabled}>
<div className={styles['toggle-label']}>ON</div>
<div className={styles['toggle-label']}>OFF</div>
<div className={classnames(styles['toggle-thumb'], { [styles['on']]: !!selectedTrack })} />
</div>
);
}
renderLabelsList({ groupedTracks, selectedTrack }) {
return (
<div className={styles['labels-list-container']}>
{
Object.keys(groupedTracks)
@ -150,13 +104,13 @@ class SubtitlesPicker extends React.Component {
<div className={styles['track-origin']}>{origin}</div>
{
Object.keys(groupedTracks[origin])
.sort(comparatorWithPriorities(this.props.languagePriorities))
.sort(comparatorWithPriorities(LANGUAGE_PRIORITIES))
.map((label) => {
const selected = selectedTrack && selectedTrack.label === label && selectedTrack.origin === origin;
return (
<div key={label}
className={classnames(styles['language-label'], { [styles['selected']]: selected })}
onClick={this.labelOnClick}
onClick={labelOnClick}
data-label={label}
data-origin={origin}
children={label}
@ -168,115 +122,83 @@ class SubtitlesPicker extends React.Component {
))
}
</div>
);
}
renderVariantsList({ groupedTracks, selectedTrack }) {
if (groupedTracks[selectedTrack.origin][selectedTrack.label].length <= 1) {
return null;
}
return (
<div className={styles['variants-container']}>
{
groupedTracks[selectedTrack.origin][selectedTrack.label].map((track, index) => (
<div key={track.id}
className={classnames(styles['variant-button'], { [styles['selected']]: track.id === selectedTrack.id })}
title={track.id}
onClick={this.variantOnClick}
data-track-id={track.id}
children={index + 1}
{
!selectedTrack ?
<div className={styles['preferences-container']}>
<div className={styles['subtitles-disabled-label']}>Subtitles are disabled</div>
</div>
:
<div className={styles['preferences-container']}>
<div className={styles['preferences-title']}>Preferences</div>
{
groupedTracks[selectedTrack.origin][selectedTrack.label].length > 1 ?
<div className={styles['variants-container']}>
{
groupedTracks[selectedTrack.origin][selectedTrack.label].map((track, index) => (
<div key={track.id}
className={classnames(styles['variant-button'], { [styles['selected']]: track.id === selectedTrack.id })}
title={track.id}
onClick={variantOnClick}
data-track-id={track.id}
children={index + 1}
/>
))
}
</div>
:
null
}
<div className={styles['color-picker-button-container']}>
<ColorInput
className={styles['color-picker-indicator']}
value={props.subtitlesTextColor}
onChange={setSubtitlesTextColor}
/>
<div className={styles['color-picker-label']}>Text color</div>
</div>
{/* <SubtitlesColorPicker
label={'Background color'}
value={props.subtitlesBackgroundColor}
onChange={setSubtitlesBackgroundColor}
/>
))
}
</div>
);
}
renderPreferences({ groupedTracks, selectedTrack }) {
if (!selectedTrack) {
return (
<div className={styles['preferences-container']}>
<div className={styles['subtitles-disabled-label']}>Subtitles are disabled</div>
</div>
);
}
return (
<div className={styles['preferences-container']}>
<div className={styles['preferences-title']}>Preferences</div>
{this.renderVariantsList({ groupedTracks, selectedTrack })}
<SubtitlesColorPicker
label={'Text color'}
value={this.props.subtitlesTextColor}
onChange={this.setSubtitlesTextColor}
/>
<SubtitlesColorPicker
label={'Background color'}
value={this.props.subtitlesBackgroundColor}
onChange={this.setSubtitlesBackgroundColor}
/>
<SubtitlesColorPicker
label={'Outline color'}
value={this.props.subtitlesOutlineColor}
onChange={this.setSubtitlesOutlineColor}
/>
<NumberInput
label={SUBTITLES_SIZE_LABELS[this.props.subtitlesSize]}
value={this.props.subtitlesSize}
delta={1}
onChange={this.setsubtitlesSize}
/>
<NumberInput
label={`${(this.props.subtitlesDelay / 1000).toFixed(2)}s`}
value={this.props.subtitlesDelay}
delta={100}
onChange={this.setSubtitlesDelay}
/>
</div>
);
}
render() {
const selectedTrack = this.props.subtitlesTracks.find(({ id }) => id === this.props.selectedSubtitlesTrackId);
const groupedTracks = this.props.subtitlesTracks.reduce((result, track) => {
result[track.origin] = result[track.origin] || {};
result[track.origin][track.label] = result[track.origin][track.label] || [];
result[track.origin][track.label].push(track);
return result;
}, {});
return (
<div className={classnames(this.props.className, styles['subtitles-picker-container'])}>
{this.renderToggleButton({ selectedTrack })}
{this.renderLabelsList({ groupedTracks, selectedTrack })}
{this.renderPreferences({ groupedTracks, selectedTrack })}
</div>
);
}
}
<SubtitlesColorPicker
label={'Outline color'}
value={props.subtitlesOutlineColor}
onChange={setSubtitlesOutlineColor}
/> */}
<NumberInput
label={SUBTITLES_SIZE_LABELS[props.subtitlesSize]}
value={props.subtitlesSize}
delta={1}
onChange={setsubtitlesSize}
/>
<NumberInput
label={`${(props.subtitlesDelay / 1000).toFixed(2)}s`}
value={props.subtitlesDelay}
delta={100}
onChange={setSubtitlesDelay}
/>
</div>
}
</div>
);
};
SubtitlesPicker.propTypes = {
className: PropTypes.string,
languagePriorities: PropTypes.objectOf(PropTypes.number).isRequired,
languagePriorities: PropTypes.objectOf(PropTypes.number),
subtitlesTracks: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
origin: PropTypes.string.isRequired
})).isRequired,
})),
selectedSubtitlesTrackId: PropTypes.string,
subtitlesSize: PropTypes.number,
subtitlesDelay: PropTypes.number,
subtitlesTextColor: PropTypes.string,
subtitlesBackgroundColor: PropTypes.string,
subtitlesOutlineColor: PropTypes.string,
dispatch: PropTypes.func.isRequired
};
SubtitlesPicker.defaultProps = {
subtitlesTracks: Object.freeze([]),
languagePriorities: Object.freeze({
English: 1
})
dispatch: PropTypes.func
};
module.exports = SubtitlesPicker;

View file

@ -1,6 +1,5 @@
.subtitles-picker-container {
width: calc(var(--subtitles-picker-button-size) * 14);
height: calc(var(--subtitles-picker-button-size) * 9);
--subtitles-picker-button-size: 2.5rem;
font-size: calc(var(--subtitles-picker-button-size) * 0.45);
padding: calc(var(--subtitles-picker-button-size) * 0.3);
gap: calc(var(--subtitles-picker-button-size) * 0.3);