@applicaster/zapp-react-dom-app
Version:
Zapp App Component for Applicaster's Quick Brick React Native App
116 lines (100 loc) • 4.27 kB
JavaScript
// @flow
import * as R from "ramda";
import { NativeModules } from "react-native";
import uuidv4 from "uuid/v4";
import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
import { mapKeys } from "@applicaster/zapp-react-native-utils/objectUtils";
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
import { renameKeys, getDeviceData } from "./utils/platform";
import { desiredKeysMap } from "./utils/const";
/**
* Gets all of the plugins that you pass to it, or all of the plugins in the appStore
* and loads them into session storage, if the value is null or undefined it will skip the key
* If the key is malformed it will skip it as well
*/
export const loadPluginDataIntoSession = async (plugins = null) => {
try {
const pluginsToLoad = plugins || appStore.get("plugins");
if (Array.isArray(pluginsToLoad)) {
pluginsToLoad.forEach((plugin) => {
if (!plugin || !plugin.identifier || !plugin.configuration) return;
Object.entries(plugin.configuration).forEach(([key, value]) => {
if (isEmptyOrNil(key) || value === null || value === undefined) {
return;
}
sessionStorage.setItem(key, value, plugin.identifier);
});
});
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(
"loadSessionStorageData: Error loading plugin data into session storage",
error
);
}
};
/**
* Gathers data from various sources including device data, Native Modules,
* and session storage. Merges them and returns as a single object.
* We specifically exclude layoutId because it is loaded in middleware
* https://github.com/applicaster/QuickBrick/blob/main/packages/zapp-react-native-redux/middlewares/riversLoader.js#L24-L25
* @async
* @param {string} uuid - The UUID to be set if not already present in local storage.
* @returns {Promise<Object>} The gathered data object.
* @throws Will throw an error if any of the data-gathering steps fail.
*/
async function gatherData(uuid) {
const deviceData = await getDeviceData();
const { languageLocale, countryLocale } =
NativeModules?.QuickBrickCommunicationModule || {};
const sessionStorageData = {
// Build time values
...NativeModules?.QuickBrickCommunicationModule,
// Device data retrieved from native device apis
...deviceData,
uuid: uuid || uuidv4(),
locale: `{language=${languageLocale}, country=${countryLocale}}`,
};
return sessionStorageData;
}
/**
* Stores the given data object into session storage. The stored keys are
* determined by the provided `desiredKeys` map, which may rename the keys.
*
* @param {Object} data - The data object to be stored.
* @param {Object} desiredKeys - The map of original key names to desired key names.
*/
function storeData(data, desiredKeys) {
// Pick only the keys we want and need, map them to the correct name, and reject any unusuable data
const filteredData = R.compose(
R.reject(isEmptyOrNil),
R.reject(R.either(R.is(Object), R.is(Function))),
mapKeys(renameKeys),
R.pick(Object.keys(desiredKeys))
)(data);
R.forEachObjIndexed((value, key) => {
if (key === "uuid") {
localStorage.setItem(key, value);
}
sessionStorage.setItem(key, value);
}, filteredData);
}
/**
* This method gathers all of the info we can get from device, user agent, and the QB communication module
* and loads them into session storage. You could pass an object with the keys you want and the value is how you want it to be named
* or stored in session storage. If you don't pass anything it will use the desiredKeysMap from utils/const.js
*/
export async function loadSessionStorageData(desiredKeys = desiredKeysMap) {
try {
const uuid = await localStorage.getItem("uuid");
const data = await gatherData(uuid);
storeData(data, desiredKeys);
loadPluginDataIntoSession();
} catch (error) {
// eslint-disable-next-line no-console
console.error("Error loading data into session storage", error);
}
}