diff --git a/src/common/Slider/Slider.js b/src/common/Slider/Slider.js
index e700d040a..c877071c3 100644
--- a/src/common/Slider/Slider.js
+++ b/src/common/Slider/Slider.js
@@ -4,6 +4,12 @@ import classnames from 'classnames';
import styles from './styles';
class Slider extends Component {
+ componentWillReceiveProps(nextProps) {
+ if (this.props.orientation !== nextProps.orientation) {
+ console.warn('changing orientation property at runtime is not supported');
+ }
+ }
+
shouldComponentUpdate(nextProps, nextState) {
return nextProps.value !== this.props.value ||
nextProps.minValue !== this.props.minValue ||
@@ -30,14 +36,17 @@ class Slider extends Component {
}
}
- calculateSlidingValue = (mouseX, sliderElement) => {
- const { x: sliderX, width: sliderWidth } = sliderElement.getBoundingClientRect();
- const thumbX = Math.min(Math.max(mouseX - sliderX, 0), sliderWidth);
- const slidingValue = (thumbX / sliderWidth) * (this.props.maxValue - this.props.minValue) + this.props.minValue;
+ calculateSlidingValue = ({ mouseX, mouseY, sliderElement }) => {
+ const { x: sliderX, y: sliderY, width: sliderWidth, height: sliderHeight } = sliderElement.getBoundingClientRect();
+ const sliderStart = this.props.orientation === 'horizontal' ? sliderX : sliderY;
+ const sliderLength = this.props.orientation === 'horizontal' ? sliderWidth : sliderHeight;
+ const mouseStart = this.props.orientation === 'horizontal' ? mouseX : mouseY;
+ const thumbStart = Math.min(Math.max(mouseStart - sliderStart, 0), sliderLength);
+ const slidingValue = (thumbStart / sliderLength) * (this.props.maxValue - this.props.minValue) + this.props.minValue;
return Math.floor(slidingValue);
}
- onStartSliding = ({ currentTarget: sliderElement, clientX: mouseX, button }) => {
+ onStartSliding = ({ currentTarget: sliderElement, clientX: mouseX, clientY: mouseY, button }) => {
if (button !== 0) {
return;
}
@@ -54,12 +63,14 @@ class Slider extends Component {
releaseThumb();
this.onSlidingAborted();
};
- const onMouseUp = ({ clientX: mouseX }) => {
+ const onMouseUp = ({ clientX: mouseX, clientY: mouseY }) => {
releaseThumb();
- this.onSlidingCompleted(this.calculateSlidingValue(mouseX, sliderElement));
+ const slidingValue = this.calculateSlidingValue({ mouseX, mouseY, sliderElement });
+ this.onSlidingCompleted(slidingValue);
};
- const onMouseMove = ({ clientX: mouseX }) => {
- this.onSliding(this.calculateSlidingValue(mouseX, sliderElement));
+ const onMouseMove = ({ clientX: mouseX, clientY: mouseY }) => {
+ const slidingValue = this.calculateSlidingValue({ mouseX, mouseY, sliderElement });
+ this.onSliding(slidingValue);
};
window.addEventListener('blur', onBlur);
@@ -68,17 +79,18 @@ class Slider extends Component {
document.body.style['pointer-events'] = 'none';
document.documentElement.style.cursor = 'pointer';
sliderElement.classList.add(styles['active']);
- onMouseMove({ clientX: mouseX });
+ onMouseMove({ clientX: mouseX, clientY: mouseY });
}
render() {
- const thumbLeft = (this.props.value - this.props.minValue) / (this.props.maxValue - this.props.minValue);
+ const thumbStartProp = this.props.orientation === 'horizontal' ? 'left' : 'top';
+ const thumbStart = (this.props.value - this.props.minValue) / (this.props.maxValue - this.props.minValue);
return (
-
+
);
@@ -91,6 +103,7 @@ Slider.propTypes = {
value: PropTypes.number.isRequired,
minValue: PropTypes.number.isRequired,
maxValue: PropTypes.number.isRequired,
+ orientation: PropTypes.oneOf(['horizontal', 'vertical']).isRequired,
onSliding: PropTypes.func,
onSlidingCompleted: PropTypes.func,
onSlidingAborted: PropTypes.func
@@ -98,7 +111,8 @@ Slider.propTypes = {
Slider.defaultProps = {
value: 0,
minValue: 0,
- maxValue: 100
+ maxValue: 100,
+ orientation: 'horizontal'
};
export default Slider;
diff --git a/src/common/Slider/styles.less b/src/common/Slider/styles.less
index cc84039df..ef9638406 100644
--- a/src/common/Slider/styles.less
+++ b/src/common/Slider/styles.less
@@ -6,10 +6,6 @@
.line {
position: absolute;
- left: 0;
- right: 0;
- top: 40%;
- bottom: 40%;
z-index: 1;
background-color: @colorprim;
}
@@ -19,8 +15,6 @@
z-index: 2;
border-radius: 50%;
background-color: @colormedium;
- transform: translateX(-50%);
- transition-property: left;
transition-duration: 0.06s;
&:hover {
@@ -28,6 +22,34 @@
}
}
+ &.horizontal {
+ .line {
+ left: 0;
+ right: 0;
+ top: 40%;
+ bottom: 40%;
+ }
+
+ .thumb {
+ transform: translateX(-50%);
+ transition-property: left;
+ }
+ }
+
+ &.vertical {
+ .line {
+ left: 40%;
+ right: 40%;
+ top: 0;
+ bottom: 0;
+ }
+
+ .thumb {
+ transform: translateY(-50%);
+ transition-property: top;
+ }
+ }
+
&.active {
.thumb {
background-color: @colorprimlight;
diff --git a/src/routes/Player/ControlBar/ControlBar.js b/src/routes/Player/ControlBar/ControlBar.js
index 27dc9b3c5..3d2859693 100644
--- a/src/routes/Player/ControlBar/ControlBar.js
+++ b/src/routes/Player/ControlBar/ControlBar.js
@@ -59,18 +59,19 @@ class ControlBar extends Component {
return `${('0' + hours).slice(-2)}:${('0' + minutes).slice(-2)}:${('0' + seconds).slice(-2)}`;
}
- renderSeekBar() {
+ renderSeekSlider() {
if (this.props.time === null || this.props.duration === null) {
return null;
}
return (
+
+
+
+
+
+ );
+ }
+
render() {
return (
- {this.renderSeekBar()}
+ {this.renderSeekSlider()}
{this.renderPlayPauseButton()}
{this.renderTimeLabel()}
+
+ {this.renderVolumeButton()}
);
diff --git a/src/routes/Player/ControlBar/styles.less b/src/routes/Player/ControlBar/styles.less
index 4d930c3c6..3ff74e587 100644
--- a/src/routes/Player/ControlBar/styles.less
+++ b/src/routes/Player/ControlBar/styles.less
@@ -1,8 +1,8 @@
@import 'stremio-colors';
@control-bar-height: 84px;
-@seek-bar-height: 26px;
-@buttons-bar-height: (@control-bar-height - @seek-bar-height);
+@seek-slider-height: 26px;
+@buttons-bar-height: (@control-bar-height - @seek-slider-height);
.control-bar-container {
height: @control-bar-height;
@@ -13,13 +13,14 @@
padding-left: 2%;
padding-right: 2%;
- .seek-bar {
+ .seek-slider {
width: 100%;
- height: @seek-bar-height;
+ height: @seek-slider-height;
+ z-index: 1;
- .thumb {
- width: @seek-bar-height;
- height: @seek-bar-height;
+ .seek-thumb {
+ width: @seek-slider-height;
+ height: @seek-slider-height;
}
}
@@ -29,6 +30,7 @@
display: flex;
flex-direction: row;
align-items: center;
+ z-index: 2;
.button {
height: @buttons-bar-height;
@@ -39,8 +41,8 @@
cursor: pointer;
.icon {
- width: 64%;
- height: 64%;
+ width: 60%;
+ height: 60%;
fill: @colorwhite80;
}
@@ -49,6 +51,37 @@
fill: @colorwhite;
}
}
+
+ &.volume-button {
+ position: relative;
+
+ .volume-slider-container {
+ display: none;
+ justify-content: center;
+ width: 100%;
+ height: 300%;
+ position: absolute;
+ bottom: 100%;
+
+ .volume-slider {
+ width: round((@buttons-bar-height * 0.4));
+ height: 100%;
+
+ .volume-thumb {
+ width: round((@buttons-bar-height * 0.4));
+ height: round((@buttons-bar-height * 0.4));
+ }
+ }
+ }
+
+ &:hover {
+ .volume-slider-container {
+ display: flex;
+
+
+ }
+ }
+ }
}
.separator {
@@ -63,5 +96,9 @@
color: @colorwhite;
font-size: 16px;
}
+
+ .spacing {
+ flex: 1
+ }
}
}
\ No newline at end of file