UNPKG

@applicaster/zapp-react-native-app

Version:

Zapp App Component for Applicaster's Quick Brick React Native App

124 lines (99 loc) 3.65 kB
import * as React from "react"; import { BackHandler } from "react-native"; import * as R from "ramda"; import { QUICK_BRICK_EVENTS, sendQuickBrickEvent, } from "@applicaster/zapp-react-native-bridge/QuickBrick"; import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks/navigation"; import { useAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils"; import { useRivers } from "@applicaster/zapp-react-native-utils/reactHooks/state"; import { useErrorStore } from "@applicaster/quick-brick-core/App/ErrorBoundary/store"; import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils"; const getHome = R.compose(R.find(R.propEq("home", true)), R.values); const isIOS = isApplePlatform(); /* Set to `false` in production, do not commit this change */ const IS_DEBUGGER_ENABLED = false; /** * This is a workaround to fix an error on start when debugger is connected. * Update function body for this function `callNativeSyncHook` * node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:167 this.processCallbacks(moduleID, methodID, params, onFail, onSucc); if(global.nativeCallSyncHook) { return global.nativeCallSyncHook(moduleID, methodID, params); } */ // Assign this to a dev-only button or useEffect call const connectToRemoteDebugger = () => { if (__DEV__ && isIOS) { try { const { DevSettings, NativeModules } = require("react-native"); // eslint-disable-next-line no-console console.warn(`Debugger connected: ${IS_DEBUGGER_ENABLED}`); if (DevSettings?.setIsDebuggingRemotely) { DevSettings.setIsDebuggingRemotely(IS_DEBUGGER_ENABLED); } NativeModules?.DevSettings?.setIsDebuggingRemotely?.(IS_DEBUGGER_ENABLED); } catch (error) { // eslint-disable-next-line no-console console.error(`connectToRemoteDebugger message: ${error.message}`); } } }; const InteractionManagerComponent = () => { const { sendHardwareBackButtonClickEvent } = useAnalytics(); const rivers = useRivers(); const navigator = useNavigation(); const isHomeScreen = () => { const homeId = R.compose(R.prop("id"), getHome)(rivers); const homePath = `/river/${homeId}`; return homePath === navigator.currentRoute; }; const exitToBackground = () => { sendQuickBrickEvent(QUICK_BRICK_EVENTS.MOVE_APP_TO_BACKGROUND, { MOVE_APP_TO_BACKGROUND: true, }); }; const goToHome = () => { const home = getHome(rivers); if (!home) { throw new Error("Could not find home screen"); } navigator.replace(home); }; const onHardwareBackPress = React.useCallback(() => { if (navigator && !navigator.canGoBack()) { if (isHomeScreen()) { exitToBackground(); } else { try { goToHome(); } catch (e) { const errorMessage = "Can't find home screen"; const error = new Error(errorMessage); useErrorStore .getState() .setError(error, "Failed navigating to home screen", false); } } } else { sendHardwareBackButtonClickEvent({ navigator }); navigator.goBack(); } return true; // Take care! see jsdoc above }, [navigator.currentRoute]); React.useEffect(() => { connectToRemoteDebugger(); }, []); React.useEffect(() => { const unsubscribe = BackHandler.addEventListener( "hardwareBackPress", onHardwareBackPress ); return () => { unsubscribe.remove(); }; }, [onHardwareBackPress]); return null; }; export const InteractionManager = React.memo(InteractionManagerComponent);