commit ef50743c5318b2b7b21fff1e6fed3733b1a18be1
parent 80c4fff633a31a6cf0b5b45fe0c63c17de686c55
Author: Massimo Siboldi <mdsiboldi@gmail.com>
Date: Thu, 8 Mar 2018 21:54:44 -0800
Add more global state to redux.
Diffstat:
3 files changed, 27 insertions(+), 20 deletions(-)
diff --git a/src/App/index.js b/src/App/index.js
@@ -100,8 +100,6 @@ class App extends Component {
super();
let initBeats = 4;
this.state = {
- beat: 0,
- playing: false,
tones: [{
active: true,
waveform: initialWave.slice(),
@@ -137,7 +135,7 @@ class App extends Component {
hasSolo = true;
group = 'solo';
}
- if (!this.state.playing || val.beats[this.state.beat]) {
+ if (!this.props.playing || val.beats[this.props.beat]) {
if (!val.mute) {
accum[group].push(val);
}
@@ -228,26 +226,25 @@ class App extends Component {
})
}
+ //TODO this could be part of the reducer, and sending PLAY action can start it. Wonder how that can be done without side effects? Or if it should.
metro = () => {
- this.setState({
- playing: true
- });
+ this.props.setPlaying(true);
const loop = () => {
- if (this.state.playing) {
- this.setState({
- beat: (this.state.beat + 1) % this.state.numBeats
- })
+ if (this.props.playing) {
+ console.log('playing');
+ this.props.setBeat((this.props.beat + 1) % this.state.numBeats);
window.setTimeout(loop, (1 / this.props.bpm) * 60000);
}
}
- loop();
+ // give redux a chance to convey it's playing, a good sign of a bad design.
+ // i like this https://medium.com/@machadogj/timers-in-react-with-redux-apps-9a5a722162e8#Timers in Actions
+ window.setTimeout(loop, 0);
}
stopMetro = () => {
- this.setState({
- playing: false,
- beat: 0
- })
+ //TODO this could be one action handler called STOP, rather than composing everything manually like this.
+ this.props.setBeat(0);
+ this.props.setPlaying(false);
}
keyHandler(e) {
@@ -270,7 +267,7 @@ class App extends Component {
}}
activated={idx === this.state.editingToneIdx}
tone={this.state.tones[idx]}
- beat={this.state.beat}
+ beat={this.props.beat}
toggleMute={() => {
this.updateTone(idx, {
mute: !this.state.tones[idx].mute
@@ -317,14 +314,14 @@ class App extends Component {
></WaveEditor>
<div class="global-controls">
<CircleButton
- active={this.state.playing}
+ active={this.props.playing}
action={this.metro}
- disabled={this.state.playing}
+ disabled={this.props.playing}
>
<div class="triangle"></div>
</CircleButton>
<CircleButton
- active={!this.state.playing}
+ active={!this.props.playing}
action={this.stopMetro}
>
<div class="rectangle"></div>
diff --git a/src/index.js b/src/index.js
@@ -7,8 +7,10 @@ import { Provider, connect } from 'preact-redux';
import { store } from './store.js';
const ConnectedApp = connect(state => state, {
- setBpm: (newVal) => ({type: 'SET_GLOBAL_BPM', value: newVal}),
setVolume: (newVal) => ({type: 'SET_GLOBAL_VOLUME', value: newVal}),
+ setBpm: (newVal) => ({type: 'SET_GLOBAL_BPM', value: newVal}),
+ setBeat: (newVal) => ({type: 'SET_GLOBAL_BEAT', value: newVal}),
+ setPlaying: (newVal) => ({type: 'SET_GLOBAL_PLAYING', value: newVal})
})(App);
const InformedApp = <Provider store={store}><ConnectedApp /></Provider>;
diff --git a/src/store.js b/src/store.js
@@ -3,6 +3,8 @@ import { createStore } from 'redux';
const initialState = {
volume: 0.7,
bpm: 120,
+ beat: 0,
+ playing: false
};
const reducer = (state, action) => {
@@ -14,6 +16,12 @@ const reducer = (state, action) => {
case 'SET_GLOBAL_BPM':
updates.bpm = action.value;
break;
+ case 'SET_GLOBAL_BEAT':
+ updates.beat = action.value;
+ break;
+ case 'SET_GLOBAL_PLAYING':
+ updates.playing = action.value;
+ break;
}
return Object.assign({}, state, updates);
}