@applicaster/quick-brick-core
Version:
Core package for Applicaster's Quick Brick App
130 lines (107 loc) • 3.72 kB
text/typescript
import * as R from "ramda";
import isEmpty from "lodash/isEmpty";
import { Dimensions, NativeModules } from "react-native";
import {
loadAppContextData,
AppData,
} from "@applicaster/zapp-react-native-redux";
import { isTablet } from "@applicaster/zapp-react-native-utils/reactHooks";
import { mapPromises } from "@applicaster/zapp-react-native-utils/arrayUtils";
import { fetchPluginConfiguration, getPromiseForType } from "../helpers";
import { cacheAssets } from "../../AssetCache";
import { logger } from "@applicaster/zapp-react-native-utils/logger";
import { ACTIVE_LAYOUT_ID_STORAGE_KEY } from "../consts";
const { AppLoaderBridge } = NativeModules;
import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
import { useErrorStore } from "../../ErrorBoundary/store";
export async function getNativeRemoteContextData(
dispatch,
runtimeConfigurationUrls,
plugins
) {
const { width, height } = Dimensions.get("window");
const isTabletDevice = isTablet(
{ width, height },
width > height ? "landscape" : "portrait"
);
const generalConfiguration = await mapPromises(getPromiseForType, [
"remoteConfigurations",
"pluginConfigurations",
"pipesEndpoints",
]);
loadAppContextData(dispatch, R.mergeAll([...generalConfiguration]));
try {
const layoutManagerPlugin = R.find(
R.pathSatisfies(R.is(Function), ["module", "selectLayout"])
)(plugins);
if (layoutManagerPlugin) {
await layoutManagerPlugin.module?.selectLayout({
runtimeConfigurationUrls,
plugin: layoutManagerPlugin,
isTablet: isTabletDevice,
});
} else {
const layoutId = await localStorage.getItem(ACTIVE_LAYOUT_ID_STORAGE_KEY);
if (layoutId) {
await AppLoaderBridge?.switchLayout(layoutId, null);
}
}
} catch (error) {
logger.error({
message: "Error selecting layout using layout manager plugin",
data: error,
});
}
const layout = await getPromiseForType("layout");
const layoutLoadingErrorMessage = "Failed to load layout data";
if (isEmpty(layout)) {
useErrorStore
.getState()
.setError(
new Error(layoutLoadingErrorMessage),
layoutLoadingErrorMessage,
false
);
}
const apiVersion = layout?.layout?.["api_version"]; // Taken from remote configuration
dispatch(AppData.actions.merge({ layoutVersion: apiVersion || "v1" }));
const resolvedPromises = await mapPromises(getPromiseForType, ["cellStyles"]);
let optionalResolvedPromise;
try {
optionalResolvedPromise = await getPromiseForType("presetsMapping");
} catch (e) {
// don't break loading sequence if presetsMapping does not exist
// only general error could be intercepted here so no way divide flow
}
const remoteData = R.mergeAll([
...resolvedPromises,
...generalConfiguration,
optionalResolvedPromise,
layout,
]);
const cachedRemoteData = await cacheAssets({
layout: remoteData.layout,
pluginConfigurations: remoteData.pluginConfigurations,
cellStyles: remoteData.cellStyles,
});
const { pluginConfigurations } = cachedRemoteData;
const updatedPlugins = R.map(
fetchPluginConfiguration(pluginConfigurations),
plugins
);
const appProperties = R.compose(
R.mergeLeft({
contentTypes: remoteData.layout?.content_types,
rivers: cachedRemoteData.layout,
cellStyles: cachedRemoteData.cellStyles,
}),
R.omit(["layout"])
)(remoteData);
if (remoteData.presetsMapping) {
appProperties.presetsMapping = remoteData.presetsMapping;
}
loadAppContextData(dispatch, {
...appProperties,
plugins: updatedPlugins,
});
}