2021-10-17 10:36:14 +02:00
|
|
|
// @flow
|
2021-12-23 09:27:03 +01:00
|
|
|
import * as ACTIONS from 'constants/action_types';
|
2021-10-17 10:36:14 +02:00
|
|
|
import isEqual from 'util/deep-equal';
|
|
|
|
import { doPreferenceSet } from 'redux/actions/sync';
|
|
|
|
|
|
|
|
const RUN_PREFERENCES_DELAY_MS = 2000;
|
|
|
|
const SHARED_PREFERENCE_VERSION = '0.1';
|
2022-07-13 15:36:51 +02:00
|
|
|
|
2021-10-17 10:36:14 +02:00
|
|
|
let oldShared = {};
|
|
|
|
let timeout;
|
2022-07-13 15:36:51 +02:00
|
|
|
|
2021-10-17 10:36:14 +02:00
|
|
|
export const buildSharedStateMiddleware = (
|
|
|
|
actions: Array<string>,
|
|
|
|
sharedStateFilters: {},
|
|
|
|
sharedStateCb?: (any) => void
|
2022-07-13 15:36:51 +02:00
|
|
|
) => ({ getState, dispatch }: { getState: GetState, dispatch: Dispatch }) => (next: ({}) => void) => (action: {
|
|
|
|
type: string,
|
|
|
|
data: any,
|
|
|
|
}) => {
|
2021-10-17 10:36:14 +02:00
|
|
|
// We don't care if sync is disabled here, we always want to backup preferences to the wallet
|
|
|
|
if (!actions.includes(action.type) || typeof action === 'function') {
|
|
|
|
return next(action);
|
|
|
|
}
|
2022-07-13 15:36:51 +02:00
|
|
|
|
2021-10-17 10:36:14 +02:00
|
|
|
clearTimeout(timeout);
|
|
|
|
const actionResult = next(action);
|
2022-07-13 15:36:51 +02:00
|
|
|
|
2021-10-17 10:36:14 +02:00
|
|
|
// Call `getState` after calling `next` to ensure the state has updated in response to the action
|
|
|
|
function runPreferences() {
|
2022-07-13 15:36:51 +02:00
|
|
|
const nextState = getState();
|
|
|
|
const syncEnabled = nextState?.settings?.clientSettings?.enable_sync;
|
|
|
|
const hasVerifiedEmail = nextState?.user?.user?.has_verified_email;
|
|
|
|
const prefsReady = nextState?.sync.prefsReady;
|
|
|
|
const preferenceKey = syncEnabled && hasVerifiedEmail && prefsReady ? 'shared' : 'local';
|
2021-10-17 10:36:14 +02:00
|
|
|
const shared = {};
|
|
|
|
|
|
|
|
Object.keys(sharedStateFilters).forEach((key) => {
|
|
|
|
const filter = sharedStateFilters[key];
|
|
|
|
const { source, property, transform } = filter;
|
|
|
|
let value = nextState[source][property];
|
|
|
|
if (transform) {
|
|
|
|
value = transform(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
shared[key] = value;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!isEqual(oldShared, shared)) {
|
|
|
|
// only update if the preference changed from last call in the same session
|
|
|
|
oldShared = shared;
|
|
|
|
dispatch(doPreferenceSet(preferenceKey, shared, SHARED_PREFERENCE_VERSION));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sharedStateCb) {
|
|
|
|
// Pass dispatch to the callback to consumers can dispatch actions in response to preference set
|
2021-12-23 09:27:03 +01:00
|
|
|
sharedStateCb({ dispatch, getState, syncId: timeout });
|
2021-10-17 10:36:14 +02:00
|
|
|
}
|
|
|
|
clearTimeout(timeout);
|
|
|
|
return actionResult;
|
|
|
|
}
|
2021-12-23 09:27:03 +01:00
|
|
|
|
2021-10-17 10:36:14 +02:00
|
|
|
timeout = setTimeout(runPreferences, RUN_PREFERENCES_DELAY_MS);
|
2021-12-23 09:27:03 +01:00
|
|
|
dispatch({ type: ACTIONS.SHARED_STATE_SYNC_ID_CHANGED, data: timeout });
|
2021-10-17 10:36:14 +02:00
|
|
|
};
|