synthing

a waveform sequencing synth on the web
Log | Files | Refs | Submodules

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:
Msrc/App/index.js | 35++++++++++++++++-------------------
Msrc/index.js | 4+++-
Msrc/store.js | 8++++++++
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); }