From f436147e49f3f110501996a602f37943f1128366 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 3 Oct 2016 20:05:44 +1300 Subject: [PATCH] Removing IOC, using redux approach --- package.json | 4 +- src/actions/index.js | 2 +- src/actions/mopidy.js | 29 +++++++ src/actions/mopidyServiceActions.js | 21 ----- src/bootstrap.js | 7 -- src/components/App.js | 9 +-- src/components/Queue.js | 23 ++---- src/reducers/index.js | 4 +- src/reducers/mopidy.js | 29 +++++++ src/reducers/mopidyServiceReducer.js | 18 ----- src/services/MopidyService.js | 113 ++++++++++++++++----------- 11 files changed, 140 insertions(+), 119 deletions(-) create mode 100755 src/actions/mopidy.js delete mode 100755 src/actions/mopidyServiceActions.js create mode 100755 src/reducers/mopidy.js delete mode 100755 src/reducers/mopidyServiceReducer.js diff --git a/package.json b/package.json index 925ccddf..5fe88445 100755 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "test-reactor", + "name": "iris", "version": "1.0.0", "description": "", "main": "app.js", @@ -27,7 +27,7 @@ "kioc": "1.0.4" }, "scripts": { - "dev": "cp src/index.html production/index.html & NODE_ENV=development webpack", + "dev": "mkdir production & cp src/index.html production/index.html & NODE_ENV=development webpack", "prod": "NODE_ENV=production webpack" }, "author": "James Barnsley", diff --git a/src/actions/index.js b/src/actions/index.js index a23de9ad..fec22d6a 100755 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,4 +1,4 @@ import albumActions from './albumActions' -import mopidyServiceActions from './mopidyServiceActions' +import mopidy from './mopidy' diff --git a/src/actions/mopidy.js b/src/actions/mopidy.js new file mode 100755 index 00000000..269377b7 --- /dev/null +++ b/src/actions/mopidy.js @@ -0,0 +1,29 @@ + +/** + * Actions and Action Creators + **/ + +export const STATUS_CHANGED = 'STATUS_CHANGED' +export const UPDATE_TRACKLIST = 'UPDATE_TRACKLIST' +export const VOLUME_CHANGED = 'VOLUME_CHANGED' + +export function updateStatus( online ){ + return { + type: STATUS_CHANGED, + online: online + } +} + +export function volumeChanged( volume ){ + return { + type: VOLUME_CHANGED, + volume: volume + } +} + +export function updateTracklist( tracks ){ + return { + type: UPDATE_TRACKLIST, + tracks: tracks + } +} \ No newline at end of file diff --git a/src/actions/mopidyServiceActions.js b/src/actions/mopidyServiceActions.js deleted file mode 100755 index ce085af9..00000000 --- a/src/actions/mopidyServiceActions.js +++ /dev/null @@ -1,21 +0,0 @@ - -/** - * Actions and Action Creators - **/ - -export const MOPIDY_ONLINE = 'MOPIDY_ONLINE' -export const UPDATE_TRACKLIST = 'UPDATE_TRACKLIST' - -export function mopidyOnline( online ){ - return { - type: MOPIDY_ONLINE, - online: online - } -} - -export function updateTracklist( tracks ){ - return { - type: UPDATE_TRACKLIST, - tracks: tracks - } -} \ No newline at end of file diff --git a/src/bootstrap.js b/src/bootstrap.js index e439cdfc..f5553dcf 100755 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -3,15 +3,8 @@ console.info('Bootstrapping...'); import { createStore } from 'redux' import reducer from './reducers/index' -import Services from './services/Services' // create our global store let store = createStore( reducer, {} ); -// start all our services -Promise.all(Services.setup( store )) - .then(() => { - console.info('Services started...'); - }); - export default store; diff --git a/src/components/App.js b/src/components/App.js index c66d8248..6b8ba4b2 100755 --- a/src/components/App.js +++ b/src/components/App.js @@ -11,6 +11,7 @@ import { connect } from 'react-redux' import * as actions from '../actions/index' import Services from '../services/Services' +import MopidyService from '../services/MopidyService' class App extends React.Component{ @@ -33,13 +34,6 @@ class App extends React.Component{ } componentDidMount(){ - Services.get('services.mopidy') - .then( function(MopidyService){ - MopidyService.connection.playback.getState() - .then( function(state){ - console.log('App.js > playback state', state); - }); - }) } render(){ @@ -55,6 +49,7 @@ class App extends React.Component{
  • Authorize
  • {this.props.children} + ); } diff --git a/src/components/Queue.js b/src/components/Queue.js index 94717965..d5fa4618 100755 --- a/src/components/Queue.js +++ b/src/components/Queue.js @@ -5,29 +5,18 @@ import { bindActionCreators } from 'redux' import Services from '../services/Services' import TrackList from '../components/TrackList' -import * as queueActions from '../actions/queueActions' +import * as actions from '../actions/mopidy' -class NowPlaying extends React.Component{ +class Queue extends React.Component{ constructor(props) { super(props); - this.state = { - tracks: [] - } - } - - // on render - componentDidMount(){ - Services.get('services.mopidy') - .then( function(MopidyService){ - MopidyService.getCurrentTracklist(); - }) } renderTracks(){ - if( this.state.tracks ){ + if( this.props.mopidy && this.props.mopidy.tracks ){ return ( - + ); } return null; @@ -56,8 +45,8 @@ const mapStateToProps = (state, ownProps) => { const mapDispatchToProps = (dispatch) => { return { - queueActions: bindActionCreators(queueActions, dispatch) + actions: bindActionCreators(actions, dispatch) } } -export default connect(mapStateToProps, mapDispatchToProps)(NowPlaying) \ No newline at end of file +export default connect(mapStateToProps, mapDispatchToProps)(Queue) \ No newline at end of file diff --git a/src/reducers/index.js b/src/reducers/index.js index c8efc575..89e850a9 100755 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,12 +7,14 @@ // import all of our application reducers import album from './album' +import mopidy from './mopidy' import { combineReducers } from 'redux' // combine them into one root reducer export default combineReducers({ - album + album, + mopidy }) diff --git a/src/reducers/mopidy.js b/src/reducers/mopidy.js new file mode 100755 index 00000000..e7bb155d --- /dev/null +++ b/src/reducers/mopidy.js @@ -0,0 +1,29 @@ + +import * as actions from '../actions/mopidy' + +export default function reducer(mopidy = {}, action){ + console.log(action); + switch (action.type) { + + case actions.STATUS_CHANGED: + return Object.assign({}, mopidy, { + online: action.online + }); + + case actions.UPDATE_TRACKLIST: + return Object.assign({}, mopidy, { + tracks: action.tracks + }); + + case actions.VOLUME_CHANGED: + return Object.assign({}, mopidy, { + volume: action.volume + }); + + default: + return mopidy + } +} + + + diff --git a/src/reducers/mopidyServiceReducer.js b/src/reducers/mopidyServiceReducer.js deleted file mode 100755 index 3c07d0ff..00000000 --- a/src/reducers/mopidyServiceReducer.js +++ /dev/null @@ -1,18 +0,0 @@ - -import * as actions from '../actions/mopidyServiceActions' - -export default function reducer(mopidyService = {}, action){ - switch (action.type) { - - case actions.UPDATE_TRACKLIST: - return Object.assign({}, mopidyService, { - tracks: action.tracks - }); - - default: - return mopidyService - } -} - - - diff --git a/src/services/MopidyService.js b/src/services/MopidyService.js index 2a40bc4e..80b6e37b 100755 --- a/src/services/MopidyService.js +++ b/src/services/MopidyService.js @@ -1,28 +1,10 @@ import Mopidy from 'mopidy' +import React, { PropTypes } from 'react' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' - -/** - * Create an IOC wrapper for our MopidyService instance - * - * This initiates our service, and provides a container for our connection. We wrap - * this in a Promise so any requests to .get() will be delayed until we're connected. Genius! - **/ - -let MopidyServiceWrapper = { - attachKey: 'services.mopidy', - attach: function( store ){ - console.info('MopidyServiceWrapper: Attaching...'); - var service = new MopidyService( store ); - return new Promise((resolve) => { - service.connection.on('state:online', () => { - resolve( service ); - }); - }); - } -} - -export default MopidyServiceWrapper +import * as actions from '../actions/mopidy' /** @@ -30,40 +12,81 @@ export default MopidyServiceWrapper * * Handles internal requests and passes them on to our connection **/ -class MopidyService { +class MopidyService extends React.Component{ - constructor( store ){ - var mopidyhost = 'music.plasticstudio.co';//window.location.hostname; - var mopidyport = "6680"; - var protocol = 'ws'; + constructor( props ){ + super(props) this.connection = new Mopidy({ - webSocketUrl: protocol+"://" + mopidyhost + ":" + mopidyport + "/mopidy/ws", + webSocketUrl: "ws://music.barnsley.nz:6680/mopidy/ws", callingConvention: 'by-position-or-by-name' }); - this.connection.on( - (type, message) => this.handleMessage( type, message ) - ); - this.store = store; + + this.connection.on( (type, data) => this.handleMessage( type, data ) ); } - setConnection( connection ){ - this.connection = connection; + handleMessage( type, data ){ + switch( type ){ + + case 'state:online': + this.updateStatus(true); + this.getTracklist(); + this.getVolume(); + break; + + case 'event:tracklistChanged': + this.getTracklist(); + break; + + case 'event:volumeChanged': + this.props.actions.volumeChanged(data.volume); + break; + + default: + //console.log( 'MopidyService: Unhandled event', type, message ); + } } - clearConnection(){ - this.connection = false; + updateStatus( online = false ){ + this.props.actions.updateStatus( online ); } - handleMessage( type, message ){ - //console.log( message ); - } - - getCurrentTracklist(){ - this.connection.tracklist.getTlTracks() - .then( function(tracks){ - console.log(tracks); + getVolume(){ + let self = this; + this.connection.playback.getVolume() + .then( function(volume){ + self.props.actions.volumeChanged(volume); }); } -} \ No newline at end of file + getTracklist(){ + let self = this; + this.connection.tracklist.getTlTracks() + .then( function(tracks){ + self.props.actions.updateTracklist(tracks); + }); + } + + render(){ + return
    { JSON.stringify(this.props.mopidy, null, 2) }
    ; + } +} + + +/** + * Export our component + * + * We also integrate our global store, using connect() + **/ + +const mapStateToProps = (state, ownProps) => { + return state; +} + +const mapDispatchToProps = (dispatch) => { + return { + actions: bindActionCreators(actions, dispatch) + } +} + +export default connect(mapStateToProps, mapDispatchToProps)(MopidyService) \ No newline at end of file