Slider progress bar

This commit is contained in:
James Barnsley
2016-11-08 16:57:44 +13:00
parent 343a12804a
commit 04e8c7cdf5
13 changed files with 195 additions and 199 deletions

View File

@ -3285,62 +3285,6 @@ label .input .text {
padding: 10px 14px; padding: 10px 14px;
} }
.slider {
position: relative;
cursor: pointer;
}
.slider .track {
position: absolute;
background: rgba(255, 255, 255, 0.3);
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
.slider .track .progress {
position: absolute;
background: #08d58f;
pointer-events: none;
left: 0;
}
.slider.horizontal {
margin: 10px 0;
height: 20px;
}
.slider.horizontal .track {
height: 2px;
top: 9px;
right: 0;
left: 0;
}
.slider.horizontal .track .progress {
top: 0;
height: 100%;
}
.slider.vertical {
margin: 10px 0;
width: 20px;
height: 100%;
}
.slider.vertical .track {
width: 2px;
top: 0;
bottom: 0;
left: 9px;
}
.slider.vertical .track .progress {
bottom: 0;
width: 100%;
}
.context-menu { .context-menu {
position: fixed; position: fixed;
left: 0; left: 0;
@ -3437,6 +3381,62 @@ label .input .text {
padding: 10px 15px 0 15px; padding: 10px 15px 0 15px;
} }
.slider {
position: relative;
cursor: pointer;
}
.slider .track {
position: absolute;
background: rgba(255, 255, 255, 0.3);
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
.slider .track .progress {
position: absolute;
background: #08d58f;
pointer-events: none;
left: 0;
}
.slider.horizontal {
margin: 10px 0;
height: 20px;
}
.slider.horizontal .track {
height: 2px;
top: 9px;
right: 0;
left: 0;
}
.slider.horizontal .track .progress {
top: 0;
height: 100%;
}
.slider.vertical {
margin: 10px 0;
width: 20px;
height: 100%;
}
.slider.vertical .track {
width: 2px;
top: 0;
bottom: 0;
left: 9px;
}
.slider.vertical .track .progress {
bottom: 0;
width: 100%;
}
.player .current-track { .player .current-track {
font-size: 16px; font-size: 16px;
text-transform: uppercase; text-transform: uppercase;
@ -4047,7 +4047,8 @@ main header h1 {
} }
.queue-view .player .artwork, .queue-view .player .artwork,
.queue-view .player .controls { .queue-view .player .controls,
.queue-view .player .slider {
display: block; display: block;
max-width: 400px; max-width: 400px;
margin: 0 auto; margin: 0 auto;
@ -4066,9 +4067,14 @@ main header h1 {
} }
.queue-view .player .current-track { .queue-view .player .current-track {
padding: 20px 0 0 0;
font-weight: 700; font-weight: 700;
} }
.queue-view .player .slider .track {
background: rgba(0, 0, 0, 0.2);
}
.search-view .search-result-sections { .search-view .search-result-sections {
padding: 20px 20px 0; padding: 20px 20px 0;
} }

File diff suppressed because one or more lines are too long

View File

@ -1456,6 +1456,7 @@
exports.setVolume = setVolume; exports.setVolume = setVolume;
exports.seek = seek; exports.seek = seek;
exports.getTimePosition = getTimePosition; exports.getTimePosition = getTimePosition;
exports.setTimePosition = setTimePosition;
exports.getPlaylists = getPlaylists; exports.getPlaylists = getPlaylists;
exports.getPlaylist = getPlaylist; exports.getPlaylist = getPlaylist;
exports.getDirectory = getDirectory; exports.getDirectory = getDirectory;
@ -1579,6 +1580,13 @@
}; };
} }
function setTimePosition(time_position) {
return {
type: 'MOPIDY_TIMEPOSITION',
data: time_position
};
}
/** /**
* Asset-oriented actions * Asset-oriented actions
**/ **/
@ -11432,7 +11440,7 @@
/* 101 */ /* 101 */
/***/ function(module, exports, __webpack_require__) { /***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;var require;/* WEBPACK VAR INJECTION */(function(process) {/** @license MIT License (c) copyright 2010-2014 original author or authors */ var require;var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(process) {/** @license MIT License (c) copyright 2010-2014 original author or authors */
/** @author Brian Cavalier */ /** @author Brian Cavalier */
/** @author John Hann */ /** @author John Hann */
@ -11890,27 +11898,28 @@
value: function componentDidMount() { value: function componentDidMount() {
var _this2 = this; var _this2 = this;
if (this.props.mopidy.connected && this.props.mopidy.state == 'playing') { var interval_counter = 0;
this.setState({ animating: true });
}
setInterval(function () { setInterval(function () {
_this2.updateProgress(); if (_this2.props.mopidy.state == 'playing') {
}, 10000);
} // every 10 seconds get real position from Mopidy
}, { if (interval_counter % 10 == 0) {
key: 'componentWillReceiveProps', _this2.updateProgress();
value: function componentWillReceiveProps(nextProps) { } else {
if (this.state.animating && nextProps.mopidy.state != 'playing') { var time_position = _this2.props.mopidy.time_position;
this.setState({ animating: false });
console.log('stop animating'); // doesn't work? // only add 600ms every 1000ms as Mopidy's time tracker is a bit shit
} _this2.props.mopidyActions.setTimePosition(time_position + 600);
}
interval_counter++;
}
}, 1000);
} }
}, { }, {
key: 'updateProgress', key: 'updateProgress',
value: function updateProgress() { value: function updateProgress() {
if (this.props.mopidy.connected && this.props.mopidy.state == 'playing') { if (this.props.mopidy.connected && this.props.mopidy.state == 'playing') {
this.setState({ animating: true });
this.props.mopidyActions.getTimePosition(); this.props.mopidyActions.getTimePosition();
} }
} }
@ -11935,8 +11944,6 @@
value: function render() { value: function render() {
var _this3 = this; var _this3 = this;
var className = 'slider horizontal';
if (this.state.animating) className += ' animating';
var percent = 0; var percent = 0;
if (this.props.mopidy.connected && typeof this.props.mopidy.current_tltrack !== 'undefined' && typeof this.props.mopidy.current_tltrack.track !== 'undefined') { if (this.props.mopidy.connected && typeof this.props.mopidy.current_tltrack !== 'undefined' && typeof this.props.mopidy.current_tltrack.track !== 'undefined') {
percent = this.props.mopidy.time_position / this.props.mopidy.current_tltrack.track.length; percent = this.props.mopidy.time_position / this.props.mopidy.current_tltrack.track.length;
@ -11946,7 +11953,7 @@
return _react2.default.createElement( return _react2.default.createElement(
'div', 'div',
{ className: className, onClick: function onClick(e) { { className: 'slider horizontal', onClick: function onClick(e) {
return _this3.handleClick(e); return _this3.handleClick(e);
} }, } },
_react2.default.createElement( _react2.default.createElement(
@ -18687,6 +18694,16 @@
'div', 'div',
{ className: 'player' }, { className: 'player' },
artwork, artwork,
_react2.default.createElement(
'div',
{ className: 'current-track' },
_react2.default.createElement(
'div',
{ className: 'title' },
mopidy_track ? mopidy_track.track.name : null
),
mopidy_track ? _react2.default.createElement(_ArtistSentence2.default, { artists: mopidy_track.track.artists }) : null
),
_react2.default.createElement( _react2.default.createElement(
'div', 'div',
{ className: 'controls cf' }, { className: 'controls cf' },
@ -18727,16 +18744,7 @@
this.renderRepeatButton() this.renderRepeatButton()
) )
), ),
_react2.default.createElement( _react2.default.createElement(_ProgressSlider2.default, null)
'div',
{ className: 'current-track' },
_react2.default.createElement(
'div',
{ className: 'title' },
mopidy_track ? mopidy_track.track.name : null
),
mopidy_track ? _react2.default.createElement(_ArtistSentence2.default, { artists: mopidy_track.track.artists }) : null
)
); );
} }
}]); }]);

File diff suppressed because one or more lines are too long

View File

@ -80,6 +80,11 @@ class FullPlayer extends React.Component{
{ artwork } { artwork }
<div className="current-track">
<div className="title">{ mopidy_track ? mopidy_track.track.name : null }</div>
{ mopidy_track ? <ArtistSentence artists={ mopidy_track.track.artists } /> : null }
</div>
<div className="controls cf"> <div className="controls cf">
<div className="pull-left"> <div className="pull-left">
<a onClick={() => this.props.mopidyActions.previous()}> <a onClick={() => this.props.mopidyActions.previous()}>
@ -100,10 +105,8 @@ class FullPlayer extends React.Component{
</div> </div>
</div> </div>
<div className="current-track"> <ProgressSlider />
<div className="title">{ mopidy_track ? mopidy_track.track.name : null }</div>
{ mopidy_track ? <ArtistSentence artists={ mopidy_track.track.artists } /> : null }
</div>
</div> </div>
); );
} }

View File

@ -17,26 +17,27 @@ class ProgressSlider extends React.Component{
} }
componentDidMount(){ componentDidMount(){
var interval_counter = 0
if( this.props.mopidy.connected && this.props.mopidy.state == 'playing' ){
this.setState({ animating: true })
}
setInterval(() => { setInterval(() => {
this.updateProgress() if( this.props.mopidy.state == 'playing' ){
}, 10000);
}
componentWillReceiveProps( nextProps ){ // every 10 seconds get real position from Mopidy
if( this.state.animating && nextProps.mopidy.state != 'playing' ){ if( interval_counter % 10 == 0 ){
this.setState({ animating: false }) this.updateProgress()
console.log('stop animating') // doesn't work? }else{
} var time_position = this.props.mopidy.time_position
// only add 600ms every 1000ms as Mopidy's time tracker is a bit shit
this.props.mopidyActions.setTimePosition( time_position + 600 )
}
interval_counter++
}
}, 1000);
} }
updateProgress(){ updateProgress(){
if( this.props.mopidy.connected && this.props.mopidy.state == 'playing' ){ if( this.props.mopidy.connected && this.props.mopidy.state == 'playing' ){
this.setState({ animating: true })
this.props.mopidyActions.getTimePosition() this.props.mopidyActions.getTimePosition()
} }
} }
@ -57,8 +58,6 @@ class ProgressSlider extends React.Component{
} }
render(){ render(){
var className = 'slider horizontal'
if( this.state.animating ) className += ' animating'
var percent = 0 var percent = 0
if( this.props.mopidy.connected && typeof(this.props.mopidy.current_tltrack) !== 'undefined' && typeof(this.props.mopidy.current_tltrack.track) !== 'undefined' ){ if( this.props.mopidy.connected && typeof(this.props.mopidy.current_tltrack) !== 'undefined' && typeof(this.props.mopidy.current_tltrack.track) !== 'undefined' ){
percent = this.props.mopidy.time_position / this.props.mopidy.current_tltrack.track.length percent = this.props.mopidy.time_position / this.props.mopidy.current_tltrack.track.length
@ -67,7 +66,7 @@ class ProgressSlider extends React.Component{
} }
return ( return (
<div className={className} onClick={ (e) => this.handleClick(e) } > <div className='slider horizontal' onClick={ (e) => this.handleClick(e) } >
<div className="track"> <div className="track">
<div className="progress" style={{ width: (percent)+'%' }}></div> <div className="progress" style={{ width: (percent)+'%' }}></div>
</div> </div>

View File

@ -1,19 +0,0 @@
/**
* Actions and Action Creators
**/
export function shiftKey( down ){
return {
type: 'SHIFT_KEY',
down: down
}
}
export function ctrlKey( down ){
return {
type: 'CTRL_KEY',
down: down
}
}

View File

@ -1,18 +0,0 @@
export default function reducer(keyboard = {}, action){
console.log(action);
switch (action.type) {
case 'SHIFT_KEY':
return Object.assign({}, keyboard, { shift: action.down });
case 'CTRL_KEY':
return Object.assign({}, keyboard, { ctrl: action.down });
default:
return keyboard
}
}

View File

@ -112,6 +112,13 @@ export function getTimePosition(){
} }
} }
export function setTimePosition( time_position ){
return {
type: 'MOPIDY_TIMEPOSITION',
data: time_position
}
}
/** /**

View File

@ -11,6 +11,7 @@
@import 'components/images'; @import 'components/images';
@import 'components/icon'; @import 'components/icon';
@import 'components/search-form'; @import 'components/search-form';
@import 'components/slider';
@import 'components/player'; @import 'components/player';
@import 'components/sidebar'; @import 'components/sidebar';
@import 'components/lists'; @import 'components/lists';

View File

@ -0,0 +1,53 @@
.slider {
position: relative;
cursor: pointer;
.track {
position: absolute;
background: rgba(255,255,255,0.3);
@include animate()
.progress {
position: absolute;
background: $turquoise;
pointer-events: none;
left: 0;
}
}
&.horizontal {
margin: 10px 0;
height: 20px;
.track {
height: 2px;
top: 9px;
right: 0;
left: 0;
.progress {
top: 0;
height: 100%;
}
}
}
&.vertical {
margin: 10px 0;
width: 20px;
height: 100%;
.track {
width: 2px;
top: 0;
bottom: 0;
left: 9px;
.progress {
bottom: 0;
width: 100%;
}
}
}
}

View File

@ -102,55 +102,3 @@ label {
} }
} }
.slider {
position: relative;
cursor: pointer;
.track {
position: absolute;
background: rgba(255,255,255,0.3);
@include animate()
.progress {
position: absolute;
background: $turquoise;
pointer-events: none;
left: 0;
}
}
&.horizontal {
margin: 10px 0;
height: 20px;
.track {
height: 2px;
top: 9px;
right: 0;
left: 0;
.progress {
top: 0;
height: 100%;
}
}
}
&.vertical {
margin: 10px 0;
width: 20px;
height: 100%;
.track {
width: 2px;
top: 0;
bottom: 0;
left: 9px;
.progress {
bottom: 0;
width: 100%;
}
}
}
}

View File

@ -11,7 +11,8 @@
} }
.artwork, .artwork,
.controls { .controls,
.slider {
display: block; display: block;
max-width: 400px; max-width: 400px;
margin: 0 auto; margin: 0 auto;
@ -29,7 +30,14 @@
} }
.current-track { .current-track {
padding: 20px 0 0 0;
font-weight: 700; font-weight: 700;
} }
.slider {
.track {
background: rgba(0,0,0,0.2);
}
}
} }
} }