UNPKG

@livelike/react-native

Version:

LiveLike React Native package

117 lines (111 loc) 3.72 kB
import { IWidgetEarnableReward, IWidgetInteraction, getRewardTransactions, getTargetedWidgetIdAndKind, } from '@livelike/javascript'; import { useEffect, useRef } from 'react'; import { getWidgetRewardsFromRewardTransactions, widgetStoreActions, } from '../store'; import { useWidgetInteractions } from './useWidgetInteractions'; import { useWidgetKind } from './useWidgetKind'; export type UseLoadWidgetRewardsEffectArg = { widgetId: string; }; export function useLoadWidgetRewardsEffect({ widgetId }) { const widgetInteractions = useWidgetInteractions({ widgetId }); const widgetKind = useWidgetKind({ widgetId }); const interactionsRef = useRef<IWidgetInteraction[] | null>(null); const rewardRef = useRef<IWidgetEarnableReward[] | null>(null); const mountRef = useRef(null); useEffect(() => { // avoid getting reward transactions on initial mount since we are already loading // widget details including reward transaction as part of useLoadWidgetEffect if (!mountRef.current && Array.isArray(widgetInteractions)) { mountRef.current = true; return; } // avoid loading widget rewards if there are no interactions or // widget interaction are same as earlier interaction if (!widgetInteractions?.length) { return; } if ( areWidgetInteractionsSame( widgetInteractions, interactionsRef.current ?? [] ) ) { return; } interactionsRef.current = widgetInteractions; const timeout = setTimeout(() => { getTargetedWidgetIdAndKind({ widgetId, widgetKind }) .then(({ widgetId: targettedWidgetId }) => getRewardTransactions({ widgetIds: [targettedWidgetId] }) ) .then((res) => { const widgetRewards = getWidgetRewardsFromRewardTransactions( res.results ); if ( rewardRef.current && areWidgetRewardsSame(widgetRewards, rewardRef.current) ) { return; } rewardRef.current = widgetRewards; // Observed a behaviour where old reward animation overlap with new reward animation // until old reward animation gets resetted and dereferenced // To avoid overlapping, we clear the existing rewards from state so that // there's no residue of existing reward animation Promise.resolve( widgetStoreActions.updateWidgetRewardsAction({ widgetId, widgetRewards: [], }) ).then(() => widgetStoreActions.updateWidgetRewardsAction({ widgetId, widgetRewards, }) ); }); }, 1000); return () => { clearTimeout(timeout); }; }, [widgetId, widgetKind, widgetInteractions]); } function areWidgetRewardsSame( rewardsA: IWidgetEarnableReward[], rewardsB: IWidgetEarnableReward[] ) { if (rewardsA.length !== rewardsB.length) { return false; } return rewardsA.every((rewardA) => { return !!rewardsB.find( ({ reward_item_id, reward_item_amount }) => rewardA.reward_item_id === reward_item_id && rewardA.reward_item_amount === reward_item_amount ); }); } function areWidgetInteractionsSame( interactionsA: IWidgetInteraction[], interactionsB: IWidgetInteraction[] ) { if (interactionsA.length !== interactionsB.length) { return false; } return interactionsA.every((interactionA) => { return !!interactionsB.find( ({ option_id, choice_id }) => (interactionA.option_id && interactionA.option_id === option_id) || (interactionA.choice_id && interactionA.choice_id === choice_id) ); }); }