mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-24 02:27:37 +00:00
Move to thunks. Use display state from store (#164)
This commit is contained in:
parent
336a888eb4
commit
1e49d0a908
13 changed files with 166 additions and 185 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {play, pause, stop} from './actionCreators';
|
||||
|
||||
|
||||
class Actions extends React.Component {
|
||||
|
|
@ -10,13 +11,13 @@ class Actions extends React.Component {
|
|||
this.stop = this.stop.bind(this);
|
||||
}
|
||||
play() {
|
||||
this.props.dispatch({type: 'PLAY'});
|
||||
this.props.dispatch(play(this.props.mediaPlayer));
|
||||
}
|
||||
pause() {
|
||||
this.props.dispatch({type: 'PAUSE'});
|
||||
this.props.dispatch(pause(this.props.mediaPlayer));
|
||||
}
|
||||
stop() {
|
||||
this.props.dispatch({type: 'STOP'});
|
||||
this.props.dispatch(stop(this.props.mediaPlayer));
|
||||
}
|
||||
render() {
|
||||
return <div className='actions'>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {close} from './actionCreators';
|
||||
|
||||
|
||||
class Close extends React.Component {
|
||||
constructor(props) {
|
||||
|
|
@ -8,7 +10,7 @@ class Close extends React.Component {
|
|||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'CLOSE'});
|
||||
this.props.dispatch(close(this.props.mediaPlayer));
|
||||
}
|
||||
render() {
|
||||
return <div
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {close, setSkinFromFilename} from './actionCreators';
|
||||
|
||||
import '../css/context-menu.css';
|
||||
|
||||
class ContextMenu extends React.Component {
|
||||
|
|
@ -27,7 +29,7 @@ class ContextMenu extends React.Component {
|
|||
}
|
||||
|
||||
close() {
|
||||
this.props.dispatch({type: 'CLOSE_WINAMP'});
|
||||
this.props.dispatch(close(this.props.mediaPlayer));
|
||||
}
|
||||
|
||||
closeMenu() {
|
||||
|
|
@ -40,9 +42,7 @@ class ContextMenu extends React.Component {
|
|||
}
|
||||
|
||||
setSkin(e) {
|
||||
const filename = e.target.dataset.filename;
|
||||
const url = 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/' + filename;
|
||||
this.props.dispatch({type: 'SET_SKIN_FROM_URL', url: url});
|
||||
setSkinFromFilename(this.props.winamp, e.target.dataset.filename);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import Actions from './Actions.jsx';
|
||||
import Balance from './Balance.jsx';
|
||||
|
|
@ -11,6 +13,7 @@ import Marquee from './Marquee.jsx';
|
|||
import MonoStereo from './MonoStereo.jsx';
|
||||
import Position from './Position.jsx';
|
||||
import Repeat from './Repeat.jsx';
|
||||
import Shade from './Shade.jsx';
|
||||
import ShadeTime from './ShadeTime.jsx';
|
||||
import Shuffle from './Shuffle.jsx';
|
||||
import Time from './Time.jsx';
|
||||
|
|
@ -18,14 +21,28 @@ import Volume from './Volume.jsx';
|
|||
|
||||
import '../css/main-window.css';
|
||||
|
||||
const MainWindow = () => {
|
||||
return <div id='main-window' className='loading stop'>
|
||||
const MainWindow = (props) => {
|
||||
const {status} = props.media;
|
||||
const {loading, doubled, shade, closed, llama} = props.display;
|
||||
|
||||
const className = classnames({
|
||||
// TODO: Handle these status changes in the individual components
|
||||
play: status === 'PLAYING',
|
||||
stop: status === 'STOPPED',
|
||||
pause: status === 'PAUSED',
|
||||
loading,
|
||||
doubled,
|
||||
llama,
|
||||
shade,
|
||||
closed
|
||||
});
|
||||
return <div id='main-window' className={className}>
|
||||
<div id='loading'>Loading...</div>
|
||||
<div id='title-bar' className='selected'>
|
||||
<ContextMenu />
|
||||
<ContextMenu mediaPlayer={props.mediaPlayer} winamp={props.winamp} />
|
||||
<ShadeTime />
|
||||
<div id='minimize'></div>
|
||||
<div id='shade'></div>
|
||||
<Shade />
|
||||
<Close />
|
||||
</div>
|
||||
<div className='status'>
|
||||
|
|
@ -33,11 +50,11 @@ const MainWindow = () => {
|
|||
<div id='button-o'></div>
|
||||
<div id='button-a'></div>
|
||||
<div id='button-i'></div>
|
||||
<div id='button-d'></div>
|
||||
<div id='button-d' className={props.display.doubled ? 'selected' : ''}></div>
|
||||
<div id='button-v'></div>
|
||||
</div>
|
||||
<div id='play-pause'></div>
|
||||
<div id='work-indicator'></div>
|
||||
<div id='work-indicator' className={props.display.working ? 'selected' : ''}></div>
|
||||
<Time />
|
||||
<canvas id='visualizer' width='152' height='32'></canvas>
|
||||
</div>
|
||||
|
|
@ -53,8 +70,8 @@ const MainWindow = () => {
|
|||
<div id='equalizer-button'></div>
|
||||
<div id='playlist-button'></div>
|
||||
</div>
|
||||
<Position />
|
||||
<Actions />
|
||||
<Position mediaPlayer={props.mediaPlayer} />
|
||||
<Actions mediaPlayer={props.mediaPlayer} />
|
||||
<Eject />
|
||||
<div className='shuffle-repeat'>
|
||||
<Shuffle />
|
||||
|
|
@ -64,4 +81,4 @@ const MainWindow = () => {
|
|||
</div>;
|
||||
};
|
||||
|
||||
module.exports = MainWindow;
|
||||
module.exports = connect(state => state)(MainWindow);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class Position extends React.Component {
|
|||
}
|
||||
|
||||
onMouseUp(e) {
|
||||
this.props.dispatch({type: 'SET_POSITION', position: e.target.value});
|
||||
this.props.mediaPlayer.seekToPercentComplete(e.target.value);
|
||||
this.props.dispatch({type: 'UNSET_FOCUS'});
|
||||
}
|
||||
|
||||
|
|
|
|||
20
js/Shade.jsx
Normal file
20
js/Shade.jsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
class Shade extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
handleClick() {
|
||||
this.props.dispatch({type: 'TOGGLE_SHADE_MODE'});
|
||||
}
|
||||
render() {
|
||||
return <div
|
||||
id='shade'
|
||||
onClick={this.handleClick}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = connect()(Shade);
|
||||
51
js/actionCreators.js
Normal file
51
js/actionCreators.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import MyFile from './my-file';
|
||||
|
||||
export function play(mediaPlayer) {
|
||||
return (dispatch, getState) => {
|
||||
if (getState().media.status === 'PLAYING') {
|
||||
mediaPlayer.stop();
|
||||
dispatch({type: 'MEDIA_IS_STOPPED'});
|
||||
} else {
|
||||
mediaPlayer.play();
|
||||
dispatch({type: 'MEDIA_IS_PLAYING'});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function pause(mediaPlayer) {
|
||||
return (dispatch, getState) => {
|
||||
const status = getState().media.status;
|
||||
switch (status) {
|
||||
case 'PAUSED':
|
||||
mediaPlayer.play();
|
||||
dispatch({type: 'MEDIA_IS_PLAYING'});
|
||||
break;
|
||||
case 'PLAYING':
|
||||
mediaPlayer.pause();
|
||||
dispatch({type: 'MEDIA_IS_PAUSED'});
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function stop(mediaPlayer) {
|
||||
return (dispatch) => {
|
||||
mediaPlayer.stop();
|
||||
dispatch({type: 'MEDIA_IS_STOPPED'});
|
||||
};
|
||||
}
|
||||
|
||||
export function close(mediaPlayer) {
|
||||
return (dispatch) => {
|
||||
mediaPlayer.stop();
|
||||
dispatch({type: 'CLOSE_WINAMP'});
|
||||
};
|
||||
}
|
||||
|
||||
export function setSkinFromFilename(winamp, filename) {
|
||||
const url = `https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/${filename}`;
|
||||
const skinFile = new MyFile();
|
||||
skinFile.setUrl(url);
|
||||
winamp.setSkin(skinFile);
|
||||
return {type: 'START_LOADING'};
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import {play, pause, stop} from './actionCreators';
|
||||
|
||||
module.exports = function(winamp, store) {
|
||||
var keylog = [];
|
||||
var trigger = [78, 85, 76, 27, 76, 27, 83, 79, 70, 84];
|
||||
|
|
@ -26,13 +28,16 @@ module.exports = function(winamp, store) {
|
|||
store.dispatch({type: 'SET_VOLUME', volume: decrementedVolume});
|
||||
break;
|
||||
case 66: winamp.next(); break; // B
|
||||
case 67: winamp.pause(); break; // C
|
||||
// C
|
||||
case 67: winamp.dispatch(pause(winamp.media)); break;
|
||||
// L
|
||||
case 76: store.dispatch({type: 'OPEN_FILE_DIALOG'}); break;
|
||||
case 82: winamp.toggleRepeat(); break; // R
|
||||
case 83: winamp.toggleShuffle(); break; // S
|
||||
case 86: winamp.stop(); break; // V
|
||||
case 88: winamp.play(); break; // X
|
||||
// V
|
||||
case 86: winamp.dispatch(stop(winamp.media)); break;
|
||||
// X
|
||||
case 88: winamp.dispatch(play(winamp.media)); break;
|
||||
case 90: winamp.previous(); break; // Z
|
||||
// numpad 0
|
||||
case 96: store.dispatch({type: 'OPEN_FILE_DIALOG'}); break;
|
||||
|
|
@ -40,7 +45,8 @@ module.exports = function(winamp, store) {
|
|||
case 98: winamp.incrementVolumeBy(-1); break; // numpad 2
|
||||
case 99: winamp.next(10); break; // numpad 3
|
||||
case 100: winamp.previous(); break; // numpad 4
|
||||
case 101: winamp.play(); break; // numpad 5
|
||||
// numpad 5
|
||||
case 101: winamp.dispatch(play(winamp.media)); break;
|
||||
case 102: winamp.next(); break; // numpad 6
|
||||
case 103: winamp.seekForwardBy(-5); break; // numpad 7
|
||||
case 104: winamp.incrementVolumeBy(1); break; // numpad 8
|
||||
|
|
@ -52,7 +58,7 @@ module.exports = function(winamp, store) {
|
|||
keylog.push(e.keyCode);
|
||||
keylog = keylog.slice(-10);
|
||||
if (keylog.toString() === trigger.toString()) {
|
||||
winamp.toggleLlama();
|
||||
winamp.dispatch({type: 'TOGGLE_LLAMA_MODE'});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ module.exports = {
|
|||
init: function(winamp) {
|
||||
this.winamp = winamp;
|
||||
this.nodes = {
|
||||
shade: document.getElementById('shade'),
|
||||
buttonD: document.getElementById('button-d'),
|
||||
visualizer: document.getElementById('visualizer'),
|
||||
workIndicator: document.getElementById('work-indicator'),
|
||||
|
|
@ -19,10 +18,6 @@ module.exports = {
|
|||
_registerListeners: function() {
|
||||
var self = this;
|
||||
|
||||
this.nodes.shade.onclick = function() {
|
||||
self.nodes.window.classList.toggle('shade');
|
||||
};
|
||||
|
||||
this.nodes.buttonD.onmousedown = function() {
|
||||
self.winamp.dispatch({type: 'SET_FOCUS', input: 'double'});
|
||||
};
|
||||
|
|
@ -36,70 +31,11 @@ module.exports = {
|
|||
self.winamp.toggleVisualizer();
|
||||
};
|
||||
|
||||
window.addEventListener('startWaiting', function() {
|
||||
self.setWorkingIndicator();
|
||||
});
|
||||
window.addEventListener('stopWaiting', function() {
|
||||
self.unsetWorkingIndicator();
|
||||
});
|
||||
window.addEventListener('startLoading', function() {
|
||||
self.setLoadingState();
|
||||
});
|
||||
window.addEventListener('stopLoading', function() {
|
||||
self.unsetLoadingState();
|
||||
});
|
||||
window.addEventListener('changeState', function() {
|
||||
self.changeState();
|
||||
});
|
||||
window.addEventListener('doubledModeToggled', function() {
|
||||
self.toggleDoubledMode();
|
||||
});
|
||||
window.addEventListener('llamaToggled', function() {
|
||||
self.toggleLlama();
|
||||
});
|
||||
window.addEventListener('close', function() {
|
||||
self.nodes.window.classList.add('closed');
|
||||
});
|
||||
|
||||
this.nodes.window.addEventListener('dragenter', this.dragenter.bind(this));
|
||||
this.nodes.window.addEventListener('dragover', this.dragover.bind(this));
|
||||
this.nodes.window.addEventListener('drop', this.drop.bind(this));
|
||||
},
|
||||
|
||||
toggleDoubledMode: function() {
|
||||
this.nodes.buttonD.classList.toggle('selected');
|
||||
this.nodes.window.classList.toggle('doubled');
|
||||
},
|
||||
|
||||
setWorkingIndicator: function() {
|
||||
this.nodes.workIndicator.classList.add('selected');
|
||||
},
|
||||
|
||||
unsetWorkingIndicator: function() {
|
||||
this.nodes.workIndicator.classList.remove('selected');
|
||||
},
|
||||
|
||||
setLoadingState: function() {
|
||||
this.nodes.window.classList.add('loading');
|
||||
},
|
||||
|
||||
unsetLoadingState: function() {
|
||||
this.nodes.window.classList.remove('loading');
|
||||
},
|
||||
|
||||
changeState: function() {
|
||||
var state = this.winamp.getState();
|
||||
var stateOptions = ['play', 'stop', 'pause'];
|
||||
for (var i = 0; i < stateOptions.length; i++) {
|
||||
this.nodes.window.classList.remove(stateOptions[i]);
|
||||
}
|
||||
this.nodes.window.classList.add(state);
|
||||
},
|
||||
|
||||
toggleLlama: function() {
|
||||
this.nodes.window.classList.toggle('llama');
|
||||
},
|
||||
|
||||
dragenter: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import {render} from 'react-dom';
|
||||
import {Provider} from 'react-redux';
|
||||
import {createStore} from 'redux';
|
||||
import {createStore, applyMiddleware} from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
import createReducer from './reducers';
|
||||
|
||||
|
|
@ -14,12 +15,13 @@ if (new Browser(window).isCompatible) {
|
|||
var winamp = Winamp;
|
||||
let store = createStore(
|
||||
createReducer(winamp),
|
||||
window.devToolsExtension && window.devToolsExtension()
|
||||
window.devToolsExtension && window.devToolsExtension(),
|
||||
applyMiddleware(thunk)
|
||||
);
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<MainWindow />
|
||||
<MainWindow winamp={winamp} mediaPlayer={winamp.media} />
|
||||
</Provider>,
|
||||
document.getElementById('winamp2-js')
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import MyFile from './my-file';
|
||||
import {combineReducers} from 'redux';
|
||||
|
||||
const userInput = (state, action) => {
|
||||
|
|
@ -24,15 +23,34 @@ const display = (state, action) => {
|
|||
if (!state) {
|
||||
return {
|
||||
doubled: false,
|
||||
marqueeStep: 0
|
||||
marqueeStep: 0,
|
||||
loading: true,
|
||||
llama: false,
|
||||
closed: false,
|
||||
shade: false,
|
||||
working: false
|
||||
};
|
||||
}
|
||||
switch (action.type) {
|
||||
case 'TOGGLE_DOUBLESIZE_MODE':
|
||||
return {...state, doubled: !state.doubled};
|
||||
case 'TOGGLE_SHADE_MODE':
|
||||
return {...state, shade: !state.shade};
|
||||
case 'TOGGLE_LLAMA_MODE':
|
||||
return {...state, llama: !state.llama};
|
||||
case 'STEP_MARQUEE':
|
||||
// TODO: Prevent this from becoming huge
|
||||
return {...state, marqueeStep: state.marqueeStep + 1};
|
||||
case 'STOP_WORKING':
|
||||
return {...state, working: false};
|
||||
case 'START_WORKING':
|
||||
return {...state, working: true};
|
||||
case 'STOP_LOADING':
|
||||
return {...state, loading: false};
|
||||
case 'START_LOADING':
|
||||
return {...state, loading: true};
|
||||
case 'CLOSE_WINAMP':
|
||||
return {...state, closed: true};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -67,7 +85,9 @@ const media = (state, action) => {
|
|||
name: '',
|
||||
channels: null,
|
||||
shuffle: false,
|
||||
repeat: false
|
||||
repeat: false,
|
||||
// TODO: Enforce possible values
|
||||
status: 'STOPPED'
|
||||
};
|
||||
}
|
||||
switch (action.type) {
|
||||
|
|
@ -94,6 +114,12 @@ const media = (state, action) => {
|
|||
return {...state, repeat: !state.repeat};
|
||||
case 'TOGGLE_SHUFFLE':
|
||||
return {...state, shuffle: !state.shuffle};
|
||||
case 'MEDIA_IS_PLAYING':
|
||||
return {...state, status: 'PLAYING'};
|
||||
case 'MEDIA_IS_PAUSED':
|
||||
return {...state, status: 'PAUSED'};
|
||||
case 'MEDIA_IS_STOPPED':
|
||||
return {...state, status: 'STOPPED'};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
@ -112,49 +138,22 @@ const createReducer = (winamp) => {
|
|||
return (state, action) => {
|
||||
state = reducer(state, action);
|
||||
switch (action.type) {
|
||||
case 'PLAY':
|
||||
winamp.play();
|
||||
return state;
|
||||
case 'PAUSE':
|
||||
winamp.pause();
|
||||
return state;
|
||||
case 'STOP':
|
||||
winamp.stop();
|
||||
return state;
|
||||
case 'SET_VOLUME':
|
||||
winamp.setVolume(action.volume);
|
||||
return state;
|
||||
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;
|
||||
case 'OPEN_FILE_DIALOG':
|
||||
// TODO: Figure out how to make this pure
|
||||
winamp.openFileDialog();
|
||||
return state;
|
||||
case 'SET_SKIN_FROM_URL':
|
||||
// TODO: Figure out how to make this pure
|
||||
const skinFile = new MyFile();
|
||||
skinFile.setUrl(action.url);
|
||||
winamp.setSkin(skinFile);
|
||||
return state;
|
||||
case 'TOGGLE_DOUBLESIZE_MODE':
|
||||
winamp.toggleDoubledMode();
|
||||
return state;
|
||||
case 'TOGGLE_REPEAT':
|
||||
winamp.toggleRepeat();
|
||||
return state;
|
||||
case 'TOGGLE_SHUFFLE':
|
||||
winamp.toggleShuffle();
|
||||
return state;
|
||||
case 'CLOSE':
|
||||
winamp.close();
|
||||
return state;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
|
|
|||
73
js/winamp.js
73
js/winamp.js
|
|
@ -8,28 +8,20 @@ import MyFile from './my-file';
|
|||
import '../css/winamp.css';
|
||||
|
||||
module.exports = {
|
||||
media: Media.init(),
|
||||
init: function(options) {
|
||||
this.fileInput = document.createElement('input');
|
||||
this.fileInput.type = 'file';
|
||||
this.fileInput.style.display = 'none';
|
||||
|
||||
this.windowManager = WindowManager;
|
||||
this.media = Media.init();
|
||||
this.skin = Skin.init(document.getElementById('visualizer'), this.media._analyser);
|
||||
this.state = '';
|
||||
|
||||
this.mainWindow = MainWindow.init(this);
|
||||
|
||||
this.events = {
|
||||
timeUpdated: new Event('timeUpdated'),
|
||||
startWaiting: new Event('startWaiting'),
|
||||
stopWaiting: new Event('stopWaiting'),
|
||||
startLoading: new Event('startLoading'),
|
||||
stopLoading: new Event('stopLoading'),
|
||||
changeState: new Event('changeState'),
|
||||
doubledModeToggled: new Event('doubledModeToggled'),
|
||||
llamaToggled: new Event('llamaToggled'),
|
||||
close: new Event('close')
|
||||
timeUpdated: new Event('timeUpdated')
|
||||
};
|
||||
|
||||
this.dispatch({type: 'SET_VOLUME', volume: options.volume});
|
||||
|
|
@ -60,19 +52,19 @@ module.exports = {
|
|||
|
||||
this.media.addEventListener('ended', function() {
|
||||
self.skin.visualizer.clear();
|
||||
self.setState('stop');
|
||||
self.dispatch({type: 'MEDIA_IS_STOPPED'});
|
||||
});
|
||||
|
||||
this.media.addEventListener('waiting', function() {
|
||||
window.dispatchEvent(self.events.startWaiting);
|
||||
self.dispatch({type: 'START_WORKING'});
|
||||
});
|
||||
|
||||
this.media.addEventListener('stopWaiting', function() {
|
||||
window.dispatchEvent(self.events.stopWaiting);
|
||||
self.dispatch({type: 'STOP_WORKING'});
|
||||
});
|
||||
|
||||
this.media.addEventListener('playing', function() {
|
||||
self.setState('play');
|
||||
self.dispatch({type: 'MEDIA_IS_PLAYING'});
|
||||
});
|
||||
|
||||
this.fileInput.onchange = function(e){
|
||||
|
|
@ -81,15 +73,6 @@ module.exports = {
|
|||
},
|
||||
|
||||
/* Functions */
|
||||
setState: function(state) {
|
||||
this.state = state;
|
||||
window.dispatchEvent(this.events.changeState);
|
||||
},
|
||||
|
||||
getState: function() {
|
||||
return this.state;
|
||||
},
|
||||
|
||||
getDuration: function() {
|
||||
return this.media.duration();
|
||||
},
|
||||
|
|
@ -110,27 +93,6 @@ module.exports = {
|
|||
this.media.seekToPercentComplete(percent);
|
||||
},
|
||||
|
||||
play: function() {
|
||||
if (this.getState() === 'play'){
|
||||
this.media.stop();
|
||||
}
|
||||
this.media.play();
|
||||
this.setState('play');
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
if (this.getState() === 'pause'){
|
||||
this.media.play();
|
||||
} else if (this.getState() === 'play') {
|
||||
this.media.pause();
|
||||
this.setState('pause');
|
||||
}
|
||||
},
|
||||
stop: function() {
|
||||
this.media.stop();
|
||||
this.setState('stop');
|
||||
},
|
||||
|
||||
// From 0-100
|
||||
setVolume: function(volume) {
|
||||
// Ensure volume does not go out of bounds
|
||||
|
|
@ -140,10 +102,6 @@ module.exports = {
|
|||
this.media.setVolume(volume);
|
||||
},
|
||||
|
||||
toggleDoubledMode: function() {
|
||||
window.dispatchEvent(this.events.doubledModeToggled);
|
||||
},
|
||||
|
||||
// From -100 to 100
|
||||
setBalance: function(balance) {
|
||||
this.media.setBalance(balance);
|
||||
|
|
@ -162,14 +120,9 @@ module.exports = {
|
|||
this.media.toggleShuffle();
|
||||
},
|
||||
|
||||
toggleLlama: function() {
|
||||
window.dispatchEvent(this.events.llamaToggled);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
window.dispatchEvent(this.events.close);
|
||||
this.media.stop();
|
||||
this.setState('stop'); // Currently unneeded
|
||||
this.dispatch({type: 'MEDIA_IS_STOPPED'});
|
||||
},
|
||||
|
||||
openFileDialog: function() {
|
||||
|
|
@ -201,16 +154,8 @@ module.exports = {
|
|||
},
|
||||
|
||||
setSkin: function(file) {
|
||||
this.setLoadingState();
|
||||
this.skin.setSkinByFile(file, this.unsetLoadingState.bind(this));
|
||||
},
|
||||
|
||||
setLoadingState: function() {
|
||||
window.dispatchEvent(this.events.startLoading);
|
||||
},
|
||||
|
||||
unsetLoadingState: function() {
|
||||
window.dispatchEvent(this.events.stopLoading);
|
||||
this.dispatch({type: 'START_LOADING'});
|
||||
this.skin.setSkinByFile(file, () => this.dispatch({type: 'STOP_LOADING'}));
|
||||
},
|
||||
|
||||
toggleVisualizer: function() {
|
||||
|
|
|
|||
|
|
@ -49,10 +49,12 @@
|
|||
"dependencies": {
|
||||
"babel-plugin-transform-object-rest-spread": "^6.8.0",
|
||||
"babel-plugin-transform-react-jsx": "^6.8.0",
|
||||
"classnames": "^2.2.5",
|
||||
"jszip": "^2.6.0",
|
||||
"react": "^15.2.0",
|
||||
"react-dom": "^15.2.0",
|
||||
"react-redux": "^4.4.5",
|
||||
"redux": "^3.5.2"
|
||||
"redux": "^3.5.2",
|
||||
"redux-thunk": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue