apeman-react-mixins
Version:
React mixin set of apeman.
128 lines (111 loc) • 2.64 kB
JSX
/**
* Mixin to handle spin.
* @mixin ApSpinMixin
*/
import React, {PropTypes as types} from 'react'
import argx from 'argx'
const SPIN_PROP_KEY = '_apSpin'
/** @lends ApSpinMixin */
let ApSpinMixin = {
// --------------------
// Custom
// --------------------
$apSpinMixed: true,
/**
* Count active spin.
* @param {string} name - Name of spin.
* @returns {number} - Number of spins.
*/
getSpinCount (name) {
const s = this
name = name || 'default'
let counts = s.state[ SPIN_PROP_KEY ] || {}
return Number(counts[ name ] || 0)
},
/**
* Set active spin count.
* @param {string} name - Name of spin.
* @param {number} count - Count to set.
*/
setSpinCount (name, count) {
const s = this
name = name || 'default'
let counts = s.state[ SPIN_PROP_KEY ] || {}
counts[ name ] = count
if (s.isMounted()) {
s.setState({ [SPIN_PROP_KEY]: counts })
}
},
/**
* Check if spin exists.
* @returns {boolean} - Exists or not.
*/
hasSpin (name) {
const s = this
name = name || 'default'
return s.getSpinCount(name) > 0
},
/**
* Increment spin count.
* @param {string} name - Name of spin.
*/
incrementSpinCount (name) {
const s = this
s.setSpinCount(name, s.getSpinCount(name) + 1)
},
/**
* Decrement spin count.
* @param {string} name - Name of spin.
*/
decrementSpinCount (name) {
const s = this
s.setSpinCount(name, s.getSpinCount(name) - 1)
},
/**
* Rest spin count
* @param {string} name - Name of spin.
*/
resetSpinCount (name) {
const s = this
s.setSpinCount(name, 0)
},
/**
* Add spin count while active.
* @param {string|number|symbol} name - Name of spin.
* @param {function} action - Action to do.
*/
spinWhile (name, action) {
let args = argx(arguments)
name = args.shift('string|number|symbol')
action = args.pop('function')
const s = this
s.incrementSpinCount(name)
let promise = action()
if (!promise) {
throw new Error('[ApSpinMixin] action must return a promise.')
}
return promise
.then((result) => {
s.decrementSpinCount(name)
return Promise.resolve(result)
})
.catch((err) => {
s.decrementSpinCount(name)
return Promise.reject(err)
})
},
// --------------------
// Specs
// --------------------
getInitialState () {
const s = this
return {
[SPIN_PROP_KEY]: {}
}
}
// --------------------
// Lifecycle
// --------------------
}
export default Object.freeze(ApSpinMixin)