/**
* @typedef {Function} MoreScreenNavigationCallback
* @param {NavigationService} navigation
* @param {String} routeName
* @param {Object} menuItem Information about the menu item such as label, icon, type
* @param {number} userId Logged-in user's id
*/
/**
* @typedef {Function} TransformMoreScreenListCallback
* @param {Array<Object>} section Menu item information
* @param {Function} dispatch Redux dispatch function
* @param {NavigationService} navigation
* @param {Function} toUserBasedOnSettings Navigate to user function
* @param {Function} attemptDeepLink Attempt deep linking
* @param {Object} auth User details
* @return {Array<Object>} Modified section
*/
/**
* @typedef {Function} TransformContainerPaddingTopCallback
* @param {Number} containerPaddingTop
* @return {Number} New padding top value
*/
/**
* @typedef {Function} TransformContentInsetTopCallback
* @param {Number} contentInsetTop
* @return {Number} New content inset value
*/
/**
* @typedef {Function} TransformContentOffsetYCallback
* @param {Number} contentOffsetY
* @return {Number} New content offset value
*/
/**
* @typedef {Function} TransformSearchContainerPaddingTopCallback
* @param {Number} listTopMargin
* @param {Number} navHeight
* @return {Number} New padding top value. Note: aside from the result of add(), you can also return a number as the new value.
*/
/**
* @typedef {Object} MoreScreenProfileItemProps
* @property {Object} user Object containing user details
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {Object} styles Default Component style
* @property {Function} navigateToUserProfile function which navigates to user's profile
* @property {Boolean} hideHandle Boolean specifying whether to show or hide handles
* @property {Boolean} showProfile Boolean specifying whether to show or hide Profile Component set via custom code
*/
/**
/**
* @class
* More Screen (Screen with additional navigation links) Hooks.
* Instance name: moreScreenApi
You can use this hook to customize how the "More Screen" will behave when the user taps on it and override the default functionality based on your preferences.
* @example
* externalCodeSetup.moreScreenApi.METHOD_NAME
*/
export class MoreScreenHooksApi {
navigationHandler = null;
/**
* Sets the function that overrides the default "More Screen" navigation functionality.
* This hook is called whenever a menu item in More Screen is clicked.
* For example, you can configure how a menu item will behave after a user taps on it.
* @method
* @param {MoreScreenNavigationCallback} navigationHandler
* @example
* ...
* import {Linking} from "react-native";
* import {CommonActions} from "@react-navigation/native";
*
* export const applyCustomCode = externalCodeSetup => {
* const defaultNavigateTo = (navigation, routeName, menuItem, userId) => {
*
* //Attempt to open using React Native's Linking function based on different conditions...
* if (
* (menuItem.type === "page" ||
* menuItem.type === "custom" ||
* (menuItem.type === "post_type" && menuItem.object === "page")) &&
* menuItem.data &&
* menuItem.data.open_external
* ) {
* Linking.canOpenURL(menuItem.data.link)
* .then(canOpen => {
* if (canOpen) {
* Linking.openURL(menuItem.data.link);
* }
* })
* .catch(error => {
* Alert.alert("There was a problem", "This page cannot be opened.");
* });
* }
* //Otherwise, navigate to appropriate screen
* else {
* navigation.dispatch(
* CommonActions.navigate({
* name: menuItem.label === "Photos" ? "GlobalPhotos" : routeName,
* params: {
* item: menuItem,
* userId
* }
* })
* );
* }
* }
* }
*
* externalCodeSetup.moreScreenApi.setNavigationHandler(defaultNavigateTo);
*/
setNavigationHandler = navigationHandler => {
this.navigationHandler = navigationHandler;
};
tabsList = list => list;
/**
* You can use this hook to add or modify existing tabs in the More screen.
* @method
* @param {TransformMoreScreenListCallback} tabsList
* @example <caption> Add a new item in More Screen items that calls the logout action </caption>
* ...
* import { logout } from "@src/actions/auth"
*
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.moreScreenApi.setTabsList((section, dispatch) => {
*
* return [
* ...section,
* {
* label: "AUTH",
* screens: [
* {
* item: {
* label: "Logout",
* icon: {
* id: 'power-on',
* type: 'buddyboss',
* box_style: 'round', //"", "none", "round", "box"
* tint_color: `#000000`,
* monochrome: true,
* icon_style: `outlined`,
* },
* onPress: () => dispatch(logout()),
* hasNavArrow: false
* },
* routeName: "Logout"
* }
* ]
* }
* ]
* })
* }
*
* @example <caption> Create your own item component </caption>
* import { logout } from "@src/actions/auth"
*
* export const applyCustomCode = externalCodeSetup => {
*
* const CustomComponent = (dispatch) => {
* return <View style={{padding: 10, backgroundColor: "white", borderRadius: 5}}>
* <TouchableOpacity onPress={() => dispatch(logout())}>
* <Text>Logout</Text>
* </TouchableOpacity>
* </View>
* }
*
* externalCodeSetup.moreScreenApi.setTabsList((section, dispatch) => {
*
* return [
* ...section,
* {
* screens: [
* {
* item: {
* component: () => CustomComponent(dispatch)
* }
* }
* ]
* }
* ]
* })
* }
*/
setTabsList = tabsList => {
this.tabsList = tabsList;
};
replaceMenuItemRoutes = [];
/**
* You can use this to substitute the default routeName of the menu item in the More Screen.
* For example, instead of redirecting to the `DocumentsScreenMoreMenu3`, you can redirect them to a custom screen such as `ConfidentialDocsScreen`.
* Note: More Screen items are composed as: [ScreenName] + "MoreMenu" + [index of the MoreScreen tab in the bottom bar component].
* For example, if the MoreScreen tab is the 4th item in the bottom bar component, the routes names of the menu items would be: `ActivitiesScreenMoreMenu3`, `SettingsScreenMoreMenu3`
* @method
* @example <caption> Change route of menu item depending on the user </caption>
*
* ...
*
* import { getNavigationService } from "@src/utils/NavigationService";
*
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.reduxApi.addOnStoreCreateListener((props) => {
*
* let shouldUnsubscribe = false;
*
* const unsubscribe = props.subscribe(() => {
*
* const currentRoute = getNavigationService().getCurrentRoute();
*
* //If navigating in the MoreScreen...
* if (currentRoute?.params?.item?.object === "more") {
*
* const state = props.getState();
* const userId = 1;
*
* //Show a different route depending on the logged-in user
* if (state.user?.userObject.id === userId){
* externalCodeSetup.moreScreenApi.setReplaceMenuItemRoutes([
* {
* "originalRoute": "DocumentsScreenMoreMenu3",
* "replaceWith": "SettingsScreenMoreMenu3"
* }
* ])
* }
* shouldUnsubscribe = true;
* }
* if (shouldUnsubscribe) {
* unsubscribe()
* }
*
* });
*
* });
* }
*/
setReplaceMenuItemRoutes = replaceMenuItemRoutes => {
this.replaceMenuItemRoutes = replaceMenuItemRoutes;
};
useOriginalRouteNames = false;
/**
* Menu items inside the More Screen are constructed such as: DocumentsScreenMoreMenu3, ActivityScreenMoreMenu3.
* Set this to `true` if you'd like to use the original route name such as: DocumentsScreen or ActivitiesScreen.
* This is especially useful if you'd like to remove the More Screen using setFilterBottomTabsRoutes while "Tab bar Visibility" is set to "Show on All Screens"
* @method
* @example
*
* ...
*
* export const applyCustomCode = externalCodeSetup => {
* //Remove the default MoreScreen from the bottom tab component
* externalCodeSetup.navigationApi.setFilterBottomTabsRoutes(routes => {
* delete routes["MoreScreen"]
* return routes;
* });
*
* //Add a button which navigates to a custom More Screen
* externalCodeSetup.indexScreenApiHooks.enableAlwaysShowHeaderRight();
* externalCodeSetup.indexScreenApiHooks.setRenderHeaderRight(<HomeHeaderRight />);
*
* //Since a bottom tab route might not have the More Screen's menu items, navigate to "DocumentsScreen" instead of the inaccessible "DocumentsScreenMoreMenu1"
* externalCodeSetup.moreScreenApi.enableUseOriginalRouteNames();
* }
*/
enableUseOriginalRouteNames = () => {
this.useOriginalRouteNames = true;
};
containerPaddingTop = ({containerPaddingTop}) => containerPaddingTop;
/**
* You can use this hook to adjust the amount of padding top used by the more screen container.
* @method
* @param {TransformContainerPaddingTopCallback} containerPaddingTop
* @example
* externalCodeSetup.moreScreenApi.setContainerPaddingTop(props => props.containerPaddingTop);
*
*/
setContainerPaddingTop = containerPaddingTop => {
this.containerPaddingTop = containerPaddingTop;
};
contentInsetTop = ({contentInsetTop}) => contentInsetTop;
/**
* You can use this hook amount by which the scroll view content is inset from the edges of the scroll view.
* @method
* @param {TransformContentInsetTopCallback} contentInsetTop
* @example
* externalCodeSetup.moreScreenApi.setContentInsetTop(props => props.contentInsetTop);
*/
setContentInsetTop = contentInsetTop => {
this.contentInsetTop = contentInsetTop;
};
contentOffsetY = ({contentOffsetY}) => contentOffsetY;
/**
* You can use this hook to set the starting scroll offset.
* @method
* @param {TransformContentOffsetYCallback} contentOffsetY
* @example
* externalCodeSetup.moreScreenApi.setContentOffsetY(props => props.contentOffsetY);
*/
setContentOffsetY = contentOffsetY => {
this.contentOffsetY = contentOffsetY;
};
searchContainerPaddingTop = ({
listTopMargin,
navHeight,
searchContainerPaddingTop
}) => searchContainerPaddingTop;
/**
* You can use this hook to adjust the amount of padding top used by the container which the search and list components occupy.
* Note: aside from the result of add() which returns an animated value, you can also return a number as the new value.
* @ignore
* @method
* @param {TransformSearchContainerPaddingTopCallback} searchContainerPaddingTop
* @example
*
* ...
*
* import {add} from "react-native-reanimated";
* export const applyCustomCode = (externalCodeSetup: any) => {
* externalCodeSetup.moreScreenApi.setSearchContainerPaddingTop(props => {
* return add(props.listTopMargin, props.navHeight + 17);
* })
* }
*/
setSearchContainerPaddingTop = searchContainerPaddingTop => {
this.searchContainerPaddingTop = searchContainerPaddingTop;
};
MoreScreenProfileItem = null;
/**
* @ignore
* You can use this hook to modify the Profile Item Component on MoreScreen.
* @method
* @param {React.ComponentType<MoreScreenProfileItemProps>} MoreScreenProfileItem
* @example
* import { Text, Image, TouchableOpacity} from "react-native";
*
* externalCodeSetup.moreScreenApi.setMoreScreenProfileItem( props => {
* const {global, colors} = props;
* return (
* <TouchableOpacity
* activeOpacity={0.5}
* onPress={() => props.navigateToUserProfile()}
* style={{
* flexDirection: "row",
* alignItems: "center",
* marginTop: 15,
* padding: 15,
* borderRadius: 10,
* backgroundColor: colors.bodyFrontBg
* }}
* >
* <Image
* source={{uri: props.user.avatar_urls.full}}
* style={{width: 60, height: 60, borderRadius: 30, marginRight: 10}}
* />
* <Text style={{fontSize: 34}}>Hi, {props.user.fullname}</Text>
* </TouchableOpacity>
* )
*});
*/
setMoreScreenProfileItem = MoreScreenProfileItem => {
this.MoreScreenProfileItem = MoreScreenProfileItem;
};
}
Source