Skip to content

Commit

Permalink
Adds an important flag to commands. (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
skellock committed Aug 18, 2016
1 parent 0f39cb5 commit 7807fe8
Show file tree
Hide file tree
Showing 14 changed files with 69 additions and 26 deletions.
4 changes: 3 additions & 1 deletion packages/demo-react-js/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class App extends Component {
<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>
<button style={Styles.button} onClick={this.props.requestBad}>Bad</button>

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

Expand All @@ -119,8 +120,9 @@ const mapDispatchToProps = dispatch => ({
requestReactNative: () => dispatch(RepoActions.request('facebook/react-native')),
requestMobx: () => dispatch(RepoActions.request('mobxjs/mobx')),
requestRedux: () => dispatch(RepoActions.request('reactjs/redux')),
requestBad: () => dispatch(RepoActions.request('zzzz/zzzzz')),
handleLogoPress: () => {
console.tron.log('wait for it...')
console.tron.log('wait for it...', true)
setTimeout(() => { makeErrorForFun('boom') }, 500)
}
})
Expand Down
7 changes: 5 additions & 2 deletions packages/demo-react-js/src/Redux/Store.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import createSagaMiddleware from 'redux-saga'
import rootReducer from './RootReducer'
import rootSaga from '../Sagas'
import Reactotron from 'reactotron-react-js'
import createTrackingEnhancer from 'reactotron-redux'
import createTronohancer from 'reactotron-redux'
import { Types as LogoTypes } from './Logo.redux'

// the logger master switch
const USE_LOGGING = false
Expand All @@ -21,7 +22,9 @@ const logger = createLogger({
// a function which can create our store and auto-persist the data
export default () => {
const sagaMiddleware = createSagaMiddleware()
const tracker = createTrackingEnhancer(Reactotron, {})
const tracker = createTronohancer(Reactotron, {
isActionImportant: action => action.type === LogoTypes.Size && action.size > 100
})
const enhancers = compose(
applyMiddleware(logger, sagaMiddleware),
tracker
Expand Down
1 change: 0 additions & 1 deletion packages/reactotron-app/App/Commands/ApiResponseCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class ApiResponseCommand extends Component {
const { payload } = command
const { duration } = payload
const status = dotPath('response.status', payload)
const ok = isWithin(200, 299, status || 0)
const url = dotPath('request.url', payload)
const method = toUpper(dotPath('request.method', payload) || '')
const requestHeaders = dotPath('request.headers', payload)
Expand Down
17 changes: 14 additions & 3 deletions packages/reactotron-app/App/Shared/Command.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,18 @@ const Styles = {
cursor: 'pointer'
},
title: {
color: Colors.tag,
textAlign: 'left',
width: 150
},
titleText: {
color: Colors.tag
},
titleTextInverse: {
backgroundColor: Colors.tag,
color: Colors.foregroundLight,
borderRadius: 4,
padding: '4px 8px'
},
subtitle: {
color: Colors.foreground,
textAlign: 'left',
Expand Down Expand Up @@ -107,9 +115,10 @@ class Command extends Component {
render () {
const { isOpen } = this.state
const { command, children, title, subtitle, preview } = this.props
const { important } = command
const hasSubtitle = !isNilOrEmpty(subtitle)
const { date } = command
const titleStyle = Styles.title
const titleTextStyle = merge(Styles.titleText, important ? Styles.titleTextInverse : {})
const topRowStyle = Styles.topRow
const timestampStyle = Styles.timestamp
const Icon = isOpen ? IconOpen : IconClosed
Expand All @@ -119,7 +128,9 @@ class Command extends Component {
<div style={Styles.body}>
<div style={topRowStyle} onClick={this.handleToggleOpen}>
<Timestamp date={date} style={timestampStyle} />
<span style={titleStyle}>{title}</span>
<div style={Styles.title}>
<span style={titleTextStyle}>{title}</span>
</div>
{isOpen && hasSubtitle && <span style={Styles.subtitle}>{subtitle}</span>}
{!isOpen && <span style={Styles.preview}>{preview}</span>}
{isOpen && <span style={Styles.spacer}></span>}
Expand Down
3 changes: 3 additions & 0 deletions packages/reactotron-core-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ client.connect()
// send a log message as a string
client.send('log', { level: 'debug', message: 'hello!' })

// send a log message as a string that's important
client.send('log', { level: 'debug', message: 'hello!' }, true)

// sending an object log message
client.send('log', {
level: 'debug',
Expand Down
4 changes: 2 additions & 2 deletions packages/reactotron-core-client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ export class Client {
/**
* Sends a command to the server
*/
send (type, payload) {
this.socket && this.socket.emit('command', { type, payload })
send (type, payload, important = false) {
this.socket && this.socket.emit('command', { type, payload, important: !!important })
}

/**
Expand Down
9 changes: 7 additions & 2 deletions packages/reactotron-core-client/src/plugins/api-response.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { isWithin } from 'ramdasauce'

/**
* Sends API request/response information.
*/
export default () => reactotron => {
return {
features: {
apiResponse: (request, response, duration) =>
reactotron.send('api.response', { request, response, duration })
apiResponse: (request, response, duration) => {
const ok = response && response.status && isWithin(200, 299, response.status)
const important = !ok
reactotron.send('api.response', { request, response, duration }, important)
}
}
}
}
8 changes: 4 additions & 4 deletions packages/reactotron-core-client/src/plugins/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
export default () => reactotron => {
return {
features: {
log: (message) => reactotron.send('log', { level: 'debug', message }),
debug: (message) => reactotron.send('log', { level: 'debug', message }),
warn: (message) => reactotron.send('log', { level: 'warn', message }),
error: (message, stack) => reactotron.send('log', { level: 'error', message, stack })
log: (message, important = false) => reactotron.send('log', { level: 'debug', message}, !!important),
debug: (message, important = false) => reactotron.send('log', { level: 'debug', message}, !!important),
warn: (message) => reactotron.send('log', { level: 'warn', message }, true),
error: (message, stack) => reactotron.send('log', { level: 'error', message, stack }, true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
export default () => reactotron => {
return {
features: {
stateActionComplete: (name, action) =>
reactotron.send('state.action.complete', { name, action }),
stateActionComplete: (name, action, important = false) =>
reactotron.send('state.action.complete', { name, action }, !!important),

stateValuesResponse: (path, value, valid = true) =>
reactotron.send('state.values.response', { path, value, valid }),
Expand Down
4 changes: 2 additions & 2 deletions packages/reactotron-core-server/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ class Server {
})

// when we receive a command from the client
socket.on('command', ({ type, payload }) => {
socket.on('command', ({ type, important, payload }) => {
this.messageId++
const date = new Date()
const fullCommand = { type, payload, messageId: this.messageId, date }
const fullCommand = { type, important, payload, messageId: this.messageId, date }

// for client intros
if (type === 'client.intro') {
Expand Down
5 changes: 4 additions & 1 deletion packages/reactotron-redux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ Here's a bigger example:
// came in up in the import section.
const enhancers = compose(
applyMiddleware(logger),
createReactotronTrackingEnhancer(Reactotron)
createReactotronTrackingEnhancer(Reactotron, {
// optional flagging of important actions
isActionImportant: action => action.type === 'FORMAT_HARD_DRIVE'
})
)

// This creates our store (rootReducer is just from a sample app, you've
Expand Down
6 changes: 3 additions & 3 deletions packages/reactotron-redux/src/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import requestKeys from './keys-request'
import requestValues from './values-request'
import getSubscriptionValues from './get-subscription-values'

const createPlugin = store => {
const createPlugin = (store, pluginConfig = {}) => {
// hold onto the send
let capturedSend

Expand Down Expand Up @@ -58,7 +58,7 @@ const createPlugin = store => {
}

// attach a function that we can call from the enhancer
plugin.report = (action, ms) => {
plugin.report = (action, ms, important = false) => {
if (!capturedSend) return

// let's call the type, name because that's "generic" name in Reactotron
Expand All @@ -70,7 +70,7 @@ const createPlugin = store => {
}

// off ya go!
capturedSend('state.action.complete', { name, action, ms })
capturedSend('state.action.complete', { name, action, ms }, important)
}

return plugin
Expand Down
8 changes: 7 additions & 1 deletion packages/reactotron-redux/src/store-enhancer.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,13 @@ const createReactotronStoreEnhancer = (reactotron, enhancerOptions = {}) => {

// action not blacklisted?
if (!R.contains(action.type, options.except || [])) {
plugin.report(action, ms)
// check if the app considers this important
let important = false
if (enhancerOptions && typeof enhancerOptions.isActionImportant === 'function') {
important = !!enhancerOptions.isActionImportant(action)
}

plugin.report(action, ms, important)
}

// return the real work's result
Expand Down
15 changes: 13 additions & 2 deletions packages/reactotron-redux/test/store-enhancer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,30 @@ test('tests pretty much everything', t => {
// these guys will hold the values of the command jumping the wire
let capturedType
let capturedPayload
let capturedImportant = false
let importantCount = 0

// create our own socket.io which captures the contents of emit
const io = x => {
return {
on: (command, callback) => true,
emit: (command, { type, payload }) => {
emit: (command, { type, payload, important }) => {
capturedType = type
capturedPayload = payload
capturedImportant = important
}
}
}

// test the important callback
const isActionImportant = (action) => {
importantCount++
return true
}

// grab the enhancer
const client = createClient({ io, plugins: CorePlugins })
const enhancer = createEnhancer(client)
const enhancer = createEnhancer(client, { isActionImportant })
t.is(typeof enhancer, 'function')

// things to make sure our internal middleware chains dispatch properly
Expand Down Expand Up @@ -62,4 +71,6 @@ test('tests pretty much everything', t => {
t.is(capturedPayload.name, 'add')
t.deepEqual(capturedPayload.action, action)
t.true(capturedPayload.ms >= 0)
t.is(importantCount, 1)
t.true(capturedImportant)
})

0 comments on commit 7807fe8

Please sign in to comment.