@livelike/react-native
Version:
LiveLike React Native package
70 lines (63 loc) • 2.6 kB
text/typescript
import { useEffect } from 'react';
import { widgetStore } from '../store';
import { WidgetUIPhase } from '../types';
import { useSelectedFieldStore } from './useSelectedFieldStore';
import { useWidgetActions } from './useWidgetActions';
import { useWidgetUIPhase } from './useWidgetUIPhase';
export type UseWidgetExpiryEffectArg = {
widgetId: string;
};
const MAX_SET_TIMEOUT_DELAY = 2147483647;
/**
* @description useWidgetExpiryEffect hook runs a timer to update widget UI phase to EXPIRED
* once the expiry time has passed. Expiry time is set when creating widget from producer suite
* @since 0.1.0
*/
export function useWidgetExpiryEffect({ widgetId }: UseWidgetExpiryEffectArg) {
const { updateWidgetUIPhaseAction } = useWidgetActions({ widgetId });
const expiredTimeStamp = useSelectedFieldStore(
widgetStore,
() => widgetStore.get()[widgetId]?.widgetPayload?.interactive_until
);
const currentWidgetUIPhase = useWidgetUIPhase({ widgetId });
const isWidgetEndUIPhase =
currentWidgetUIPhase === WidgetUIPhase.INTERACTIVE_TIMED_OUT ||
currentWidgetUIPhase === WidgetUIPhase.FOLLOW_UP_PUBLISHED;
useEffect(() => {
if (!expiredTimeStamp || isWidgetEndUIPhase) return;
const expiredTime = new Date(expiredTimeStamp);
let expiryTimeout;
function expiryTimeoutFn() {
const timeout = expiredTime.getTime() - Date.now();
if (timeout <= 0) {
updateWidgetUIPhaseAction({
widgetId,
widgetUIPhase: WidgetUIPhase.EXPIRED,
});
return;
}
// setTimeout stores the delay as 32-bit signed integer. So, when interactive_until is set
// for more than 24.8 days later, the code executes immediately disabling the widget.
// The below if condition is added to handle the same.
// If timeout is greater than MAX_SET_TIMEOUT_DELAY, a setTimeout with MAX_SET_TIMEOUT_DELAY
// as the delay will run which will recursively call startInteractiveUntilTimer again and
// again until the timeout is less than MAX_SET_TIMEOUT_DELAY and eventually sets this.disabled as true
if (timeout > MAX_SET_TIMEOUT_DELAY) {
expiryTimeout = setTimeout(() => {
expiryTimeoutFn();
}, MAX_SET_TIMEOUT_DELAY);
} else {
expiryTimeout = setTimeout(() => {
updateWidgetUIPhaseAction({
widgetId,
widgetUIPhase: WidgetUIPhase.EXPIRED,
});
}, timeout);
}
}
expiryTimeoutFn();
return () => {
clearTimeout(expiryTimeout);
};
}, [expiredTimeStamp, isWidgetEndUIPhase]);
}