@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
129 lines (106 loc) • 3.75 kB
text/typescript
/// <reference types="@applicaster/applicaster-types" />
import * as React from "react";
import * as R from "ramda";
import { handleActionSchemeUrl } from "@applicaster/quick-brick-core/App/DeepLinking/URLSchemeHandler/SchemeHandlerHooks/useUrlSchemeHandler";
import { CellTapContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellTapContext";
import {
useNavigation,
useProfilerLogging,
useRoute,
} from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import { ZappPipesEntryContext } from "@applicaster/zapp-react-native-ui-components/Contexts";
import { toBooleanWithDefaultTrue } from "@applicaster/zapp-react-native-utils/booleanUtils";
import { ActionExecutorContext } from "@applicaster/zapp-react-native-utils/actionsExecutor/ActionExecutorContext";
import { isFunction, noop } from "../../functionUtils";
import { useSendAnalyticsOnPress } from "../analytics";
import { logOnPress, warnEmptyContentType } from "./helpers";
/**
* If onCellTap is defined execute the function and
* skip default logic.
* @return void
*/
type Props = {
item?: ZappEntry;
index?: number;
component?: ZappUIComponent;
zappPipesData?: ZappPipesData;
};
type onPressReturnFn =
| ((_item?: ZappEntry | any, _index?: number) => Promise<void>)
| (() => void);
export const useCellClick = ({
component,
zappPipesData,
item,
}: Props): onPressReturnFn => {
const { push, currentRoute } = useNavigation();
const { pathname } = useRoute();
const onCellTap: Option<Function> = React.useContext(CellTapContext);
const actionExecutor = React.useContext(ActionExecutorContext);
const cellSelectable = toBooleanWithDefaultTrue(
component?.rules?.component_cells_selectable
);
const [__, setEntryContext] =
ZappPipesEntryContext.useZappPipesContext(pathname);
const logTimestamp = useProfilerLogging();
const sendAnalyticsOnPress = useSendAnalyticsOnPress(
item,
component,
zappPipesData
);
const onPress = React.useCallback(
async (_item?: ZappEntry | any, _index?: number) => {
// Making sure we are not getting GestureResponderEvent in here.
const isZappEntry = _item?.id && _item?.type;
const selectedItem = isZappEntry ? _item : item;
setEntryContext?.(selectedItem);
if (!selectedItem?.type?.value) {
warnEmptyContentType(selectedItem);
}
sendAnalyticsOnPress(selectedItem, _index ?? 0);
logTimestamp(selectedItem?.id?.toString());
logOnPress(selectedItem, pathname, component, onCellTap);
if (selectedItem) {
await actionExecutor?.handleEntryActions(selectedItem);
}
if (selectedItem?.type?.value === "action") {
if (selectedItem?.link?.href) {
handleActionSchemeUrl({
url: selectedItem.link.href,
});
}
} else {
if (isFunction(onCellTap)) {
onCellTap?.(selectedItem, _index);
} else {
if (currentRoute === pathname || pathname.includes("video-modal")) {
const targetScreen = component?.data?.target;
push(
R.when(
() => targetScreen,
R.mergeLeft({ screen_type: targetScreen })
)(selectedItem)
);
}
}
}
},
[
onCellTap,
currentRoute,
setEntryContext,
pathname,
push,
sendAnalyticsOnPress,
]
);
const onPressRef = React.useRef<onPressReturnFn>();
if (!cellSelectable) {
// update ref with dummy function
onPressRef.current = noop;
} else {
// update ref with the latest onPress function
onPressRef.current = onPress;
}
return React.useCallback(onPressRef.current, []);
};