@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
172 lines (142 loc) • 4.16 kB
text/typescript
import * as R from "ramda";
import { getNamespaceAndKey } from "../appUtils/contextKeysManager/utils";
import { createLogger } from "../logger";
const { log_error, log_verbose } = createLogger({
subsystem: "FeedDecorator",
category: "General",
});
function getScope(scope) {
if (scope === "screen") {
return scope;
} else if (!scope || scope === "ctx") {
return "ctx";
} else {
log_verbose(
`decorateFeed: Unsupported scope "${scope}" provided in preference_editor_options. Defaulting to "ctx".`
);
return "ctx";
}
}
function makeMultiSelect(feed: ZappFeed, key, decoratedFeed) {
const scope = getScope(
decoratedFeed.extensions?.preference_editor_options?.scope
);
const behavior = {
...feed.extensions?.["behavior"],
select_mode: "multi",
current_selection: `@{${scope}/${key}}`,
};
if (!feed.extensions) {
decoratedFeed.extensions = {
behavior,
};
} else {
decoratedFeed.extensions.behavior = behavior;
}
const actionType =
decoratedFeed.extensions?.preference_editor_options?.scope === "screen"
? "screenToggleFlag"
: decoratedFeed.extensions?.preference_editor_options?.scope === "session"
? "sessionStorageToggleFlag"
: "localStorageToggleFlag";
decoratedFeed.entry?.forEach((entry: ZappEntry) => {
entry.type.value = "action";
entry.id = entry.extensions?.tag || entry.id;
entry.extensions = {
...(entry.extensions || {}),
tap_actions: {
actions: [
{
type: actionType,
options: {
key,
},
},
],
},
};
});
return decoratedFeed;
}
function makeSingleSelect(feed: ZappFeed, key, decoratedFeed) {
const scope = getScope(
decoratedFeed.extensions?.preference_editor_options?.scope
);
const behavior = {
...feed.extensions?.["behavior"],
select_mode: "single",
current_selection: `@{${scope}/${key}}`,
};
if (!feed.extensions) {
decoratedFeed.extensions = {
behavior,
};
} else {
decoratedFeed.extensions.behavior = behavior;
}
const localStorageProducer = (entry: ZappFeed) => {
entry.id = entry.extensions?.tag || entry.id;
const { key: keyName, namespace } = getNamespaceAndKey(key);
const action =
decoratedFeed.extensions?.preference_editor_options?.scope === "session"
? "sessionStorageSet"
: "localStorageSet";
return {
type: action,
options: {
content: {
[namespace]: {
[keyName]: entry.id,
},
},
},
};
};
const screenStateProducer = (entry: ZappFeed) => {
entry.id = entry.extensions?.tag || entry.id;
return {
type: "screenSetVariable",
options: {
key,
value: entry.id,
},
};
};
const producer =
decoratedFeed.extensions?.preference_editor_options?.scope === "screen"
? screenStateProducer
: localStorageProducer;
decoratedFeed.entry?.forEach((entry: ZappEntry) => {
entry.type.value = "action";
entry.extensions = {
...(entry.extensions || {}),
tap_actions: {
actions: [producer(entry)],
},
};
});
return decoratedFeed;
}
export const decorateFeed = (feed: ZappFeed) => {
if (!(feed.extensions?.["role"] === "preference_editor")) {
return feed;
}
const key = feed.extensions?.["preference_editor_options"]?.["key"];
if (!key) {
log_error(
`decorateFeed: No 'key' provided in feed titled "${feed.title}" with id "${feed.id}" in preference_editor_options. The preference_editor role requires a key for local storage.`
);
throw new Error(
"decorateFeed: No 'key' provided in feed preference_editor_options"
);
}
const decoratedFeed = R.clone(feed);
const isSingleSelect =
(feed.extensions?.["preference_editor_options"]?.select_mode ||
feed.extensions?.["behavior"]?.select_mode) === "single";
if (isSingleSelect) {
return makeSingleSelect(feed, key, decoratedFeed);
} else {
return makeMultiSelect(feed, key, decoratedFeed);
}
};