Move Position to react/redux

This commit is contained in:
Jordan Eldredge 2016-07-22 08:11:09 -07:00
parent f6df92fb29
commit 1965879bcd
5 changed files with 89 additions and 57 deletions

View file

@ -364,6 +364,11 @@
#winamp2-js .stop #position::-webkit-slider-thumb { visibility: hidden; }
#winamp2-js .stop #position::-moz-range-thumb { visibility: hidden; }
/* For some reason this is needed for the position slider to show up now that
* we are using React.
*/
#winamp2-js .play #position::-webkit-slider-thumb { visibility: visible; }
#winamp2-js .actions div {
height: 18px;
width: 23px;

77
js/Position.jsx Normal file
View file

@ -0,0 +1,77 @@
// Single line text display that can animate and hold multiple registers
import React from 'react';
import {connect} from 'react-redux';
import {getTimeStr} from './utils';
class Position extends React.Component {
constructor(props) {
super(props);
// Consider moving to global state. Currently nobody else cares.
this.state = {
mouseIsDown: false,
currentPosition: 0
};
this.setPosition = this.setPosition.bind(this);
this.showMarquee = this.showMarquee.bind(this);
this.hideMarquee = this.hideMarquee.bind(this);
this.onMouseUp = this.onMouseUp.bind(this);
}
setPosition(e) {
this.props.dispatch({type: 'SHOW_MARQUEE_REGISTER', register: 'message'});
this.setState({
mouseIsDown: true,
currentPosition: e.target.value
});
var newPercentComplete = e.target.value;
var newElapsed = getTimeStr(this.props.length * newPercentComplete / 100);
var duration = getTimeStr(this.props.length);
var message = `Seek to: ${newElapsed}/${duration} (${newPercentComplete}%)`;
this.props.dispatch({type: 'SET_MARQUEE_REGISTER', register: 'message', text: message});
}
onMouseUp(e) {
this.props.dispatch({type: 'SHOW_MARQUEE_REGISTER', register: 'songTitle'});
this.props.dispatch({type: 'SET_POSITION', position: e.target.value});
this.setState({mouseIsDown: false});
}
showMarquee() {
}
hideMarquee() {
}
render() {
const position = this.props.length ?
(this.props.timeElapsed / this.props.length) * 100 :
0;
// In shade mode, the position slider shows up differently depending on if
// it's near the start, middle or end of its progress
let className = '';
if (position <= 33) {
className = 'left';
} else if (position >= 66) {
className = 'right';
}
const displayedPosition = this.state.mouseIsDown ? this.state.currentPosition : position;
return <input
id='position'
className={className}
type='range'
min='0'
max='100'
step='1'
value={displayedPosition}
onChange={this.change}
onInput={this.setPosition}
onMouseUp={this.onMouseUp}
onMouseDown={this.setPosition}
/>;
}
}
module.exports = connect(state => state.media)(Position);

View file

@ -58,7 +58,7 @@ module.exports = el('div', {id: 'main-window', class: 'loading stop'}, [
el('div', {id: 'equalizer-button'}),
el('div', {id: 'playlist-button'})
]),
el('input', {id: 'position', type: 'range', min: '0', max: '100', step: '1', value: '0'}),
el('div', {id: 'position-holder'}),
el('div', {id: 'actions-holder'}),
el('div', {id: 'eject'}),
el('div', {class: 'shuffle-repeat'}, [

View file

@ -7,6 +7,7 @@ import Kbps from './Kbps.jsx';
import Khz from './Khz.jsx';
import Volume from './Volume.jsx';
import Balance from './Balance.jsx';
import Position from './Position.jsx';
import '../css/main-window.css';
@ -17,7 +18,6 @@ module.exports = {
close: document.getElementById('close'),
shade: document.getElementById('shade'),
buttonD: document.getElementById('button-d'),
position: document.getElementById('position'),
visualizer: document.getElementById('visualizer'),
eject: document.getElementById('eject'),
repeat: document.getElementById('repeat'),
@ -40,6 +40,7 @@ module.exports = {
this.winamp.renderTo(<Khz />, document.getElementById('khz-holder'));
this.winamp.renderTo(<Volume />, document.getElementById('volume-holder'));
this.winamp.renderTo(<Balance />, document.getElementById('balance-holder'));
this.winamp.renderTo(<Position />, document.getElementById('position-holder'));
this._registerListeners();
return this;
@ -73,33 +74,6 @@ module.exports = {
self.winamp.toggleDoubledMode();
};
this.nodes.position.onmousedown = function() {
if (!self.nodes.window.classList.contains('stop')){
self.winamp.dispatch({type: 'SHOW_MARQUEE_REGISTER', register: 'position'});
self.nodes.window.classList.add('setting-position');
}
};
this.nodes.position.onmouseup = function() {
self.winamp.dispatch({type: 'SHOW_MARQUEE_REGISTER', register: 'songTitle'});
self.nodes.window.classList.remove('setting-position');
};
this.nodes.position.oninput = function() {
var newPercentComplete = self.nodes.position.value;
var newFractionComplete = newPercentComplete / 100;
var newElapsed = self._timeString(self.winamp.getDuration() * newFractionComplete);
var duration = self._timeString(self.winamp.getDuration());
var message = 'Seek to: ' + newElapsed + '/' + duration + ' (' + newPercentComplete + '%)';
self.winamp.dispatch({type: 'SET_MARQUEE_REGISTER', register: 'message', text: message});
};
this.nodes.position.onchange = function() {
if (self.winamp.getState() !== 'stop'){
self.winamp.seekToPercentComplete(this.value);
}
};
this.nodes.eject.onclick = function() {
self.winamp.dispatch({type: 'OPEN_FILE_DIALOG'});
};
@ -116,9 +90,6 @@ module.exports = {
self.winamp.toggleVisualizer();
};
window.addEventListener('timeUpdated', function() {
self.updateTime();
});
window.addEventListener('startWaiting', function() {
self.setWorkingIndicator();
});
@ -167,30 +138,6 @@ module.exports = {
this.nodes.window.classList.add('closed');
},
updatePosition: function() {
if (!this.nodes.window.classList.contains('setting-position')) {
this.nodes.position.value = this.winamp.getPercentComplete();
}
},
// In shade mode, the position slider shows up differently depending on if
// it's near the start, middle or end of its progress
updateShadePositionClass: function() {
var position = this.nodes.position;
position.removeAttribute('class');
if (position.value <= 33) {
position.classList.add('left');
} else if (position.value >= 66) {
position.classList.add('right');
}
},
updateTime: function() {
this.updateShadePositionClass();
this.updatePosition();
},
setWorkingIndicator: function() {
this.nodes.workIndicator.classList.add('selected');
},

View file

@ -91,7 +91,7 @@ const media = (state, action) => {
return {
timeMode: 'ELAPSED',
timeElapsed: 0,
length: null,
length: null, // Consider renaming to "duration"
kbps: null,
khz: null,
volume: 50,
@ -146,6 +146,9 @@ const createReducer = (winamp) => {
case 'SET_BALANCE':
winamp.setBalance(action.balance);
return state;
case 'SET_POSITION':
winamp.seekToPercentComplete(action.position);
return state;
case 'CLOSE_WINAMP':
winamp.close();
return state;