Static cleanout; Sliders now true range sliders for drag support, fixes #297

This commit is contained in:
James Barnsley
2018-07-28 22:12:36 +12:00
parent 19433efece
commit 6ff7f1865d
91 changed files with 10942 additions and 24424 deletions

View File

@ -1,34 +1,26 @@
import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as mopidyActions from '../../services/mopidy/actions'
import * as helpers from '../../helpers';
import * as mopidyActions from '../../services/mopidy/actions';
class ProgressSlider extends React.Component{
constructor(props){
super(props);
this.handleChange = helpers.throttle(this.handleChange.bind(this), 250);
}
handleClick(e){
var slider = e.target;
if (slider.className != 'slider' ) slider = slider.parentElement;
var sliderX = e.clientX - slider.getBoundingClientRect().left;
var sliderWidth = slider.getBoundingClientRect().width;
var percent = (sliderX / sliderWidth ).toFixed(2);
if (this.props.connected && this.props.current_track){
var destination_time = this.props.current_track.duration * percent;
this.props.mopidyActions.setTimePosition(destination_time);
this.setState({ animating: false });
}
}
handleChange(value){
this.props.mopidyActions.setTimePosition(this.props.current_track.duration * (value / 100));
}
render(){
var percent = 0;
if (this.props.connected && this.props.current_track){
if (this.props.connected && this.props.time_position && this.props.current_track){
percent = this.props.time_position / this.props.current_track.duration;
percent = percent * 100;
if (percent > 1000){
@ -37,8 +29,15 @@ class ProgressSlider extends React.Component{
}
return (
<div className={"progress slider horizontal "+this.props.play_state} onClick={ (e) => this.handleClick(e) } >
<div className={"progress slider horizontal "+this.props.play_state}>
<div className="track">
<input
type="range"
min="0"
max="100"
value={percent}
onChange={e => this.handleChange(parseInt(e.target.value))}
/>
<div className="progress" style={{ width: (percent)+'%' }}></div>
</div>
</div>

View File

@ -1,52 +1,19 @@
import React, { PropTypes } from 'react'
import Icon from '../Icon'
import React from 'react';
import Icon from '../Icon';
import * as helpers from '../../helpers';
export default class VolumeControl extends React.Component{
constructor(props){
super(props)
super(props);
this.handleChange = helpers.throttle(this.handleChange.bind(this), 100);
}
handleClick(e){
var old_percent = this.props.volume;
var slider = e.target;
if (slider.className != 'slider' ) slider = slider.parentElement;
var sliderX = e.clientX - slider.getBoundingClientRect().left;
var sliderWidth = slider.getBoundingClientRect().width;
var percent = Math.round((sliderX / sliderWidth ) * 100);
if (percent > 100){
percent = 100
} else if (percent < 0){
percent = 0
}
this.props.onVolumeChange(percent, old_percent);
}
handleWheel(e){
if (this.props.scrollWheel){
var old_percent = this.props.volume;
// Identify which direction we've scrolled (inverted)
// This is simplified and doesn't consider momentum as it varies wildly
// between browsers and devices
var direction = (e.deltaY > 0 ? -1 : 1)
var percent = this.props.volume;
percent += direction * 5
if (percent > 100){
percent = 100
} else if (percent < 0){
percent = 0
}
this.props.onVolumeChange(percent, old_percent);
e.preventDefault();
}
handleChange(value){
this.props.onVolumeChange(value, this.props.volume);
}
renderMuteButton(){
@ -77,10 +44,17 @@ export default class VolumeControl extends React.Component{
}
return (
<span className={className} onWheel={e => this.handleWheel(e)}>
<span className={className}>
{this.props.NoMuteButton ? null : this.renderMuteButton()}
<div className="slider-wrapper">
<div className="slider horizontal" onClick={e => this.handleClick(e)}>
<div className="slider horizontal">
<input
type="range"
min="0"
max="25"
value={this.props.volume/4}
onChange={e => this.handleChange(parseInt(e.target.value)*4)}
/>
<div className="track">
<div className="progress" style={{ width: this.props.volume+'%' }}></div>
</div>

View File

@ -4,6 +4,47 @@ export let isTouchDevice = function(){
return 'ontouchstart' in document.documentElement
}
/**
* Returns a function, that, as long as it continues to be invoked, will not
* be triggered. The function will be called after it stops being called for
* N milliseconds. If `immediate` is passed, trigger the function on the
* leading edge, instead of the trailing.
**/
export let debounce = function(fn, wait, immediate){
var timeout;
return function(){
var context = this, args = arguments;
var later = function(){
timeout = null;
if (!immediate){
fn.apply(context, args);
}
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow){
fn.apply(context, args);
}
};
};
export let throttle = function(fn, delay){
let lastCall = 0;
return function (...args){
const now = (new Date).getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return fn(...args);
}
}
/**
* Storage handler

View File

@ -278,7 +278,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +(store.getState().mopidy.play_state == 'paused' ? ' resumed' : ' started')+' playback',
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
}
@ -301,7 +300,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' paused playback',
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
}
@ -320,7 +318,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' skipped <em>'+store.getState().core.current_track.name+'</em>',
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
}
@ -338,7 +335,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' stopped playback',
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
}
@ -353,7 +349,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' changed track'
}
}
@ -366,7 +361,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' removed '+action.tlids.length+' tracks'
}
}
@ -439,7 +433,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +(action.mute ? ' muted' : ' unmuted')+' playback'
}
}
@ -599,7 +592,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' is adding '+action.uris.length+' URIs to queue',
icon: (store.getState().core.current_track ? helpers.getTrackIcon(store.getState().core.current_track, store.getState().core) : false)
}
@ -821,7 +813,6 @@ const MopidyMiddleware = (function(){
'notification',
{
notification: {
type: 'info',
content: store.getState().pusher.username +' cleared queue'
}
}

View File

@ -3,6 +3,32 @@
position: relative;
cursor: pointer;
input[type="range"]{
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
opacity: 0;
z-index: 2;
cursor: pointer;
&::-webkit-slider-thumb {
width: 1px;
border: 0;
}
&::-moz-range-thumb {
width: 1px;
border: 0;
}
&::-ms-thumb {
width: 1px;
border: 0;
}
}
.track {
position: absolute;
background: rgba(0,0,0,0.2);
@ -37,6 +63,34 @@
top: 0;
height: 100%;
max-width: 100%;
border-radius: 4px;
&:after {
@include animate(0.1s);
content: '';
display: block;
background: $turquoise;
position: absolute;
top: 0;
right: -1px;
width: 4px;
height: 4px;
border-radius: 50%;
}
}
}
&:hover {
.track {
.progress {
&:after {
width: 12px;
height: 12px;
top: -4px;
right: -6px;
background: lighten($turquoise, 10%);
}
}
}
}
}