Skip to content

Commit

Permalink
Adds more guts to the react js demo. (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
skellock committed Aug 23, 2016
1 parent 74075e7 commit 7977d4d
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 58 deletions.
10 changes: 0 additions & 10 deletions packages/demo-react-js/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,9 @@
text-align: center;
}

.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}

.App-logo-fast {
animation: App-logo-spin infinite 1s linear;
height: 80px;
}

.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
Expand Down
64 changes: 55 additions & 9 deletions packages/demo-react-js/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,26 @@ import React, { Component, PropTypes } from 'react';
import logo from './logo.svg';
import './App.css';
import { connect } from 'react-redux'
import { Actions } from './Redux/Startup.redux'
import { Actions as StartupActions } from './Redux/Startup.redux'
import { Actions as LogoActions } from './Redux/Logo.redux'
import { Actions as RepoActions } from './Redux/Repo.redux'

const Styles = {
button: {
fontSize: 15,
padding: 10,
margin: '10px 10px',
backgroundColor: '#333333',
border: 0,
borderRadius: 4,
color: '#eeeeee'
},
avatar: {
height: 80,
width: 80,
borderRadius: 40
}
}

class App extends Component {

Expand All @@ -17,7 +36,7 @@ class App extends Component {
}

componentWillMount () {
this.props.startup()
// this.props.startup()
}

renderError () {
Expand All @@ -42,35 +61,62 @@ class App extends Component {
<div>
<p className='App-message'><b>{name}</b></p>
<p className='App-message'>
<a href={url}>{message}</a>
<a href={url} target='somewhere'>{message}</a>
</p>
<p className='App-sha'>{sha}</p>
</div>
)
}

render () {
const { error, fetching } = this.props
const logoClass = fetching ? 'App-logo-fast' : 'App-logo'
const { error, speed, size, repo, avatar } = this.props
const logoStyles = {
animation: `App-logo-spin infinite ${speed}s linear`,
height: `${size}px`
}

return (
<div className="App">
<div className="App-header">
<img src={logo} className={logoClass} alt="logo" />
<h2>Reactotron Demo</h2>
<div>
<button style={Styles.button} onClick={this.props.slower}>Slow</button>
<button style={Styles.button} onClick={this.props.faster}>Fast</button>
<button style={Styles.button} onClick={this.props.bigger}>Big</button>
<button style={Styles.button} onClick={this.props.smaller}>Small</button>
</div>
<img src={logo} style={logoStyles} alt="logo" />
</div>
<h3 className='App-message-title'>Latest Commit Message</h3>
{ repo &&
<h3 className='App-message-title'>Latest Commit From {repo}</h3> }
{ avatar &&
<div><img src={avatar} style={Styles.avatar} alt="avatar" /></div>
}
<button style={Styles.button} onClick={this.props.requestReactotron}>Reactotron</button>
<button style={Styles.button} onClick={this.props.requestReactNative}>React Native</button>
<button style={Styles.button} onClick={this.props.requestMobx}>Mobx</button>
<button style={Styles.button} onClick={this.props.requestRedux}>Redux</button>

{ error ? this.renderError() : this.renderMessage() }


</div>
);
}
}

const mapStateToProps = state => state.repoMessage
const mapStateToProps = state => ({ ...state.repo, ...state.logo })

const mapDispatchToProps = dispatch => ({
startup: () => dispatch(Actions.startup())
startup: () => dispatch(StartupActions.startup()),
faster: () => dispatch(LogoActions.changeSpeed(1)),
slower: () => dispatch(LogoActions.changeSpeed(20)),
bigger: () => dispatch(LogoActions.changeSize(160)),
smaller: () => dispatch(LogoActions.changeSize(40)),
requestReactotron: () => dispatch(RepoActions.request('reactotron/reactotron')),
requestReactNative: () => dispatch(RepoActions.request('facebook/react-native')),
requestMobx: () => dispatch(RepoActions.request('mobxjs/mobx')),
requestRedux: () => dispatch(RepoActions.request('reactjs/redux'))
})

export default connect(mapStateToProps, mapDispatchToProps)(App);
33 changes: 33 additions & 0 deletions packages/demo-react-js/src/Redux/Logo.redux.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export const Types = {
Speed: 'logo.speed',
Size: 'logo.size',
Reset: 'logo.reset'
}

export const Actions = {
changeSpeed: (speed) => ({ type: Types.Speed, speed }),
changeSize: (size) => ({ type: Types.Size, size }),
reset: () => ({ type: Types.Reset })
}

export const INITIAL_STATE = {
size: 100,
speed: 5
}

const changeSpeed = (state, { speed }) => ({ ...state, speed })
const changeSize = (state, { size }) => ({ ...state, size })
const reset = (state, { size }) => INITIAL_STATE

// actions ->
const reducerMap = {
[Types.Speed]: changeSpeed,
[Types.Size]: changeSize,
[Types.Reset]: reset
}

// our reducer
export const reducer = (state = INITIAL_STATE, action) => {
const handler = reducerMap[action.type]
return typeof handler === 'function' ? handler(state, action) : state
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
export const Types = {
Request: 'RepoMessage.Request',
Receive: 'RepoMessage.Receive',
Failure: 'RepoMessage.Failure'
Request: 'repo.request',
Receive: 'repo.receive',
Failure: 'repo.failure'
}

export const Actions = {
request: () => ({ type: Types.Request }),
receive: (message, url, name, sha) => ({ type: Types.Receive, message, url, name, sha }),
request: (repo) => ({ type: Types.Request, repo }),
receive: (message, url, name, sha, avatar) => ({ type: Types.Receive, message, url, name, sha, avatar }),
failure: (error) => ({ type: Types.Failure, error })
}

export const INITIAL_STATE = {
message: null,
repo: null,
url: null,
name: null,
sha: null,
fetching: false,
avatar: null,
error: null
}

// we're going out for the repo message
const request = (state, action) =>
({ ...INITIAL_STATE, fetching: true })
const request = (state, { repo }) =>
({ ...INITIAL_STATE, fetching: true, repo })

// we've got a repo message
const receive = (state, action) => {
const { message, url, name, sha } = action
return { ...state, fetching: false, message, url, name, sha }
const receive = (state, { message, url, name, sha, avatar }) => {
return { ...state, fetching: false, message, url, name, sha, avatar }
}

// we failed to get the repo message :(
Expand Down
6 changes: 4 additions & 2 deletions packages/demo-react-js/src/Redux/RootReducer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { combineReducers } from 'redux'
import { reducer as repoMessageReducer } from './RepoMessage.redux'
import { reducer as repoReducer } from './Repo.redux'
import { reducer as logoReducer } from './Logo.redux'

export default combineReducers({
repoMessage: repoMessageReducer
repo: repoReducer,
logo: logoReducer
})
4 changes: 2 additions & 2 deletions packages/demo-react-js/src/Redux/Store.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export default () => {
const tracker = createTrackingEnhancer(Reactotron, {
})
const enhancers = compose(
tracker,
applyMiddleware(logger, sagaMiddleware)
applyMiddleware(logger, sagaMiddleware),
tracker
)

const store = createStore(rootReducer, enhancers)
Expand Down
22 changes: 22 additions & 0 deletions packages/demo-react-js/src/Sagas/Repo.sagas.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import RS from 'ramdasauce'
import { call, put } from 'redux-saga/effects'
import * as Repo from '../Redux/Repo.redux'

export function * request (api, action) {
// make the call to github
const { repo } = action
const { ok, data, status, problem } = yield call(api.get, `/repos/${repo}/commits`)
// are we good?
if (ok) {
const entry = RS.dotPath('0', data)
const { commit, author, html_url: url } = entry
const { message, tree } = commit
const { name, avatar_url } = author
const { sha } = tree
console.log({ avatar_url })
// record the last commit's message
yield put(Repo.Actions.receive(message, url, name, sha, avatar_url))
} else {
yield put(Repo.Actions.failure(`uh oh: ${problem} status: ${status}`))
}
}
19 changes: 0 additions & 19 deletions packages/demo-react-js/src/Sagas/RepoMessage.sagas.js

This file was deleted.

6 changes: 3 additions & 3 deletions packages/demo-react-js/src/Sagas/Startup.sagas.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { put } from 'redux-saga/effects'
import * as RepoMessage from '../Redux/RepoMessage.redux'
// import { put } from 'redux-saga/effects'
// import * as RepoMessage from '../Redux/RepoMessage.redux'

// process STARTUP actions
export function * startup () {
yield put(RepoMessage.Actions.request())
// yield put(RepoMessage.Actions.request())
}
6 changes: 3 additions & 3 deletions packages/demo-react-js/src/Sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import ApiSauce from 'apisauce'
import Reactotron from 'reactotron-react-js'

import * as Startup from '../Redux/Startup.redux'
import * as RepoMessage from '../Redux/RepoMessage.redux'
import * as Repo from '../Redux/Repo.redux'

import { startup } from './Startup.sagas'
import { request as requestRepoMessage } from './RepoMessage.sagas'
import { request as requestRepo } from './Repo.sagas'

const api = ApiSauce.create({
baseURL: 'https://api.github.com',
Expand All @@ -19,7 +19,7 @@ api.addMonitor(Reactotron.apisauce)

export default function * rootSaga () {
yield [
takeLatest(RepoMessage.Types.Request, requestRepoMessage, api),
takeLatest(Repo.Types.Request, requestRepo, api),
takeEvery(Startup.Types.Startup, startup)
]
}

0 comments on commit 7977d4d

Please sign in to comment.