UNPKG

@navinc/base-react-components

Version:
98 lines (84 loc) 3.29 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, user, 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 [lastUser, setLastUser] = useState(user) 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 (user.key && clientSideID && !isInitialized && !hasTimedOut) ldclient.current = initialize(clientSideID, user) else if (!isInitialized) console.warn('Please provide a user object and clientSideID') // eslint-disable-next-line react-hooks/exhaustive-deps }, [clientSideID, user.key, isInitialized, hasTimedOut]) // This is right, we only want it to re-run when the key changes if its the object it will re-run useEffect(() => { if (ldclient.current && user.key && !isInitialized) ldclient.current.waitForInitialization().then(() => { setIsInitialized(true) setIsLoading(false) setFlags(ldclient.current.allFlags()) }) }, [isInitialized, user.key]) useEffect(() => { if (!isEqual(user, lastUser) && isInitialized) { setLastUser(user) ldclient.current.identify(user) ldclient.current.identify(user) } }, [user, lastUser, 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} /> }