import * as React from "react";
import {NavigationService} from "./types";
/**
* @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" | "ActivityMedia" | "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
* @param {Function} constructTabbarAllScreens Returns the appropriate screens depending on value of "Tab Bar Visibility"
* @param {Boolean} showTabBarOnAllScreens Returns `true` if "Tab Bar Visibility" is set to "Show on All Screens"
* @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} item Route information
* @property {Boolean} focused Returns `true` if icon is currently active
* @property {String} tintColor Icon color
* @property {Function} calcFontSize Used to calculate font size based on the fixed value you assign and percent set on branding options
* @property {Object} colors App colors
*/
/**
* @typedef {Object} LabelProps
* @property {Object} props Route information
* @property {Array<Object>} textStyle Default style for the text component
*/
/**
* @typedef {Object} BottomTabBarProps
* @property {Object} state Route state information
* @property {Object} descriptors Bottom tab bar menu items
* @property {NavigationService} navigation
*/
/**
* @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;
};
/**
*
* Display BlurView in IOS TabBar
*/
isBlurViewInIOSTabBar = false;
enableBlurViewInIOSTabBar = () => {
this.isBlurViewInIOSTabBar = true;
};
/**
* 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>
* );
*
*
* 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.
* @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,
* tabBarActiveTintColor: 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.
* @method
* @param {BottomTabsRoutesFilterCallback} filterBottomTabsRoutes
* @example <caption> Create a custom More Screen </caption>
*
* import React from "react";
* import {Platform} from "react-native";
* import MoreScreen from "@src/containers/Custom/MoreScreen";
* import FontManager from "@src/FontManager";
* import {NAV_HEIGHT, BARHEIGHT, isHaveDynamicIsland} from "@src/styles/global";
* import {SEARCH_HEIGHT} from "@src/components/Search";
* import {useSearchTransition} from "@src/components/listUtils";
*
* export const applyCustomCode = externalCodeSetup => {
*
* const MyCustomScreen = props => {
* const showSearch = true;
* const SPACING_TOP = FontManager.applyFontHeightAdjustment(NAV_HEIGHT + 17);
* const INITIAL_SCROLL = -SPACING_TOP + SEARCH_HEIGHT;
* const {listTopMargin} = useSearchTransition(
* showSearch,
* false,
* Platform.select({
* ios: NAV_HEIGHT - BARHEIGHT - (isHaveDynamicIsland() ? 20 : 16),
* android: NAV_HEIGHT - 26 - BARHEIGHT
* })
* );
*
* const searchContainerPaddingTop = listTopMargin.value + (NAV_HEIGHT + 17);
*
* return (
* <MoreScreen
* screenTitle="More Menus"
* containerPaddingTop={NAV_HEIGHT}
* contentInsetTop={SPACING_TOP}
* contentOffsetY={INITIAL_SCROLL}
* searchContainerPaddingTop={searchContainerPaddingTop}
* showSearch={showSearch}
* />
* );
* };
*
* externalCodeSetup.navigationApi.setFilterBottomTabsRoutes(routes => {
* return {
* ...routes,
* MoreScreen: {
* ...routes.MoreScreen.options,
* screen: {
* ...routes.MoreScreen.screen,
* component: MyCustomScreen
* }
* }
* };
* });
* };
*
*/
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 "@src/components/hocs/withNavigation";
*
* 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>
* );
* });
*
*
* externalCodeSetup.navigationApi.setFilterAfterAuthRoutes(afterAuthRoutes => {
* return {
* ...afterAuthRoutes,
* MyWelcomeScreen: {
* screen: 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, props) => 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} props
* @example
* import React from "react";
* import Icon from "@src/components/Icon";
* import BadgeIcon from "@src/components/BadgeIcon";
* import {getIcon} from "@src/navigators/util";
* import {glyphMap as bbIconGlyphMap} from "@src/components/BBIcon";
* export const applyCustomCode = (externalCodeSetup) => {
* externalCodeSetup.navigationApi.setBottomTabBarIcon(
* (icon, props) => {
* const {tintColor, focused, calcFontSize, colors, item} = props;
*
* if (!item) return null;
*
* const {color, menuIcon} = getIcon(
* item,
* bbIconGlyphMap,
* focused,
* tintColor
* );
*
* if (item.object === "notifications" || item.object === "messages") {
* return (
* <BadgeIcon
* calcFontSize={calcFontSize}
* tintColor={color}
* bottomTabsBg={colors.bottomTabsBg}
* warningColor={colors.warningColor}
* foregroundColor={item.icon.fg_color}
* platform="ios"
* inMore={false}
* app={"learnerapp"}
* type={item.object}
* icon={menuIcon}
* styles={{height: 25, width: 25}}
* />
* );
* }
*
* return (
* <Icon
* icon={menuIcon}
* foregroundColor={item.icon.fg_color}
* tintColor={color}
* styles={{height: 25, width: 25}}
* />
* );
* }
* );
* }
*/
setBottomTabBarIcon = bottomTabBarIcon => {
this.bottomTabBarIcon = bottomTabBarIcon;
};
bottomTabBarLabel = (label, labelProps) => label;
/**
* You can use this to replace the bottom tab bar label to display your preferred labels.
* @method
* @param {React.ComponentType<Text>} Label Tab label component
* @param {LabelProps} labelProps
*
* externalCodeSetup.navigationApi.setBottomTabBarLabel((label, labelProps) => (
* <Text
* style={labelProps.textStyle}
* numberOfLines={1}
* ellipsizeMode={"tail"}
* allowFontScaling={false}
* >
* {labelProps.props.item.label}
* </Text>
* ));
*/
setBottomTabBarLabel = bottomTabBarLabel => {
this.bottomTabBarLabel = bottomTabBarLabel;
};
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 your own bottom tab bar </caption>
*
* import React from "react";
* import {Text, View, TouchableOpacity} from "react-native";
*
* import {isTabletOrIPad} from "@src/utils";
* import {
* FontWeights,
* textRTLStyleFix,
* correctBottomSafeArea
* } from "@src/styles/global";
* import {useSafeAreaInsets} from "react-native-safe-area-context";
*
* import Icon from "@src/components/Icon";
* import BadgeIcon from "@src/components/BadgeIcon";
* import {getMenuFontIconVariant} from "@src/navigators/util";
* import {glyphMap as bbIconGlyphMap} from "@src/components/BBIcon";
* import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
* import {useScreenProps} from "@src/navigators/v5/ScreenPropsProvider";
*
* export const applyCustomCode = externalCodeSetup => {
* const renderIcon = props => {
* const {calcFontSize} = useScreenProps(["calcFontSize"]);
*
* const {focused, item, tabBarOptions, colors} = props;
* const {tabBarActiveTintColor} = tabBarOptions;
*
* if (!item) return null;
*
* let color;
* let menuIcon;
* if (item.icon.type === "buddyboss") {
* if (bbIconGlyphMap[item.icon.id]) {
* menuIcon = {
* fontIconName: item.icon.id,
* fontIconVariant: getMenuFontIconVariant(item.icon, focused)
* };
* } else {
* menuIcon = {
* uri: focused ? item.icon.uri_active || item.icon.uri : item.icon.uri
* };
* }
* color = focused ? tabBarActiveTintColor : item.icon.color;
* } else {
* menuIcon = {
* uri: focused ? item.icon.uri_active || item.icon.uri : item.icon.uri
* };
* if (item.icon.type !== "custom") {
* color = focused ? tabBarActiveTintColor : item.icon.color;
* } else if (item.icon.fill_color) {
* color = focused ? tabBarActiveTintColor : item.icon.color;
* }
* }
*
* if (item.object === "notifications" || item.object === "messages") {
* return (
* <BadgeIcon
* calcFontSize={calcFontSize}
* tintColor={color}
* bottomTabsBg={colors.bottomTabsBg}
* warningColor={colors.warningColor}
* foregroundColor={item.icon.fg_color}
* platform="ios"
* inMore={false}
* app={"learnerapp"}
* type={item.object}
* icon={menuIcon}
* styles={{height: 25, width: 25}}
* />
* );
* }
*
* return (
* <Icon
* icon={menuIcon}
* foregroundColor={item.icon.fg_color}
* tintColor={color}
* styles={{height: 25, width: 25}}
* />
* );
* };
*
* const MyTabBar = withGlobalStyles(props => {
* const {state, descriptors, navigation, global, colors} = props;
*
* const insets = useSafeAreaInsets();
* const bottomSafeArea = correctBottomSafeArea(insets.bottom);
*
* const textStyle = [
* global.menuLabelStyle,
* {
* marginHorizontal: 5,
* marginTop: isTabletOrIPad() ? -(bottomSafeArea / 5) : 2,
* fontWeight: FontWeights["medium"],
* ...textRTLStyleFix(),
* opacity: 1,
* textAlign: "center"
* }
* ];
*
* return (
* <View style={{flexDirection: "row"}}>
* {state.routes.map((route, index) => {
* const {options} = descriptors[route.key];
*
* const item = route.params.item;
*
* const isFocused = state.index === index;
*
* const onPress = () => {
* const event = navigation.emit({
* type: "tabPress",
* target: route.key,
* canPreventDefault: true
* });
*
* if (!isFocused && !event.defaultPrevented) {
* navigation.navigate({name: route.name, merge: true});
* }
* };
*
* return (
* <TouchableOpacity
* onPress={onPress}
* style={{
* flex: 1,
* height: 40,
* alignItems: "center",
* alignSelf: "center",
* marginBottom: 33
* }}
* activeOpacity={1}
* >
* <View
* style={{
* height: 30,
* alignItems: "center",
* justifyContent: "center"
* }}
* >
* {renderIcon({
* focused: isFocused,
* item,
* colors,
* tabBarOptions: options
* })}
* </View>
*
* <Text
* style={[
* textStyle,
* {color: isFocused ? colors.linkColor : colors.textColor}
* ]}
* numberOfLines={1}
* ellipsizeMode="tail"
* allowFontScaling={false}
* >
* {item.label}
* </Text>
* </TouchableOpacity>
* );
* })}
* </View>
* );
* });
*
* externalCodeSetup.navigationApi.setBottomTabBar(props => (
* <MyTabBar {...props} />
* ));
* }
*/
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;
};
screensWithoutTabBar = [];
/**
* This hook allows you to customise which screens will not have a tab bar even when the "Show on All Screens" option is selected.
* Therefore you can use this hook to specifically select the pages where you don’t want to display tab bars.
* @method
* @param {Array} screensWithoutTabBar Screen names: {@link https://www.buddyboss.com/resources/app-codex/global.html#MainStackScreenNames}
* @example
*
* externalCodeSetup.navigationApi.setScreensWithoutTabBar(["BlogSingleScreen", "CoursesSingleScreen"])
*/
setScreensWithoutTabBar = screensWithoutTabBar => {
this.screensWithoutTabBar = screensWithoutTabBar;
};
}
Source