Refactor to allow dispatching of two kinds of Actions
They are: 1. The existing type of Action, Objects with an `action` type. 1. Asyncronous Actions, functions that accept a `dispatch` argument, which can be used to dispatch Actions asyncronously.
This commit is contained in:
parent
60d8ebb914
commit
13925db251
5 changed files with 37 additions and 31 deletions
|
@ -14,13 +14,12 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createPromiseActionCreator } from './actionCreators';
|
import { asyncAction } from './actionCreators';
|
||||||
|
|
||||||
const GroupActions = {};
|
const GroupActions = {};
|
||||||
|
|
||||||
GroupActions.fetchJoinedGroups = createPromiseActionCreator(
|
GroupActions.fetchJoinedGroups = function(matrixClient) {
|
||||||
'GroupActions.fetchJoinedGroups',
|
return asyncAction('GroupActions.fetchJoinedGroups', () => matrixClient.getJoinedGroups());
|
||||||
(matrixClient) => matrixClient.getJoinedGroups(),
|
};
|
||||||
);
|
|
||||||
|
|
||||||
export default GroupActions;
|
export default GroupActions;
|
||||||
|
|
|
@ -15,14 +15,13 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Analytics from '../Analytics';
|
import Analytics from '../Analytics';
|
||||||
import { createPromiseActionCreator } from './actionCreators';
|
import { asyncAction } from './actionCreators';
|
||||||
import TagOrderStore from '../stores/TagOrderStore';
|
import TagOrderStore from '../stores/TagOrderStore';
|
||||||
|
|
||||||
const TagOrderActions = {};
|
const TagOrderActions = {};
|
||||||
|
|
||||||
TagOrderActions.commitTagOrdering = createPromiseActionCreator(
|
TagOrderActions.commitTagOrdering = function(matrixClient) {
|
||||||
'TagOrderActions.commitTagOrdering',
|
return asyncAction('TagOrderActions.commitTagOrdering', () => {
|
||||||
(matrixClient) => {
|
|
||||||
// Only commit tags if the state is ready, i.e. not null
|
// Only commit tags if the state is ready, i.e. not null
|
||||||
const tags = TagOrderStore.getOrderedTags();
|
const tags = TagOrderStore.getOrderedTags();
|
||||||
if (!tags) {
|
if (!tags) {
|
||||||
|
@ -31,7 +30,7 @@ TagOrderActions.commitTagOrdering = createPromiseActionCreator(
|
||||||
|
|
||||||
Analytics.trackEvent('TagOrderActions', 'commitTagOrdering');
|
Analytics.trackEvent('TagOrderActions', 'commitTagOrdering');
|
||||||
return matrixClient.setAccountData('im.vector.web.tag_ordering', {tags});
|
return matrixClient.setAccountData('im.vector.web.tag_ordering', {tags});
|
||||||
},
|
});
|
||||||
);
|
};
|
||||||
|
|
||||||
export default TagOrderActions;
|
export default TagOrderActions;
|
||||||
|
|
|
@ -14,25 +14,23 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import dis from '../dispatcher';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an action creator that will dispatch actions asynchronously that
|
* Create an asynchronous action creator that will dispatch actions indicating
|
||||||
* indicate the current status of promise returned by the given function, fn.
|
* the current status of the promise returned by fn.
|
||||||
* @param {string} id the id to give the dispatched actions. This is given a
|
* @param {string} id the id to give the dispatched actions. This is given a
|
||||||
* suffix determining whether it is pending, successful or
|
* suffix determining whether it is pending, successful or
|
||||||
* a failure.
|
* a failure.
|
||||||
* @param {function} fn the function to call with arguments given to the
|
* @param {function} fn a function that returns a Promise.
|
||||||
* returned function. This function should return a Promise.
|
* @returns {function} a function that uses its single argument as a dispatch
|
||||||
* @returns {function} a function that dispatches asynchronous actions when called.
|
* function.
|
||||||
*/
|
*/
|
||||||
export function createPromiseActionCreator(id, fn) {
|
export function asyncAction(id, fn) {
|
||||||
return (...args) => {
|
return (dispatch) => {
|
||||||
dis.dispatch({action: id + '.pending'});
|
dispatch({action: id + '.pending'});
|
||||||
fn(...args).then((result) => {
|
fn().then((result) => {
|
||||||
dis.dispatch({action: id + '.success', result});
|
dispatch({action: id + '.success', result});
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
dis.dispatch({action: id + '.failure', err});
|
dispatch({action: id + '.failure', err});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ const TagPanel = React.createClass({
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
// This could be done by anything with a matrix client
|
// This could be done by anything with a matrix client
|
||||||
GroupActions.fetchJoinedGroups(this.context.matrixClient);
|
dis.dispatch(GroupActions.fetchJoinedGroups(this.context.matrixClient));
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -81,7 +81,7 @@ const TagPanel = React.createClass({
|
||||||
|
|
||||||
_onGroupMyMembership() {
|
_onGroupMyMembership() {
|
||||||
if (this.unmounted) return;
|
if (this.unmounted) return;
|
||||||
GroupActions.fetchJoinedGroups(this.context.matrixClient);
|
dis.dispatch(GroupActions.fetchJoinedGroups.bind(this.context.matrixClient));
|
||||||
},
|
},
|
||||||
|
|
||||||
onClick() {
|
onClick() {
|
||||||
|
@ -94,7 +94,7 @@ const TagPanel = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onTagTileEndDrag() {
|
onTagTileEndDrag() {
|
||||||
TagOrderActions.commitTagOrdering(this.context.matrixClient);
|
dis.dispatch(TagOrderActions.commitTagOrdering(this.context.matrixClient));
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -20,14 +20,24 @@ const flux = require("flux");
|
||||||
|
|
||||||
class MatrixDispatcher extends flux.Dispatcher {
|
class MatrixDispatcher extends flux.Dispatcher {
|
||||||
/**
|
/**
|
||||||
* @param {Object} payload Required. The payload to dispatch.
|
* @param {Object|function} payload Required. The payload to dispatch.
|
||||||
* Must contain at least an 'action' key.
|
* If an Object, must contain at least an 'action' key.
|
||||||
|
* If a function, must have the signature (dispatch) => {...}.
|
||||||
* @param {boolean=} sync Optional. Pass true to dispatch
|
* @param {boolean=} sync Optional. Pass true to dispatch
|
||||||
* synchronously. This is useful for anything triggering
|
* synchronously. This is useful for anything triggering
|
||||||
* an operation that the browser requires user interaction
|
* an operation that the browser requires user interaction
|
||||||
* for.
|
* for.
|
||||||
*/
|
*/
|
||||||
dispatch(payload, sync) {
|
dispatch(payload, sync) {
|
||||||
|
// Allow for asynchronous dispatching by accepting payloads that have the
|
||||||
|
// type `function (dispatch) {...}`
|
||||||
|
if (typeof payload === 'function') {
|
||||||
|
payload((action) => {
|
||||||
|
this.dispatch(action, sync);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
super.dispatch(payload);
|
super.dispatch(payload);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue