import { isEqual } from "lodash"; import React, { useEffect, useMemo, useState } from "react"; import { View } from "react-native"; import { useDispatch, useSelector } from "react-redux"; import { commonStyles } from "../../Container/Navi-Insurance/Styles"; import { ActionMetaData, GenericActionPayload } from "../actions/GenericAction"; import { sendAsAnalyticsEvent } from "../hooks/useAnalyticsEvent"; import { useBottomSheet } from "../hooks/useBottomSheet"; import { logToSentry } from "../hooks/useSentryLogging"; import { CtaData } from "../interface"; import { ModalView } from "../interface/modals/ModalView"; import { ScreenData } from "../interface/widgets/screenData/ScreenData"; import { Router } from "../navigator/NavigationRouter"; import { updateCtaData } from "../redux/screens/screenActionCreators"; import { setCurrentScreenName } from "../utilities/AlfredUtils"; import { getCacheKey, getScreenDataFromCache, isScreenWhiteListedForCaching, saveScreenDataInCache, } from "../utilities/CacheUtils"; import { getScreenMapperNameFromCtaData, getScreenNameFromCtaData, } from "../utilities/MiscUtils"; import { WidgetActionTypes } from "../widgets/widget-actions/WidgetActionTypes"; import { ScreenMapper } from "./screen-mappers/ScreenMapper"; const BaseScreen: React.FC<{ navigation: any; route: any }> = ({ navigation, route, }) => { const [screenData, setScreenData] = useState(null); const [screenName, setScreenName] = useState(null); const [screenKey, setScreenKey] = useState(null); const [screenState, setScreenState] = useState( ScreenState.LOADING ); const [errorMetaData, setErrorMetaData] = useState( null ); useEffect(() => { const cacheKey = getCacheKey(screenName, screenKey); if (!screenData) { const screenInitialData: ScreenData = { screenState: ScreenState.LOADING, }; setScreenData(screenInitialData); } if (!!cacheKey && isScreenWhiteListedForCaching(screenName)) { if ( !( !!screenData?.errorMetaData || screenData?.screenState === ScreenState.ERROR ) ) { saveScreenDataInCache(screenName, screenData); } } }, [screenData]); useEffect(() => { if (!!getScreenNameFromCtaData(route.params?.ctaData)) { setScreenName(getScreenNameFromCtaData(route.params?.ctaData)!!); if (!!route.params?.ctaData?.screenKey) { setScreenKey(route.params?.ctaData?.screenKey); } if (isScreenWhiteListedForCaching(screenName)) { retrieveScreenDataFromCache( getScreenNameFromCtaData(route.params?.ctaData)!!, route.params?.ctaData?.screenKey ); } } }, []); const dispatch = useDispatch(); const retrieveScreenDataFromCache = ( screenName: string | null | undefined, screenKey: string | null | undefined ) => { let cacheKey = getCacheKey(screenName, screenKey); if (!!cacheKey) { getScreenDataFromCache(cacheKey).then((screenData) => { if (!!screenData) { setScreenData(screenData); } }); } }; const { cta } = useSelector((state: any) => { const savedCta = state.screenReducer.ctaData; if (isEqual(savedCta, route.params.ctaData)) { return { cta: state.screenReducer.ctaData }; } return { cta: route.params.ctaData }; }); useEffect(() => { const ctaData: CtaData = route.params.ctaData; if (!isEqual(cta, ctaData)) { dispatch(updateCtaData({ cta: ctaData, setScreenState: screenState })); } }, [route.params.ctaData, screenState]); const { bottomsheet, addBottomSheet } = useBottomSheet(); const handleActions = (actionPayload?: GenericActionPayload) => { actionPayload?.metaData?.forEach((ActionMetaData) => { if (!!ActionMetaData.analyticsEventProperties) { sendAsAnalyticsEvent(ActionMetaData.analyticsEventProperties); } if (ActionMetaData.actionType === WidgetActionTypes.OPEN_BOTTOM_SHEET) { addBottomSheet(ActionMetaData.data as ModalView); } else { const updatedActionPayload: GenericActionPayload = { ...(actionPayload as GenericActionPayload), setScreenData, setScreenState, setErrorMetaData, ctaData: cta, screenData: { ...screenData }, }; if (!!actionPayload) { Router.handleAction(updatedActionPayload, navigation); } else { // handle error logToSentry( `Action payload is missing or invalid: ${actionPayload} | MethodName: handleActions` ); } } }); }; const MemoizedScreenMapper = useMemo(() => { const secondIdentifier = getScreenMapperNameFromCtaData(cta); setCurrentScreenName( "RN_" + secondIdentifier?.toUpperCase() + "_" + screenName ); return ( {ScreenMapper.getScreenMapper(cta, screenData, handleActions)} ); }, [cta, screenData]); return ( {MemoizedScreenMapper} {bottomsheet.map((sheet, index) => ( {sheet} ))} ); }; export enum ScreenState { LOADING, LOADED, ERROR, OVERLAY, } export default BaseScreen;