UNPKG

@navinc/base-react-components

Version:
104 lines (91 loc) 3.21 kB
import React, { useState, useEffect, useRef, createContext, useContext, useCallback } from 'react' import { initialize } from 'launchdarkly-js-client-sdk' import isEqual from 'lodash.isequal' const LaunchDarklyContext = createContext({}) export const LaunchDarklyProvider = ({ clientSideID, context, options, children, LoadingContent, onTimeout = () => {}, }) => { const ldclient = useRef() const [flags, setFlags] = useState([]) const [isLoading, setIsLoading] = useState(true) const [hasTimedOut, setHasTimedOut] = useState(false) const [isInitialized, setIsInitialized] = useState(false) const [lastContext, setLastContext] = useState(context) const trackMetric = ldclient.current?.track const whichVariation = ldclient.current?.variation const trackOfferReferral = useCallback((offer = {}, additionalInfo = {}) => { const { matchFactorScore, mfSource, offerCategory, offerId, rtid, order } = offer const payload = { matchFactorScore, mfSource, offerCategory, offerId, rtid, order, ...additionalInfo, } if (ldclient.current) ldclient.current.waitForInitialization().then(() => ldclient.current.track('offer_referral', payload)) }, []) useEffect(() => { setTimeout(() => { if (isLoading) { setIsLoading(false) setHasTimedOut(true) // should be a bugsnag call onTimeout() } }, 500) }) useEffect(() => { if (context && clientSideID && !isInitialized && !hasTimedOut) ldclient.current = initialize(clientSideID, context, options) else if (!isInitialized) console.warn('Please provide a user object and clientSideID') }, [clientSideID, context, isInitialized, hasTimedOut, options]) useEffect(() => { if (ldclient.current && context && !isInitialized) ldclient.current.waitForInitialization().then(() => { setIsInitialized(true) setIsLoading(false) setFlags(ldclient.current.allFlags()) }) }, [isInitialized, context]) // TODO Not sure this is being used useEffect(() => { if (!isEqual(context, lastContext) && isInitialized) { setLastContext(context) ldclient.current.identify(context) } }, [context, lastContext, ldclient, isInitialized]) // TODO add listener for on change to update flags state return ( <LaunchDarklyContext.Provider value={{ flags, isLoading, isInitialized, trackMetric, trackOfferReferral, whichVariation, ldclient: ldclient.current, }} > {isLoading && !!LoadingContent ? <LoadingContent /> : children} </LaunchDarklyContext.Provider> ) } export const useLaunchDarkly = () => { const { flags, isLoading, isInitialized, trackMetric, trackOfferReferral, whichVariation, ldclient } = useContext(LaunchDarklyContext) const hasProvider = !!ldclient return { flags, isLoading, isInitialized, trackMetric, trackOfferReferral, whichVariation, ldclient, hasProvider } } export const withLaunchDarkly = (Component) => (props) => { const { whichVariation } = useLaunchDarkly() return <Component whichVariation={whichVariation} {...props} /> }