Removing IOC, using redux approach

This commit is contained in:
James Barnsley
2016-10-03 20:05:44 +13:00
parent 12f07637ee
commit f436147e49
11 changed files with 140 additions and 119 deletions

View File

@ -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",

View File

@ -1,4 +1,4 @@
import albumActions from './albumActions'
import mopidyServiceActions from './mopidyServiceActions'
import mopidy from './mopidy'

29
src/actions/mopidy.js Executable file
View File

@ -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
}
}

View File

@ -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
}
}

7
src/bootstrap.js vendored
View File

@ -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;

View File

@ -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{
<li><a onClick={this.handleClick}>Authorize</a></li>
</ul>
{this.props.children}
<MopidyService />
</div>
);
}

View File

@ -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 (
<TrackList tracks={this.state.tracks} />
<TrackList tracks={this.props.mopidy.tracks} />
);
}
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)
export default connect(mapStateToProps, mapDispatchToProps)(Queue)

View File

@ -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
})

29
src/reducers/mopidy.js Executable file
View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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);
});
}
}
getTracklist(){
let self = this;
this.connection.tracklist.getTlTracks()
.then( function(tracks){
self.props.actions.updateTracklist(tracks);
});
}
render(){
return <pre>{ JSON.stringify(this.props.mopidy, null, 2) }</pre>;
}
}
/**
* 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)