diff --git a/src/libs/Middleware/SaveResponseInOnyx.js b/src/libs/Middleware/SaveResponseInOnyx.js index b347e45ab61c..28b8a93fb585 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.js +++ b/src/libs/Middleware/SaveResponseInOnyx.js @@ -1,6 +1,9 @@ import Onyx from 'react-native-onyx'; +import _ from 'underscore'; import CONST from '../../CONST'; +import ONYXKEYS from '../../ONYXKEYS'; import * as QueuedOnyxUpdates from '../actions/QueuedOnyxUpdates'; +import * as MemoryOnlyKeys from '../actions/MemoryOnlyKeys/MemoryOnlyKeys'; import * as OnyxUpdates from '../actions/OnyxUpdates'; /** @@ -15,6 +18,27 @@ function SaveResponseInOnyx(response, request) { return; } + // The data for this response comes in two different formats: + // 1. Original format - this is what was sent before the RELIABLE_UPDATES project and will go away once RELIABLE_UPDATES is fully complete + // - The data is an array of objects, where each object is an onyx update + // Example: [{onyxMethod: 'whatever', key: 'foo', value: 'bar'}] + // 1. Reliable updates format - this is what was sent with the RELIABLE_UPDATES project and will be the format from now on + // - The data is an object, containing updateIDs from the server and an array of onyx updates (this array is the same format as the original format above) + // Example: {lastUpdateID: 1, previousUpdateID: 0, onyxData: [{onyxMethod: 'whatever', key: 'foo', value: 'bar'}]} + // NOTE: This is slightly different than the format of the pusher event data, where pusher has "updates" and HTTPS responses have "onyxData" (long story) + + // Supports both the old format and the new format + const onyxUpdates = _.isArray(responseData) ? responseData : responseData.onyxData; + // If there is an OnyxUpdate for using memory only keys, enable them + _.find(onyxUpdates, ({key, value}) => { + if (key !== ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS || !value) { + return false; + } + + MemoryOnlyKeys.enable(); + return true; + }); + // Save the update IDs to Onyx so they can be used to fetch incremental updates if the client gets out of sync from the server OnyxUpdates.saveUpdateIDs(Number(responseData.lastUpdateID || 0), Number(responseData.previousUpdateID || 0)); diff --git a/src/libs/actions/MemoryOnlyKeys/MemoryOnlyKeys.js b/src/libs/actions/MemoryOnlyKeys/MemoryOnlyKeys.js new file mode 100644 index 000000000000..d46222189804 --- /dev/null +++ b/src/libs/actions/MemoryOnlyKeys/MemoryOnlyKeys.js @@ -0,0 +1,19 @@ +import Onyx from 'react-native-onyx'; +import ONYXKEYS from '../../../ONYXKEYS'; +import Log from '../../Log'; + +const memoryOnlyKeys = [ONYXKEYS.COLLECTION.REPORT, ONYXKEYS.COLLECTION.POLICY, ONYXKEYS.PERSONAL_DETAILS_LIST]; + +const enable = () => { + Log.info('[MemoryOnlyKeys] enabled'); + Onyx.set(ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, true); + Onyx.setMemoryOnlyKeys(memoryOnlyKeys); +}; + +const disable = () => { + Log.info('[MemoryOnlyKeys] disabled'); + Onyx.set(ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, false); + Onyx.setMemoryOnlyKeys([]); +}; + +export {disable, enable}; diff --git a/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.js b/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.js new file mode 100644 index 000000000000..fa62268753db --- /dev/null +++ b/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.js @@ -0,0 +1,12 @@ +import * as MemoryOnlyKeys from '../MemoryOnlyKeys'; + +const exposeGlobalMemoryOnlyKeysMethods = () => { + window.enableMemoryOnlyKeys = () => { + MemoryOnlyKeys.enable(); + }; + window.disableMemoryOnlyKeys = () => { + MemoryOnlyKeys.disable(); + }; +}; + +export default exposeGlobalMemoryOnlyKeysMethods; diff --git a/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.native.js b/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.native.js new file mode 100644 index 000000000000..9d08b9db6aa4 --- /dev/null +++ b/src/libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods/index.native.js @@ -0,0 +1,6 @@ +/** + * This is a no-op because the global methods will only work for web and desktop + */ +const exposeGlobalMemoryOnlyKeysMethods = () => {}; + +export default exposeGlobalMemoryOnlyKeysMethods; diff --git a/src/libs/actions/User.js b/src/libs/actions/User.js index 9648b77220ac..b77c5b278bc9 100644 --- a/src/libs/actions/User.js +++ b/src/libs/actions/User.js @@ -548,8 +548,13 @@ function subscribeToUserEvents() { PusherUtils.subscribeToPrivateUserChannelEvent(Pusher.TYPE.MULTIPLE_EVENTS, currentUserAccountID, (pushJSON) => { let updates; - // This is the old format where each update was just an array, with the new changes it's an object with - // lastUpdateID, previousUpdateID and updates + // The data for this push event comes in two different formats: + // 1. Original format - this is what was sent before the RELIABLE_UPDATES project and will go away once RELIABLE_UPDATES is fully complete + // - The data is an array of objects, where each object is an onyx update + // Example: [{onyxMethod: 'whatever', key: 'foo', value: 'bar'}] + // 1. Reliable updates format - this is what was sent with the RELIABLE_UPDATES project and will be the format from now on + // - The data is an object, containing updateIDs from the server and an array of onyx updates (this array is the same format as the original format above) + // Example: {lastUpdateID: 1, previousUpdateID: 0, updates: [{onyxMethod: 'whatever', key: 'foo', value: 'bar'}]} if (_.isArray(pushJSON)) { updates = pushJSON; } else { @@ -568,6 +573,7 @@ function subscribeToUserEvents() { if (!currentUserAccountID) { return; } + Onyx.update(pushJSON); triggerNotifications(pushJSON); }); diff --git a/src/pages/signin/LoginForm.js b/src/pages/signin/LoginForm.js index 84f9c9d529bf..bc14a5844f09 100644 --- a/src/pages/signin/LoginForm.js +++ b/src/pages/signin/LoginForm.js @@ -32,6 +32,7 @@ import * as PolicyUtils from '../../libs/PolicyUtils'; import Log from '../../libs/Log'; import withNavigationFocus, {withNavigationFocusPropTypes} from '../../components/withNavigationFocus'; import usePrevious from '../../hooks/usePrevious'; +import * as MemoryOnlyKeys from '../../libs/actions/MemoryOnlyKeys/MemoryOnlyKeys'; const propTypes = { /** Should we dismiss the keyboard when transitioning away from the page? */ @@ -74,13 +75,6 @@ const defaultProps = { blurOnSubmit: false, }; -/** - * Enables experimental "memory only keys" mode in Onyx - */ -const setEnableMemoryOnlyKeys = () => { - window.enableMemoryOnlyKeys(); -}; - function LoginForm(props) { const input = useRef(); const [login, setLogin] = useState(''); @@ -149,7 +143,7 @@ function LoginForm(props) { // If the user has entered a guide email, then we are going to enable an experimental Onyx mode to help with performance if (PolicyUtils.isExpensifyGuideTeam(loginTrim)) { Log.info('Detected guide email in login field, setting memory only keys.'); - setEnableMemoryOnlyKeys(); + MemoryOnlyKeys.enable(); } setFormError(null); diff --git a/src/setup/index.js b/src/setup/index.js index d49baf25c0d7..5e92bff35ba1 100644 --- a/src/setup/index.js +++ b/src/setup/index.js @@ -6,6 +6,7 @@ import platformSetup from './platformSetup'; import * as Metrics from '../libs/Metrics'; import * as Device from '../libs/actions/Device'; import intlPolyfill from '../libs/IntlPolyfill'; +import exposeGlobalMemoryOnlyKeysMethods from '../libs/actions/MemoryOnlyKeys/exposeGlobalMemoryOnlyKeysMethods'; export default function () { /* @@ -42,18 +43,7 @@ export default function () { }, }); - // When enabled we will skip persisting to disk any server-side downloaded objects (e.g. workspaces, chats, etc) that can hog up a user's resources. - window.enableMemoryOnlyKeys = () => { - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.set(ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, true); - Onyx.setMemoryOnlyKeys([ONYXKEYS.COLLECTION.REPORT, ONYXKEYS.COLLECTION.POLICY, ONYXKEYS.PERSONAL_DETAILS_LIST]); - }; - - window.disableMemoryOnlyKeys = () => { - // eslint-disable-next-line rulesdir/prefer-actions-set-data - Onyx.set(ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS, false); - Onyx.setMemoryOnlyKeys([]); - }; + exposeGlobalMemoryOnlyKeysMethods(); Device.setDeviceID();