diff --git a/app/store/index.js b/app/store/index.js index e1fce8ba6..753a27b15 100644 --- a/app/store/index.js +++ b/app/store/index.js @@ -15,6 +15,7 @@ import {NavigationTypes, ViewTypes} from 'app/constants'; import appReducer from 'app/reducers'; import networkConnectionListener from 'app/utils/network'; import {createSentryMiddleware} from 'app/utils/sentry/middleware'; +import {promiseTimeout} from 'app/utils/promise_timeout'; import {messageRetention} from './middleware'; import {transformSet} from './utils'; @@ -102,6 +103,22 @@ export default function configureAppStore(initialState) { ); const offlineOptions = { + effect: (effect, action) => { + if (typeof effect !== 'function') { + throw new Error('Offline Action: effect must be a function.'); + } else if (!action.meta.offline.commit) { + throw new Error('Offline Action: commit action must be present.'); + } + + if (action.meta.offline.canTimeout) { + const defaultTimeout = 10000; + const timeout = action.meta.offline.timeout || defaultTimeout; + + return promiseTimeout(effect(), timeout); + } + + return effect(); + }, detectNetwork: (callback) => networkConnectionListener(callback), persist: (store, options) => { const persistor = persistStore(store, {storage: AsyncStorage, ...options}, () => { diff --git a/app/utils/promise_timeout.js b/app/utils/promise_timeout.js new file mode 100644 index 000000000..3023872a5 --- /dev/null +++ b/app/utils/promise_timeout.js @@ -0,0 +1,16 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +export function promiseTimeout(promise, ms) { + const timeout = new Promise((resolve, reject) => { + const id = setTimeout(() => { + clearTimeout(id); + reject('Timed out in ' + ms + 'ms.'); + }, ms); + }); + + return Promise.race([ + promise, + timeout + ]); +}