@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
190 lines (163 loc) • 4.69 kB
text/typescript
import * as R from "ramda";
import { useMemo } from "react";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
// importing this way prevents typescript packages importing from this
// file to go crazy reporting errors on JS
import { populateConfigurationValues } from "@applicaster/zapp-react-native-utils/configurationUtils";
import { useLocalizedStrings } from "../localizationUtils";
const populateFields = (
data,
manifestFields = [],
pathToValues: string | string[] = "configuration",
skipDefaults = false
) =>
R.compose(
(config) =>
populateConfigurationValues(manifestFields, config, skipDefaults),
R.pathOr({}, R.unless(Array.isArray, Array)(pathToValues))
)(data);
export function parsePluginConfiguration(plugin, manifest) {
return populateFields(plugin, manifest.custom_configuration_fields);
}
export function usePluginConfiguration<T, S>(identifier, manifest) {
const { plugins } = usePickFromState(["plugins"]);
const plugin = useMemo(
() => R.find(R.propEq("identifier", identifier), plugins),
[plugins, identifier]
);
const configurationFields: T = useMemo(
() => populateFields(plugin, manifest?.custom_configuration_fields),
[plugin, manifest]
);
const defaultLocalizations = useMemo(() => {
return (
manifest?.localizations?.fields?.reduce(
(defaults, { key, initial_value }) =>
R.assocPath(["en", key], initial_value, defaults),
{ en: {} }
) || {}
);
}, [manifest]);
const localizationsParams = useMemo(() => {
return {
localizations: R.mergeDeepWith(
(left, right) => {
if (R.isNil(left)) return right;
return left;
},
plugin?.configuration?.localizations,
defaultLocalizations
),
};
}, [plugin?.configuration?.localizations, defaultLocalizations]);
const localizations: S = useLocalizedStrings(localizationsParams);
return useMemo(
() => ({
configurationFields,
localizations,
}),
[configurationFields, localizations]
);
}
type LayoutConfigurationKey =
| "assets"
| "general"
| "styles"
| "advertising"
| "rules"
| "localizations";
// Include the keys in Option types
type Options = {
skipDefaults?: boolean;
keys?: Array<LayoutConfigurationKey>;
};
export function useLayoutConfiguration<
A extends unknown,
S extends unknown,
G extends unknown,
R extends unknown,
L extends unknown,
>(layoutData, manifest, options: Options = {}) {
const keys = options.keys || [
"assets",
"general",
"styles",
"advertising",
"rules",
"localizations",
];
const defaultLocalizations = useMemo(() => {
return (
manifest?.localizations?.fields?.reduce(
(defaults, { key, initial_value }) =>
R.assocPath(["en", key], initial_value, defaults),
{ en: {} }
) || {}
);
}, [manifest]);
const localizationsParams = useMemo(() => {
return {
localizations: R.mergeDeepWith(
(left, right) => {
if (R.isNil(left)) return right;
return left;
},
layoutData?.localizations,
defaultLocalizations
),
};
}, [layoutData?.localizations, defaultLocalizations]);
// Always call useLocalizedStrings regardless of whether localizations is in the keys
const localizations: L = useLocalizedStrings(localizationsParams);
return useMemo(() => {
let assets: A, general: G, styles: S, advertising: R, rules: R;
if (keys.includes("assets")) {
assets = populateFields(
layoutData,
manifest?.assets?.fields,
"assets",
!!options?.skipDefaults
);
}
if (keys.includes("general")) {
general = populateFields(
layoutData,
manifest?.general?.fields,
"general",
!!options?.skipDefaults
);
}
if (keys.includes("styles")) {
styles = populateFields(
layoutData,
manifest?.styles?.fields,
"styles",
!!options?.skipDefaults
);
}
if (keys.includes("advertising")) {
advertising = populateFields(
layoutData,
manifest?.advertising?.fields,
"advertising",
!!options?.skipDefaults
);
}
if (keys.includes("rules")) {
rules = populateFields(
layoutData,
manifest?.rules?.fields,
"rules",
!!options?.skipDefaults
);
}
return {
assets,
general,
styles,
advertising,
rules,
localizations: keys.includes("localizations") ? localizations : undefined,
};
}, [keys.join("")]);
}