refactor(SpeedMenu): use option list instead of multiselect

This commit is contained in:
Tim 2022-10-27 16:30:33 +02:00
parent 328ad68824
commit d601608735
5 changed files with 101 additions and 21 deletions

View file

@ -0,0 +1,33 @@
// Copyright (C) 2017-2022 Smart code 203358507
const React = require('react');
const PropTypes = require('prop-types');
const classnames = require('classnames');
const { Button } = require('stremio/common');
const styles = require('./styles');
const OptionButton = ({ className, value, selected, onSelect }) => {
const onClick = React.useCallback(() => {
if (typeof onSelect === 'function') {
onSelect(value);
}
}, [onSelect, value]);
return (
<Button
className={classnames(className, styles['option'], { 'selected': selected })}
onClick={onClick}
>
<div className={styles['label']}>{ value }x</div>
<div className={styles['icon']} />
</Button>
);
};
OptionButton.propTypes = {
className: PropTypes.string,
value: PropTypes.number,
selected: PropTypes.bool,
onSelect: PropTypes.func,
};
module.exports = OptionButton;

View file

@ -0,0 +1,5 @@
// Copyright (C) 2017-2022 Smart code 203358507
const Option = require('./Option');
module.exports = Option;

View file

@ -0,0 +1,38 @@
// Copyright (C) 2017-2022 Smart code 203358507
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
.option {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 1.5em;
&:global(.selected) {
background-color: @color-background;
.icon {
display: block;
}
}
&:hover, &:focus {
background-color: @color-background-light2;
}
.label {
flex: 1;
font-weight: 400;
color: @color-surface-light5-90;
}
.icon {
flex: none;
display: none;
width: 0.5rem;
height: 0.5rem;
border-radius: 100%;
margin-left: 1rem;
background-color: @color-accent3-90;
}
}

View file

@ -3,7 +3,7 @@
const React = require('react');
const PropTypes = require('prop-types');
const classnames = require('classnames');
const { Multiselect } = require('stremio/common');
const Option = require('./Option');
const styles = require('./styles');
const RATES = Array.from(Array(8).keys(), (n) => n * 0.25 + 0.25).reverse();
@ -12,31 +12,29 @@ const SpeedMenu = ({ className, playbackSpeed, onPlaybackSpeedChanged }) => {
const onMouseDown = React.useCallback((event) => {
event.nativeEvent.speedMenuClosePrevented = true;
}, []);
const onOptionSelect = React.useCallback((event) => {
if (typeof onPlaybackSpeedChanged === 'function' && event.value) {
onPlaybackSpeedChanged(parseFloat(event.value));
const onOptionSelect = React.useCallback((value) => {
if (typeof onPlaybackSpeedChanged === 'function') {
onPlaybackSpeedChanged(value);
}
}, [onPlaybackSpeedChanged]);
const selectableOptions = React.useMemo(() => ({
title: 'Playback Speed',
options: RATES.map((rate) => ({
value: `${rate}`,
label: `${rate}x`,
title: `${rate}x`
})),
selected: [`${playbackSpeed}`],
renderLabelText: () => `${playbackSpeed}x`,
onSelect: onOptionSelect
}), [playbackSpeed, onOptionSelect]);
return (
<div className={classnames(className, styles['speed-menu-container'])} onMouseDown={onMouseDown}>
<div className={styles['title']}>
Playback Speed
</div>
<Multiselect
{...selectableOptions}
className={styles['select-input-container']}
/>
<div className={styles['options-container']}>
{
RATES.map((rate) => (
<Option
className={styles['option']}
key={rate}
value={rate}
selected={rate === playbackSpeed}
onSelect={onOptionSelect}
/>
))
}
</div>
</div>
);
};

View file

@ -15,7 +15,13 @@
margin: 1rem;
}
.select-input-container {
padding: 1rem 1.5rem;
.options-container {
flex: 0 1 auto;
max-height: calc(3.2rem * 8);
overflow-y: auto;
.option {
height: 3.2rem;
}
}
}