Introduce Redux

This commit is contained in:
Jordan Eldredge 2016-07-09 14:19:50 -07:00
parent 65de47414d
commit 060aafef65
4 changed files with 63 additions and 19 deletions

View file

@ -1,15 +1,11 @@
import React from 'react';
import MyFile from './my-file';
import {connect} from 'react-redux';
import '../css/context-menu.css';
class ContextMenu extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: false
};
this.openFileDialog = this.openFileDialog.bind(this);
this.close = this.close.bind(this);
this.toggleMenu = this.toggleMenu.bind(this);
@ -27,34 +23,30 @@ class ContextMenu extends React.Component {
}
openFileDialog() {
this.props.winamp.openFileDialog();
this.props.dispatch({type: 'OPEN_FILE_DIALOG'});
}
close() {
// Close all of Winamp
this.props.winamp.close();
this.props.dispatch({type: 'CLOSE_WINAMP'});
}
closeMenu() {
this.setState({selected: false});
this.props.dispatch({type: 'CLOSE_CONTEXT_MENU'});
}
toggleMenu(event) {
this.setState({selected: !this.state.selected});
this.props.dispatch({type: 'TOGGLE_CONTEXT_MENU'});
event.stopPropagation();
}
setSkin(e) {
const filename = e.target.dataset.filename;
const url = 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/' + filename;
const skinFile = new MyFile();
skinFile.setUrl(url);
this.props.winamp.setSkin(skinFile);
this.props.dispatch({type: 'SET_SKIN_FROM_URL', url: url});
}
render() {
var classes = this.state.selected ? 'selected' : '';
var classes = this.props.selected ? 'selected' : '';
return <div id='option' className={classes} onClick={this.toggleMenu}>
<ul id='context-menu'>
<li><a href='https://github.com/captbaritone/winamp2-js' target='_blank'>Winamp2-js...</a></li>
@ -80,4 +72,4 @@ class ContextMenu extends React.Component {
}
}
module.exports = ContextMenu;
module.exports = connect(state => state.contextMenu)(ContextMenu);

View file

@ -1,5 +1,9 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {createStore} from 'redux';
import createReducer from './reducers';
import Browser from './browser';
import mainWindowDom from './main-window-dom';
@ -25,8 +29,15 @@ if (new Browser(window).isCompatible) {
skinUrl: 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91.wsz'
});
let store = createStore(createReducer(winamp));
new Hotkeys(winamp);
ReactDOM.render(<ContextMenu winamp={winamp} />, document.getElementById('context-menu-holder'));
render(
<Provider store={store}>
<ContextMenu winamp={winamp} />
</Provider>,
document.getElementById('context-menu-holder')
);
} else {
document.getElementById('winamp').style.display = 'none';
document.getElementById('browser-compatibility').style.display = 'block';

39
js/reducers.js Normal file
View file

@ -0,0 +1,39 @@
import MyFile from './my-file';
const createReducer = (winamp) => {
const reducers = (state, action) => {
if (!state) {
return {
contextMenu: {
selected: false
}
};
}
switch (action.type) {
case 'TOGGLE_CONTEXT_MENU':
return Object.assign({}, state, {contextMenu: {selected: !state.contextMenu.selected}});
case 'CLOSE_CONTEXT_MENU':
return Object.assign({}, state, {contextMenu: {selected: false}});
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;
default:
return state;
}
};
return reducers;
};
export default createReducer;

View file

@ -43,6 +43,8 @@
"babel-plugin-transform-react-jsx": "^6.8.0",
"jszip": "^2.6.0",
"react": "^15.2.0",
"react-dom": "^15.2.0"
"react-dom": "^15.2.0",
"react-redux": "^4.4.5",
"redux": "^3.5.2"
}
}