Source

navigation.js

import * as React from "react";

/**
 * Nativation object from "@react-navigation/native"
 * @typedef {Object} NavigationService
 * @property {Function} navigate
 * @property {Function} dispatch
 * @see {@link https://reactnavigation.org/docs/navigation-prop/}
 */

/**
 * @typedef {"Auth" | "noAuth" | "Main" | "All"} NavigatorNames
 */

/**
 * @typedef {"LoginScreen" | "SignupScreen" | "CodeVerificationScreen" | "LinkAccountScreen" | "SocialLoginDataInputScreen" | "ForgotScreen" | "SocialLoginScreen"} AuthStackScreenNames
 */

/**
 * @typedef {"SettingsAboutScreen" | "ProfileGroupSingleScreen" | "SurveyScreen" | "ActivitiesCreatePostScreen" | "MessagesCreatePostScreen" | "QuizSingleScreen" | "QuizResults" | "QuizDetails" | "QuizReview" | "CourseSectionScreen" | "CourseQuizzesScreen" | "CourseMaterialsScreen" | "BBMediaFullView" | "MergeTopicScreen" | "LessonSingleScreen" | "LearnTopicSingleScreen" | "SubForumsSingleScreen" | "ForumsSingleScreen" | "CoursesSingleScreen" | "CoursesScreen" | "CoursesCategorySingleScreen" | "TopicsTagScreen" | "TopicsSingleScreen" | "AddTopicScreen" | "SelectScreen" | "MoveReplyScreen" | "SplitReplyScreen" | "NewReplyScreen" | "CreateNewAlbum" | "AddNewProfilePhoto" | "AddNewGroupPhoto" | "SettingsPushScreen" | "SettingsPrivacyScreen" | "GroupsSingleScreen" | "PageScreen" | "BlockScreen" | "ProfileScreen" | "PrivacySettingsScreen" | "GroupInviteSettingsScreen" | "LoginInfoScreen" | "AlbumSingleScreen" | "CreateNewPhotosScreen" | "AlbumAddPhotosScreen" | "HomeNotificationsScreen" | "HomeForumsScreen" | "HomeCourseCategoriesScreen" | "HomeTopicsScreen" | "HomeGroupsScreen" | "HomeMemberScreen" | "HomeActivityScreen" | "HomeMembersScreen" | "ReportFormScreen" | "ManageGroupDetails" | "EditNavigation" | "EditXprofile" | "ViewXprofile" | "PhotoXprofile" | "CoverXprofile" | "ProfileCourses" | "ProfilePhotos" | "GlobalPhotos" | "ProfileGamipress_achievements" | "ProfileGamipress_points" | "ProfileGamipress_ranks" | "ProfileBadgeos_achievements" | "ProfileBadgeos_points" | "ProfileBadgeos_ranks" | "ProfileActivities" | "ProfileCertificates" | "ProfileResults" | "ProfileBlog" | "ProfileXprofile" | "ProfileInvites" | "ProfileFriends" | "ProfileForums" | "ProfileGroups" | "GroupMessages" | "GroupMessageCreatePostScreen" | "GroupActivity" | "GroupPhotos" | "GroupAdmin" | "GroupManageSettings" | "GroupManageSettingsForm" | "GroupManageCoverPhoto" | "GroupManageMembers" | "GroupManagePhoto" | "GroupManageDelete" | "GroupManageDetails" | "GroupMembers" | "GroupSubgroups" | "GroupInvite" | "SelectGroupMembers" | "PendingInvites" | "SubmitInvite" | "GroupRequests" | "GroupCourses" | "ProductSingleScreen" | "ActivitySingleScreen" | "BlogSingleScreen" | "BlogSingleDeeplink" | "BlogReplyScreen" | "MyLibraryScreen" | "DownloadedCoursesScreen" | "BlogScreen" | "SettingsScreen" | "GroupsScreen" | "NotificationsScreen" | "TopicsScreen" | "CourseCategoriesScreen" | "ActivitiesScreen" | "MessagesScreen" | "MembersScreen" | "ForumsScreen" | "ProductsScreen" | "EmailInvitesSendScreen" | "EmailInvitesSentScreen" | "EmailInviteMessageScreen" | "SendFeedbackScreen" | "ReportBugScreen"} MainStackScreenNames
 */

/**
 * @typedef {"my_library" | "blog" | "settings" | "groups" | "notifications" | "topics" | "courses" | "courses_category" | "courses_all" | "activity" | "documents" | "messages" | "members" | "forums" | "profile" | "iap_products" | "photos" | "videos" | "gamipress_achievements" | "badgeos_achievements" | "course_certificates" } MainMenuScreenNames
 */

/**
 * @typedef {AuthStackScreenNames | MainStackScreenNames | MainMenuScreenNames} ScreenName
 */

/**
 * @typedef {Object} Navigator
 * @property {NavigationService} navigation Navigation object
 * @property {Function} dispatch Dispatch function
 */

/**
 * @typedef {Object} RoutesObject
 * @example
 * {
 *     AppLockScreen: {screen: AppLockNavigator},
 *     Main: {screen: MainScreenNavigator, navigationOptions: {header: null}},
 * 	   ...
 * }
 */

/**
 * @typedef {Function} AfterAuthRoutesFilter
 * @param {RoutesObject} routes Current routes
 * @return {RoutesObject} New routes
 */

/**
 * @typedef {Function} ShouldUpdateCallback
 * @param {Object} thisProps Current props
 * @param {Object} nextProps Next props
 * @param {Object} thisState Current state
 * @param {Object} nextState Next state
 * @return {Boolean} Return `true` if component should update
 */

/**
 * @typedef {Function} BottomTabsSettingsFilterCallback
 * @param {Object} tabsOptions `tabsOptions` include `tabBarOptions`, `initialRouteName` `tabBarComponent` etc..
 * @param {Object} colors App colors
 * @return {Object} New tab settings
 */

/**
 * @typedef {Function} BottomTabsRoutesFilterCallback
 * @param {Object} routes Current bottom tab routes
 * @return {Object} New routes
 */

/**
 * @typedef {Function} InitialAfterAuthRouteCallback
 * @param {Object} props AppNavigator component props
 * @return {String} Route
 */

/**
 * @typedef {Function} NavigatorEventListenerCallback
 * @param {Navigator} navigator Root navigator object
 */

/**
 * @typedef {Function} HOCsFilter
 * @param {Array<Function>} hocs Initial HOCs array
 * @return {Array<Function>} New HOCs array
 */

/**
 * @typedef {Function} MapStateToProps
 * @param {Object} state - Redux state
 * @return {Object} - Props
 */

/**
 * @typedef {Object} animatedSwitchNavigatorProps
 * @property {Object} routes Default navigation routes
 * @property {Object} options Default navigation options
 * @property {Object} routeProps Contains information which can be utilized when creating custom navigators
 * @return {animatedSwitchNavigatorReturn}
 */

/**
 * @typedef {Object} animatedSwitchNavigatorReturn
 * @property {Object} routes New navigation routes
 * @property {Object} options New navigation options
 */

/**
 * @typedef {Object} IconProps
 * @property {Object} route Route information such as label, icon, route name etc.
 * @property {Boolean} focused Returns `true` if icon is currently active
 * @property {String} tintColor Icon color
 */

/**
 * @typedef {Object} BottomTabBarProps
 * @property {Object} style Contains colors for nav bar use
 * @property {Boolean} showLabel Returns `true` if label should be used
 * @property {String} activeTintColor
 * @property {String} inactiveTintColor
 * @property {NavigationService} Navigation
 * @property {Number} height Default tab bar height
 * @property {Number} safeAreaInset SafeArea for IOS use
 */

/**
 * @class
 * Navigation Hooks.
 * Instance name: navigationApi
  
   You can use this hook to customize app navigation aspects such as adding a new route to the app react-navigation tree, adding new HOC (Higher-Order Components) and more.
 * @example
 * externalCodeSetup.navigationApi.METHOD_NAME
 */
export class NavigationApi {
	/**
	 * @ignore
	 * The app shows the SocialLoginScreen when this property is set to `true`
	 * Note that social login needs to be enabled and configured at the backend
	 * beforehand.
	 * @private
	 * @type {Boolean}
	 */
	socialLoginEnabled = false;
	/**
	 * @ignore Social login support removed
	 * Enables social login (if social login is enabled and configured at the backend beforehand)
	 * @method
	 */
	enableSocialLogin = () => {
		this.socialLoginEnabled = true;
	};

	/**
	 * @deprecated
	 */
	filterMultisiteDrawerSettings = (switchSite, options) => options;
	setFilterMultisiteDrawerSettings = filterMultisiteDrawerSettings => {
		this.filterMultisiteDrawerSettings = filterMultisiteDrawerSettings;
	};

	/**
	 * @deprecated
	 */
	filterInitialAfterAuthRoute = (props, initialAfterAuthRoute) =>
		initialAfterAuthRoute;
	setFilterInitialAfterAuthRoute = filterInitialAfterAuthRoute => {
		this.filterInitialAfterAuthRoute = filterInitialAfterAuthRoute;
	};

	/**
	 * @deprecated
	 * We don't use default icons anymore. All icons are provided by plugin.
	 */
	customIcons = {};
	addCustomIcons = iconsMap => {
		Object.assign(this.customIcons, iconsMap);
	};

	/**
	 * @deprecated
	 */
	setShowIosBottomTabsLabels = shouldShow => {
		console.warn(
			"This hook is deprecated. " +
				"Use globalSettings.app_menu.ios.show_labels and globalSettings.app_menu.android.show_labels instead"
		);
	};

	/**
	 * @deprecated
	 */
	composeHooks = newHooks => newHooks;
	/**
	 * @deprecated
	 */
	AddComposeHooks = composeHooks => {
		console.warn("This hook is deprecated. Use addComposeHocs");
		this.composeHooks = composeHooks;
	};

	/**
	 * @deprecated
	 * We use a custom TabBar component now.
	 */
	iosBottomTabsIconRenderer = null;
	setIosBottomTabsIcon = renderFunction => {
		console.warn("This hook is depreciated");
		this.iosBottomTabsIconRenderer = renderFunction;
	};

	/**
	 * Used to provide additional component update logic
	 * @private
	 */
	shouldComponentUpdate = (thisProps, nextProps, thisState, nextState) =>
		undefined;
	/**
	 * Used to provide custom update logic to AppNavigator.
	 * This function is called in shouldComponentUpdate.
	 * If this hook returns a boolean, the component will use this to determine if it should update.
	 * For more info about shouldComponentUpdate function, refer to {@link https://reactjs.org/docs/react-component.html#shouldcomponentupdate}
	 * @method
	 * @param {ShouldUpdateCallback} updateFunc
	 * @example
	 * externalCodeSetup.navigationApi.setShouldComponentUpdate((thisProps, nextProps, thisState, nextState) => {
	 *  //If condition...
	 *  return true;
	 * })
	 */
	setShouldComponentUpdate = updateFunc => {
		this.shouldComponentUpdate = updateFunc;
	};

	/**
	 * Used to provide a custom initial after auth route
	 * Takes AppNavigator props and returns a route name
	 * Return null to use default initial route logic
	 * @private
	 */
	initialAfterAuthRoute = props => null;
	/**
	 * By default we navigate to the "Main" stack after navigation.
	 * This hook is used to provide a different route after login.
	 * It uses the callback function `func` that will receive AppNavigator props and return a route name as a string.
	 * More examples at: {@link https://www.buddyboss.com/resources/dev-docs/app-development/extending-the-buddyboss-app/creating-new-screens/}
	 * @method
	 * @param {InitialAfterAuthRouteCallback} func
	 * @return {ScreenName} Return string screen name
	 * @example <caption> Show products screen after user authentication </caption>
	 * externalCodeSetup.navigationApi.setInitialAfterAuthRoute( props => {
	 *   if (props.auth.isLoggedIn){
	 *     return "ProductsScreen";
	 *   }
	 * })
	 */
	setInitialAfterAuthRoute = func => {
		this.initialAfterAuthRoute = func;
	};

	/**
	 * Used to provide custom state props
	 * Takes redux state as an argument and returns an object mapping state to props
	 * @private
	 */
	mapStateToProps = state => ({});

	/**
	 * Used to provide AppNavigator component custom redux props.
	 * It uses the `mapStateFunc` callback function that should receive redux state as an argument and return state props as an object.
	 * @method
	 * @param {MapStateToProps} mapStateFunc
	 * @example <caption> Add `blog` redux state and a localDate field to AppNavigator component props </caption>
	 * externalCodeSetup.navigationApi.setMapStateToProps( props => {
	 *   return {...props, blog: props.blog, localDate: new Date()}
	 * })
	 *
	 * //These new props can now be used in AppNavigator functions. For example:
	 * externalCodeSetup.navigationApi.setInitialAfterAuthRoute( props => {
	 *    if (props.localDate < foo)
	 *      return "CustomScreen"
	 * })
	 *
	 */
	setMapStateToProps = mapStateFunc => {
		this.mapStateToProps = mapStateFunc;
	};
	/**
	 * @ignore
	 * @private
	 */
	defaultStackNavigatorConfig = {};
	/**
	 * @ignore
	 * Reason for ignoring: A lot of stackNavigator options can't be used in the app such as setting a header style
	 * Each screen in the TabBarNavigator is wrapped in a StackNavigator.
	 * This hook is used to provide a custom stackConfigs all of these StackNavigators.
	 * For more info on how setting config for defaultStackNavigator, see {@link https://reactnavigation.org/docs/4.x/stack-navigator}
	 * @method
	 * @param {Object} config Configuration object
	 */
	setDefaultStackNavigatorConfig = config => {
		this.defaultStackNavigatorConfig = config;
	};

	/**
	 * @private
	 */
	newNavigationRoutes = [];
	/**
	 * Add a new route to react-navigation tree.
	 * NOTE: The route will be added to the root navigator if the parentNavigator value is missing.
	 * More information can be found at: {@link https://www.buddyboss.com/resources/dev-docs/app-development/extending-the-buddyboss-app/creating-new-screens/}
	 * @method
	 * @param {String} id Key of route in route map
	 * @param {String} routeName Route name in react-navigation tree
	 * @param {React.ComponentType<any>} component Route component
	 * @param {NavigatorNames} parentNavigator Parent navigator name; can be one of the NavigatorNames values.
	 * @example <caption> Register a new route and navigate to that route </caption>
	 *
	 * //After adding BookScreen as a new navigation route, you can now navigate to this screen using NavigationService
	 * externalCodeSetup.navigationApi.addNavigationRoute(
	 *  "book",
	 *  "BookScreen",
	 *  () => <Text>Custom Book Screen</Text>,
	 *  "All"
	 * );
	 *
	 * //Example on how to navigate to BookScreen
	 * //Since "book" is now registered, app can now navigate to that route
	 * const MyCustomLoginScreen = (props) => (
	 *  <View>
	 *    <Text> This is a custom login screen</Text>
	 *    <Button title="Go To Book Screen" onPress={() => props.navigation.navigate("book")}/>
	 *  </View>
	 * )
	 * externalCodeSetup.navigationApi.replaceScreenComponent(
	 *  "LoginScreen",
	 *  MyCustomLoginScreen
	 * );
	 */
	addNavigationRoute = (id, routeName, component, parentNavigator) => {
		this.newNavigationRoutes.push({id, routeName, component, parentNavigator});
	};

	/**
	 * @private
	 */
	screenReplacements = {};
	/**
	 * Replaces a certain screen in the app.
	 * More information at {@link https://www.buddyboss.com/resources/dev-docs/app-development/extending-the-buddyboss-app/creating-new-screens/}
	 * @method
	 * @param {ScreenName} componentName The name of the screen registered in the core BuddyBoss App navigation.
	 * @param {React.ComponentType<any>} replaceWith  Your custom screen component.
	 * @example <caption> Replace LoginScreen with MyScreen </caption>
	 *
	 * const MyScreen = (props) => (
	 *		<View style={{flex: 1}}>
	 *			<Text>This is my screen</Text>
	 *		</View>
	 *	);
	 *
	 *  MyScreen.navigationOptions = {header: null};
	 *
	 *  externalCodeSetup.navigationApi.replaceScreenComponent("LoginScreen", MyScreen);
	 */
	replaceScreenComponent = (componentName, replaceWith) => {
		this.screenReplacements[componentName] = replaceWith;
	};

	/**
	 * @private
	 * @property {Array<NavigatorEventListenerCallback>} navigatorCreatedCallbacks
	 */
	navigatorCreatedCallbacks = [];
	/**
	 * Use to subscribe to root navigator created event.
	 * This will return the navigator object.
	 * Useful for dispatching navigation events outside of navigation tree components or getting state of navigator
	 * @method
	 * @param {NavigatorEventListenerCallback} onNavigatorCreated
	 * @returns {UnsubscribeFunction} Unsubscribe function
	 * @example
	 *  externalCodeSetup.navigationApi.addNavigatorCreatedCallback(props => {
	 *    Alert.alert("Navigator created!")
	 *  })
	 */
	addNavigatorCreatedCallback = onNavigatorCreated => {
		this.navigatorCreatedCallbacks.push(onNavigatorCreated);
		return () => {
			const index = this.navigatorCreatedCallbacks.indexOf(onNavigatorCreated);
			if (index !== -1) {
				this.navigatorCreatedCallbacks.splice(index, 1);
			}
		};
	};

	/**
	 *
	 * @param {Object} tabsOptions
	 * @param {Object} colors
	 * @private
	 */
	filterBottomTabsSettings = (tabsOptions, colors) => tabsOptions;
	/**
	 * You can use this hook to configure `createBottomTabNavigator` from react-navigation.
	 * `tabsOptions` and `colors` objects are provided which you can use to return a new settings object.
	 * For more information on how to set `tabBarOptions`, see {@link https://reactnavigation.org/docs/4.x/bottom-tab-navigator}
	 * @method
	 * @param {BottomTabsSettingsFilterCallback} filterBottomTabsSettings
	 * @example <caption> Change bottom tab bar's active tint color </caption>
	 *   externalCodeSetup.navigationApi.setFilterBottomTabsSettings((tabsOptions, colors) => {
	 *     return {
	 *      ...tabsOptions,
	 *      tabBarOptions: {
	 *        ...tabsOptions.tabBarOptions,
	 *        activeTintColor: colors.headerBg
	 *       }
	 *     }
	 *   })
	 */
	setFilterBottomTabsSettings = filterBottomTabsSettings => {
		this.filterBottomTabsSettings = filterBottomTabsSettings;
	};

	/**
	 *
	 * @param {Object} routes
	 * @private
	 */
	filterBottomTabsRoutes = routes => routes;
	/**
	 * You can use this hook to configure `createBottomTabNavigator` from react-navigation.
	 * `routes` object is provided which you can use to return a new routes object.
	 * For more information, see {@link https://reactnavigation.org/docs/4.x/bottom-tab-navigator}
	 * @method
	 * @param {BottomTabsRoutesFilterCallback} filterBottomTabsRoutes
	 * @example <caption>Override default navigation for MoreScreen </caption>
	 *
	 * //Register a custom screen in navigation route
	 *   externalCodeSetup.navigationApi.addNavigationRoute(
	 *     "book",
	 *     "BookScreen",
	 *     () => <Text>Custom Book Screen</Text>,
	 *     "All"
	 *   );
	 *
	 *  externalCodeSetup.navigationApi.setFilterBottomTabsRoutes(routes => {
	 *     return {
	 *       ...routes,
	 *       MoreScreen: {
	 *        ...routes?.MoreScreen,
	 *        navigationOptions: {
	 *          ...routes?.MoreScreen.navigationOptions,
	 *          //Navigate to new "book" route when MoreScreen item in menu is pressed
	 *          tabBarOnPress: ({navigation}) => {
	 *            navigation.navigate("book")
	 *          }
	 *        }
	 *       }
	 *     }
	 *   })
	 *
	 */
	setFilterBottomTabsRoutes = filterBottomTabsRoutes => {
		this.filterBottomTabsRoutes = filterBottomTabsRoutes;
	};

	filterAfterAuthRoutes = routes => routes;
	/**
	 * You can use this hook to filter possible changes after authentication routes.
	 * `filterAfterAuthRoutes` takes current routes object and returns a new one.
	 * For more info, see {@link https://www.buddyboss.com/resources/dev-docs/app-development/extending-the-buddyboss-app/creating-new-screens/}
	 * @method
	 * @param {AfterAuthRoutesFilter} filterAfterAuthRoutes
	 * @example <caption> Add custom screen to auth route then navigate to custom screen</caption>
	 *
	 * ...
	 *
	 * import { withNavigation } from 'react-navigation';
	 *
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *  const MyWelcomeScreen = withNavigation((props) => {
	 *   return <View style={{flex:1, justifyContent: "center", alignSelf: "center"}}>
	 *     <Text> Welcome to our App! New adventure awaits!</Text>
	 *     <Button title="Go to App" onPress={() => props.navigation.navigate("Main")}/>
	 *    </View>
	 *  })
	 *
	 *  MyWelcomeScreen.navigationOptions = {
	 *    header: null
	 *  }
	 *
	 *  externalCodeSetup.navigationApi.setFilterAfterAuthRoutes(afterAuthRoutes => {
	 *    return {
	 *       ...afterAuthRoutes,
	 *       "MyWelcomeScreen": MyWelcomeScreen
	 *      };
	 *  });
	 *
	 *  externalCodeSetup.navigationApi.setInitialAfterAuthRoute(props => {
	 *    return "MyWelcomeScreen";
	 *  });
	 *
	 * }
	 */
	setFilterAfterAuthRoutes = filterAfterAuthRoutes => {
		this.filterAfterAuthRoutes = filterAfterAuthRoutes;
	};

	composeHocs = hocs => hocs;
	/**
	 * Use this hook to register new HOCs (Higher-Order Components) which will be applied to the AppNavigator component.
	 * For more info on how to use HOCs, refer to: {@link https://reactjs.org/docs/higher-order-components.html}
	 * @method
	 * @param {HOCsFilter} composeHocs
	 * @example <caption> Add new HOC </caption>
	 *  externalCodeSetup.navigationApi.addComposeHocs(hocs => {
	 *   return [
	 *    ...hocs,
	 *    withMyCustomHoc
	 *   ];
	 * })
	 */
	addComposeHocs = composeHocs => {
		this.composeHocs = composeHocs;
	};

	bottomTabBarIcon = (icon, iconProps) => icon;

	/**
	 * You can use this to replace the bottom tab bar icons to display your preferred icons.
	 * @method
	 * @param {?React.ComponentType<Icon>} Icon Tab icon component
	 * @param {IconProps} iconProps
	 * @example <caption> Customize icon for courses </caption>
	 *  externalCodeSetup.navigationApi.setBottomTabBarIcon((icon, iconProps) => {
	 *
	 *    const routeLabel = iconProps.route.routes[0].params.item?.label;
	 *
	 *    if (routeLabel === "Courses") {
	 *      return <View
	 *        style={{
	 *          height: 30,
	 *          width: 30,
	 *          borderRadius: 58,
	 *          backgroundColor: '#5a95ff',
	 *          justifyContent: 'center',
	 *          alignItems: 'center',
	 *        }}>
	 *        <Image
	 *          source={require('@src/assets/img/apple-icon.png')}
	 *          style={{
	 *            width: 40,
	 *            height: 40,
	 *            tintColor: 'black',
	 *            alignContent: 'center',
	 *          }}
	 *        />
	 *      </View>
	 *    }
	 *
	 *    return icon;
	 *  })
	 */
	setBottomTabBarIcon = bottomTabBarIcon => {
		this.bottomTabBarIcon = bottomTabBarIcon;
	};

	bottomTabBar = null;

	/**
	 * You can use this to replace the bottom tab bar component according to your preference.
	 * For more information regarding the BottomTabBar, you can use the following link: {@link https://reactnavigation.org}
	 * @method
	 * @param {?React.ComponentType<BottomTabBarProps>} BottomTabBarProps
	 * @example <caption> Create own bottom tab bar </caption>
	 *
	 * ...
	 *
	 * import { BottomTabBar } from "react-navigation-tabs";
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *  externalCodeSetup.navigationApi.setBottomTabBar(props => {
	 *
	 *    const { style, height, safeAreaInset } = props;
	 *
	 *    const renderLabel = (props) => {
	 *       //Render label by returning a text react component...
	 *    }
	 *
	 *    const renderIcon = (props) => {
	 *       //Render icon by returning an image react component...
	 *    }
	 *
	 *    return <BottomTabBar
	 *      {...props}
	 *      style={[style, { height: height }]}
	 *      safeAreaInset={{ bottom: safeAreaInset }}
	 *      getLabelText={renderLabel}
	 *      renderIcon={renderIcon}
	 *    />
	 *
	 *     //Alternatively, user can also create his own component without relying on react-navigation-tab BottomTabBar
	 *  })
	 * }
	 */
	setBottomTabBar = bottomTabBar => {
		this.bottomTabBar = bottomTabBar;
	};

	animatedSwitchNavigator = (routes, options) => ({
		routes: routes,
		options: options
	});

	/**
	 * This hook allows you to create your own animated switch navigator.
	 * For example, you can add a new route and use it as your initial switch route instead of the default "Auth" route which will show you the login screen.
	 * @method
	 * @param {animatedSwitchNavigatorProps} animatedSwitchNavigator
	 * @returns {animatedSwitchNavigatorReturn}
	 *
	 * @example <caption> Add a custom screen to be used as initial switch route </caption>
	 *
	 * //In custom_code/MyCustomScreen.js...
	 *
	 * import React from 'react';
	 * import { View, Text, Button } from 'react-native';
	 *
	 * const MyCustomScreen = props => {
	 *
	 *  return <View style={{ flex: 1, justifyContent: "center", alignSelf: "center" }}>
	 *    <Text> Welcome to our App! New adventure awaits!</Text>
	 *    <Button title="Go to App" onPress={() => props.navigation.navigate("Auth")} />
	 *  </View>
	 * }
	 *
	 * export default MyCustomScreen;
	 *
	 *
	 * //In custom_code/index.js...
	 *
	 * ...
	 *
	 * import MyCustomScreen from "./components/MyCustomScreen";
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *  externalCodeSetup.navigationApi.setAnimatedSwitchNavigator((routes, options, routeProps) => {
	 *
	 *    const feature = routeProps.settings.features.multisite_network;
	 *    const hasMultiSite = Platform.select({
	 *      ios: feature.is_enabled_ios,
	 *      android: feature.is_enabled_android
	 *    })
	 *
	 *     // Get the initial switch route based on state data.
	 *     // getInitialSwitchRoute() is based on BB App's AppNavigator.js
	 *     // Feel free to copy and paste this to your own code
	 *
	 *    const getInitialSwitchRoute = () => {
	 *
	 *      const defaultInitialRoute = "Auth";
	 *
	 *      const myCustomRoute = "MyCustomScreen"
	 *
	 *      if (!routeProps.hasValidSigning) {
	 *        return "InvalidSigningScreen";
	 *      }
	 *
	 *      if (routeProps.shouldEnforceVersionControl) {
	 *        return "VersionControlScreen";
	 *      } else if (routeProps.isLoggedIn) {
	 *        if (
	 *          routeProps.isFeatureEnabled(hasMultiSite) &&
	 *          routeProps.sites.selectedSite === null
	 *        ) {
	 *          return "AuthSiteSelectionScreen";
	 *        } else {
	 *          return routeProps.shouldLockApp ? "AppLockScreen" : "noAuth";
	 *        }
	 *      }
	 *      else {
	 *        return myCustomRoute; //Use my own custom route instead of the default "Auth" route
	 *        // return defaultInitialRoute;
	 *      }
	 *
	 *    };
	 *
	 *    const newRoutes = {
	 *     ...routes,
	 *     MyCustomScreen: {
	 *      screen: MyCustomScreen
	 *     }
	 *    }
	 *
	 *    const newOptions = {
	 *     ...options,
	 *     initialRouteName: getInitialSwitchRoute()
	 *    }
	 *
	 *    return {
	 *     routes: newRoutes,
	 *     options: newOptions,
	 *    }
	 *
	 *  })
	 * }
	 */
	setAnimatedSwitchNavigator = animatedSwitchNavigator => {
		this.animatedSwitchNavigator = animatedSwitchNavigator;
	};
}