import React, { useCallback, useEffect } from "react"; import { TouchableOpacity, ViewStyle } from "react-native"; import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions"; import { useUIComponentContext } from "@applicaster/zapp-react-native-ui-components/Contexts/UIComponentContext"; import Image from "./Image"; type Props = { item: ZappEntry | ZappFeed; flavour?: "flavour_1" | "flavour_2"; asset?: { props: {}; src: { active: string; inactive: string; } & Record; style: {}; type: "Image" | "Svg" | "Lottie"; }; action: { identifier: string; type?: string; }; style: ViewStyle; testID?: string; accessibilityLabel?: string; accessibilityHint?: string; cellUUID?: string; extraProps?: Record; }; function isStringAsset(asset) { return typeof asset === "string" || Array.isArray(asset); } function getAssetValue(asset, flavour, fallbackAsset = null) { if (!asset) { return null; } if (typeof asset === "string") return asset; if (Array.isArray(asset)) { const flavourIndex = Number(flavour.replace("flavour_", "")); if (flavour && flavourIndex > -1) return asset[flavourIndex - 1]; return asset[0]; } return asset.src || fallbackAsset; } export const ActionButton = React.memo(function ActionButtonComponent( props: Props ) { const { item, action, asset, flavour = "flavour_1", cellUUID } = props; const actionContext = useActions(action?.identifier); const component = useUIComponentContext(); // TODO: add subscription API for action availability const actionDisabled = typeof actionContext?.isActionAvailable === "function" && !actionContext.isActionAvailable(item); // Note: in theory initialization is not needed anymore, we are using useEffect const [actionState, setActionState] = React.useState( actionDisabled || !actionContext ? null : actionContext.initialEntryState(item) ); useEffect(() => { if (!((actionDisabled || !actionContext) && actionState !== null)) { setActionState(actionContext.initialEntryState(item)); } }, [actionDisabled, item?.id, actionContext, action, setActionState]); const onPress = useCallback(() => { actionContext.invokeAction(item, { updateState: (state) => { setActionState(state); }, ...(component ? { component } : {}), }); }, [actionState, actionContext?.state, item, component]); useEffect(() => { if (typeof actionContext?.addListener === "function") { return actionContext?.addListener(String(item.id), (state) => { setActionState(state); }); } }, [item?.id, setActionState, actionContext]); if (actionDisabled || !actionContext) return null; const AssetComponent = actionState?.asset; // Default state is not yet ready if (!AssetComponent) return null; return ( {isStringAsset(actionState.asset) ? ( ) : ( )} ); });