@livelike/react-native
Version:
LiveLike React Native package
101 lines (95 loc) • 3.69 kB
text/typescript
import {
getMilliseconds,
SINGLE_INTERACTION_WIDGET_KINDS,
} from '@livelike/javascript';
import { useCallback, useMemo } from 'react';
import { widgetStore } from '../store';
import { WidgetUIPhase } from '../types';
import { useSelectedFieldStore } from './useSelectedFieldStore';
import { useWidgetActions } from './useWidgetActions';
import { useWidgetInteractions } from './useWidgetInteractions';
import { useWidgetKind } from './useWidgetKind';
import { useWidgetUIPhase } from './useWidgetUIPhase';
import { useIsTimelineWidget } from './useIsTimelineWidget';
export type UseWidgetInteractiveTimeoutArg = {
widgetId: string;
/** custom interactiveTimeout, defaults to the timeout value set when creating widget in producer suite */
interactiveTimeout?: number | null;
/** function to be called when widget timeouts */
onInteractiveTimeout?: () => void;
};
export type UseWidgetInteractiveTimeoutResult = {
/** resulted timeout value to be used by LLWidgetHeader */
interactiveTimeout: number | null;
/** resulted timeout handler function to be used by LLWidgetHeader */
onInteractiveTimeout: () => void;
};
/**
* @description useWidgetInteractiveTimeout hook is to derive resulted interactiveTimeout based on
* the passed interactiveTimeout value that in turns drives widget UI phases.
* For example, once the widget timeouts, widget UI phase would transition from INTERACTIVE to TIMED_OUT
* which would turn the widget into a non interact-able widget.
* Resulted interactiveTimeout value is used by `LLWidgetHeader` component.
* @since 0.1.0
*/
export const useWidgetInteractiveTimeout = ({
widgetId,
interactiveTimeout: interactiveTimeoutProp,
onInteractiveTimeout: onInteractiveTimeoutProp,
}: UseWidgetInteractiveTimeoutArg): UseWidgetInteractiveTimeoutResult => {
const { updateWidgetUIPhaseAction } = useWidgetActions({ widgetId });
const widgetUIPhase = useWidgetUIPhase({ widgetId });
const isTimelineWidget = useIsTimelineWidget({ widgetId });
const widgetInteractiveDuration = useSelectedFieldStore(
widgetStore,
() => widgetStore.get()[widgetId]?.widgetPayload?.timeout
);
const widgetKind = useWidgetKind({ widgetId });
const widgetInteractions = useWidgetInteractions({ widgetId });
const onInteractiveTimeout = useCallback(() => {
updateWidgetUIPhaseAction({
widgetId,
widgetUIPhase: WidgetUIPhase.INTERACTIVE_TIMED_OUT,
});
onInteractiveTimeoutProp?.();
}, [widgetId, onInteractiveTimeoutProp]);
const interactiveTimeout = useMemo(() => {
const isExpired = widgetUIPhase === WidgetUIPhase.EXPIRED;
const isSubmitted = widgetUIPhase === WidgetUIPhase.SUBMITTED;
const isFollowUpPublished =
widgetUIPhase === WidgetUIPhase.FOLLOW_UP_PUBLISHED;
const isInteractiveTimedOut =
widgetUIPhase === WidgetUIPhase.INTERACTIVE_TIMED_OUT;
if (isExpired || isInteractiveTimedOut) {
return null;
}
if (isFollowUpPublished && !isTimelineWidget) {
return null;
}
// set interactive timeout to null if widget interaction is already submitted
// for single interaction widgets
if (
SINGLE_INTERACTION_WIDGET_KINDS.includes(widgetKind) &&
isSubmitted &&
!isTimelineWidget
) {
return null;
}
if (interactiveTimeoutProp !== undefined) {
return interactiveTimeoutProp;
}
return widgetInteractiveDuration
? getMilliseconds(widgetInteractiveDuration)
: null;
}, [
widgetUIPhase,
interactiveTimeoutProp,
widgetInteractiveDuration,
widgetInteractions,
isTimelineWidget,
]);
return {
interactiveTimeout,
onInteractiveTimeout,
};
};