UNPKG

@livelike/react-native

Version:

LiveLike React Native package

118 lines (111 loc) 3.7 kB
import { useCallback, useRef } from 'react'; import { IWidgetOptionItem, hasDebugLogger } from '@livelike/javascript'; import { useWidgetActions } from './useWidgetActions'; import { useWidgetInteractionActions } from './useWidgetInteractionActions'; import { useWidgetInteractions } from './useWidgetInteractions'; import { useWidgetOptions } from './useWidgetOptions'; import { useWidgetInteractedAnalytics } from './useWidgetInteractedAnalytics'; export type UseCheerMeterOnOptionPressArg = { widgetId: string; optionIndex: number; throttleTime: number; }; export const useCheerMeterOnOptionPress = ({ widgetId, optionIndex, throttleTime, }: UseCheerMeterOnOptionPressArg) => { const throttleRef = useRef({ prevDateTime: undefined, timeout: undefined, cacheVoteCount: 0, }); const widgetOptions = useWidgetOptions({ widgetId }); const { createWidgetInteractionAction, updateWidgetInteractionAction } = useWidgetInteractionActions({ widgetId }); const { updateWidgetOptionsAction } = useWidgetActions({ widgetId }); const widgetOption = widgetOptions?.[optionIndex]; const widgetInteractions = useWidgetInteractions({ widgetId }); const { trackWidgetInteractedAction } = useWidgetInteractedAnalytics({ widgetId, }); const hasInteractedOption = !!widgetInteractions?.find( ({ option_id }) => option_id === widgetOption?.id ); return useCallback(() => { let { timeout, prevDateTime, cacheVoteCount } = throttleRef.current; const now = Date.now(); clearTimeout(timeout); throttleRef.current.cacheVoteCount = cacheVoteCount + 1; if (!prevDateTime || now - prevDateTime >= throttleTime) { updateCount(); prevDateTime = now; } else { timeout = setTimeout( () => updateCount(), throttleTime - (now - prevDateTime) ); } throttleRef.current = { prevDateTime, timeout, cacheVoteCount: throttleRef.current.cacheVoteCount, }; function updateCount() { const interactionItem = { ...widgetOptions[optionIndex], vote_count: throttleRef.current.cacheVoteCount, }; trackWidgetInteractedAction<IWidgetOptionItem>({ interactionItem: widgetOptions[optionIndex], }); throttleRef.current = { ...throttleRef.current, // reset cache vote count cacheVoteCount: 0, }; (hasInteractedOption ? updateWidgetInteractionAction({ interactionItem }) : createWidgetInteractionAction({ interactionItem }) ) .then((res) => { if (!res) { return; } const updatedOptions = widgetOptions.map((option) => ({ ...option })); updatedOptions[optionIndex] = { ...updatedOptions[optionIndex], vote_count: updatedOptions[optionIndex].vote_count + interactionItem.vote_count, }; updateWidgetOptionsAction({ widgetId, widgetOptions: updatedOptions, }); }) .catch((e) => { hasDebugLogger() && console.error( `Error while ${ hasInteractedOption ? 'updating' : 'creating' } interaction`, e ); // add earlier cache vote count back throttleRef.current = { ...throttleRef.current, // reset cache vote count cacheVoteCount: interactionItem.vote_count, }; }); } }, [ throttleRef.current, optionIndex, hasInteractedOption, widgetOptions, updateWidgetInteractionAction, createWidgetInteractionAction, ]); };