79 lines
2.1 KiB
JavaScript
79 lines
2.1 KiB
JavaScript
|
/* @flow */
|
||
|
|
||
|
import Flux from 'flux';
|
||
|
import Store from './lib/flux/Store';
|
||
|
import type {Action} from './flow/Action';
|
||
|
|
||
|
type Interceptor = (payload: mixed) => boolean;
|
||
|
|
||
|
export class Dispatcher<Action> extends Flux.Dispatcher<Action> {
|
||
|
_interceptor: ?Interceptor;
|
||
|
_afterDispatch: ?Function;
|
||
|
|
||
|
// Super hacky but to avoid forking and rewriting Facebook's Flux Dispatcher
|
||
|
// this is a way to hook into the dispatch call's cleanup method to trigger
|
||
|
// all the stores' at the same time. This makes it so setState is going to
|
||
|
// be the same on all emits and `shouldComponentUpdate1 will be even more
|
||
|
// effective.
|
||
|
_stopDispatching(...args: Array<any>) {
|
||
|
try {
|
||
|
Store.emitChanges();
|
||
|
} finally {
|
||
|
super._stopDispatching(...args);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use this in situations where a user action should trigger a Dispatch but
|
||
|
* an action that occurs during a dispatch does not need to trigger it.
|
||
|
*/
|
||
|
maybeDispatch(payload: Action) {
|
||
|
if (!this.isDispatching()) {
|
||
|
this.dispatch(payload);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Use this to Dispatch in a situation where you have no other choice but to
|
||
|
* defer it to the next event loop tick. This should be used in VERY special cases
|
||
|
* because it can result in performance issues.
|
||
|
*/
|
||
|
dirtyDispatch(payload: Action) {
|
||
|
if (this.isDispatching()) {
|
||
|
setImmediate(this.dispatch.bind(this, payload));
|
||
|
} else {
|
||
|
this.dispatch(payload);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Dispatches a payload to all registered callbacks.
|
||
|
*/
|
||
|
dispatch(payload: Action) {
|
||
|
if (this._interceptor == null || !this._interceptor(payload)) {
|
||
|
super.dispatch(payload);
|
||
|
this._afterDispatch && this._afterDispatch();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set interceptor that might consume payloads.
|
||
|
*/
|
||
|
setInterceptor(interceptor: ?Interceptor) {
|
||
|
this._interceptor = interceptor;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set a callback to run after a dispatch.
|
||
|
*/
|
||
|
setAfterDispatch(callback: ?Function) {
|
||
|
this._afterDispatch = callback;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export default (new Dispatcher(): Dispatcher<Action>);
|
||
|
|
||
|
|
||
|
|
||
|
// WEBPACK FOOTER //
|
||
|
// ./discord_app/Dispatcher.js
|