Source

externalCode/notificationsScreen.js

/**
 * @typedef {Object} NotificationsItemWidgetAvatarComponentProps
 * @property {Object} item Notification object
 * @property {Object} styles Default notification item styles
 * @property {Boolean} notList Returns boolean which can be used to set marginLeft of notification item
 * @property {Function} getAvatar Helper function which returns the url of the user's avatar
 */

/**
 * @typedef {Object} NotificationsItemWrapperComponentProps
 * @property {Object} item Notification object
 * @property {Boolean} notList Returns `true` if component is not being used in a list such as if it's being used in the Block Screen's Notifications Widget.
 * @property {Function} thisRowCollapsed Function that is called when action panel starts animating on close.
 * @property {Function} renderRightActions Function that is expected to return an action panel that is going to be revealed from the right side when user swipes left.
 * @property {Function} onItemPress Function that is called when user pressed on the notification.
 * @property {Object} wrapperProps Contains different objects such as colors, action buttons, navigation etc.
 */

/**
 * @typedef {Object} NotificationsMoreButtonWrapperComponentProps
 * @property {Object} global App global style
 * @property {Object} colors App colors
 * @property {Object} item Notification object
 * @property {NavigationService} navigation
 * @property {Array} actionButtons Action buttons for ActionSheetButtonWrapper
 * @property {TranslationFunction} t
 * @property {Boolean} notList Returns `true` if component is not being used in a list such as if it's being used in the Block Screen's Notifications Widget
 * @property {Function} renderInnerContent Can be used by ActionSheetButtonWrapper to render the notification item row content
 * @property {Function} renderSheetHeader Can be used by ActionSheetButtonWrapper to render its ActionSheetHeader
 * @property {Boolean} shouldOpen Returns `true` if action sheet should open upon initialization
 * @property {Object} wrapStyle Default wrap component style
 */

/**
 * @typedef {Object} NotificationsItemRowComponentProps
 * @property {Object} styles Notification item styles
 * @property {Function} renderContent Helper function which renders the content of the notification item row. Parameters to pass in order are: `align`, `truncate`, `global`, `colors`, `item`, `textColor`, `navigation`
 * @property {Object} global App global style
 * @property {Object} colors App colors
 * @property {Object} item Notification object
 * @property {String} textColor
 * @property {NavigationService} navigation
 * @property {Function} formatDateFunc Helper function which returns time since last posted
 * @property {React.ComponentType} DefaultMetadataComponent Can be used to render the default metadata component. Requires the following props: `global`, `formatDateFunc`, `item`
 */

/**
 * @typedef {Object} NotificationItemMoreButtonProps
 * @property {Object} global App global style
 * @property {Object} colors App colors
 * @property {Boolean} notList Returns `true` if component is not being used in a list such as if it's being used in the Block Screen's Notifications Widget
 */

/**
 * @typedef {Object} NotificationsItemWidgetContentComponentProps
 * @property {Object} item Notification object
 * @property {Object} textStyle Default notification text styles
 * @property {Object} textProps Contains information on how text should be rendered
 * @property {Boolean} truncate Returns `true` if line content should be limited
 * @property {String} capitalizedStrippedTitle Returns title with capitalized character
 * @property {NavigationService} navigation
 * @property {Object} global App global style
 * @property {Object} colors App colors
 */

/**
 * @typedef {Object} NotificationsItemWidgetMetadataComponentProps
 * @property {Object} item Notification object
 * @property {Function} formatDateFunc Helper function which returns time since last posted
 * @property {Object} global App global style
 */

/**
 * @typedef {Function} TransformNotificationsParams
 * @param {FetchNotificationsParams}
 * @return {Object}
 */

/**
 * @typedef {Object} FetchNotificationsParams
 * @see {@link https://www.buddyboss.com/resources/api/#api-Notifications-GetBBNotifications}
 * @property {Number} per_page Maximum number of items to be returned in result set.
 * @property {Number} page Current page of the collection.
 * @property {String} sort_order Order sort attribute ascending or descending. Default value: `ASC`. Allowed values: `ASC`, `DESC`
 * @property {String} order_by Name of the field to order according to. Default value: `date_notified`. Allowed values: `id`, `date_notified`, `item_id`
 * @property {Boolean} is_new Limit result set to items from specific states
 */

/**
 * @typedef {Object} NotificationsListHeaderComponentProps
 * @property {Object} styles Default styles
 * @property {TranslationFunction} t
 * @property { String } screenTitle Title of screen
 * @property {Function} adjustedScroll Returns calculated values using react animated
 * @property {Object} global App global style
 * @property {Object} colors App colors
 * @property {Object} filterProps Props used by the filter
 * @property {Boolean} headerIsDark Returns `true` if the set color for the header is dark
 * @property {Number} fontSizeAdjustment Returns font adjusted values for the filter
 */

/**
 * @typedef {Function} TransformNotificationViewModelCallback
 * @property {Object} viewModel Notifications view model
 * @return {Object} New view model
 */

/**
 * @typedef {Function} TransformNotificationListPropsCallback
 * @property {Object} props Notifications list props
 * @return {Object}
 */

/**
 * @class
 * Notification screen hooks.
 * Instance name: notificationsScreenApi
 
   You can use this hook to customize the notifications screen such as by adding header icons and other actions.
 * @example
 * externalCodeSetup.notificationsScreenApi.METHOD_NAME
 */
export class NotificationsScreenApi {
	/**
	 * Use this to add a component to the right side of the header. The component will be visible even when the user scrolls down.
	 * @method
	 * @param {React.ComponentType<any>} renderer Component to render
	 * @example <caption>Add a link to another page</caption>
	 *
	 * In custom_code/NotificationHeader.js
	 * import React from 'react';
	 * import {withNavigation} from "@src/components/hocs/withNavigation";
	 * import IconButton from "@src/components/IconButton";
	 *
	 * const NotificationHeaderRight = (props) => {
	 *
	 *    return <IconButton
	 *        pressHandler={() => props.navigation.navigate("MessagesScreen")}
	 *        icon={{fontIconName: "check", weight: 300}}
	 *        tintColor="#aaa"
	 *        style={{
	 *            height: 20,
	 *            marginRight: -10,
	 *            alignSelf: "flex-end"
	 *        }}
	 *    />
	 *
	 * }
	 *
	 * export default withNavigation(NotificationHeaderRight);
	 *
	 * //In custom_code/index.js
	 *
	 * ...
	 * import NotificationHeader from "./components/NotificationHeader";
	 * export const applyCustomCode = externalCodeSetup => {
	 *   externalCodeSetup.notificationsScreenApi.setRenderHeaderRight(<NotificationHeader />);
	 *   externalCodeSetup.notificationsScreenApi.enableAlwaysShowHeaderRight();
	 * }
	 */
	setRenderHeaderRight = renderer => {
		this.renderHeaderRight = renderer;
	};

	alwaysShowHeaderRight = false;

	/**
	 * Use this to always show the header right component.
	 * @method
	 * @example
	 * externalCodeSetup.notificationsApiHooks.enableAlwaysShowHeaderRight();
	 */
	enableAlwaysShowHeaderRight = () => {
		this.alwaysShowHeaderRight = true;
	};

	NotificationsItemWidgetAvatarComponent = null;
	/**
	 * You can use this to change the profile avatar.
	 * @method
	 * @param {?React.ComponentType<NotificationsItemWidgetAvatarComponentProps>} NotificationsItemWidgetAvatarComponent
	 * @example
	 *
	 * //In custom_code/components/NotificationsItemWidgetAvatar.js...
	 *
	 * import React from "react";
	 * import AppAvatar from "@src/components/AppAvatar";
	 * import AppTouchableWithoutFeedback from "@src/components/AppTouchableOpacity";
	 * const AVATAR_SIZE = 50; //Default avatar size
	 * const AVATAR_MARGIN_LEFT = 8;
	 *
	 * const NotificationsItemWidgetAvatar = (props) => {
	 *
	 *    const { item, styles, notList, getAvatar } = props;
	 *
	 *    return (
	 *        <AppTouchableWithoutFeedback
	 *            onPress={item.navigateToProfile ? item.navigateToProfile : () => { }}
	 *            style={[
	 *                styles.avatarWrap,
	 *                { marginLeft: notList ? 0 : AVATAR_MARGIN_LEFT }
	 *            ]}
	 *        >
	 *            <AppAvatar
	 *                // size={AVATAR_SIZE}
	 *                size={30} //Use smaller avatar
	 *                name={item?.user?.name}
	 *                source={{
	 *                    uri: getAvatar(item?.avatar_urls?.full, 96)
	 *                }}
	 *            />
	 *        </AppTouchableWithoutFeedback>
	 *    )
	 *
	 * }
	 *
	 * export default NotificationsItemWidgetAvatar;
	 *
	 * //In custom_code/index.js...
	 *
	 * ...
	 *
	 * import NotificationsItemWidgetAvatar from "./components/NotificationsItemWidgetAvatar";
	 * export const applyCustomCode = externalCodeSetup => {
	 *   externalCodeSetup.notificationsScreenApi.setNotificationsItemWidgetAvatarComponent((props) => <NotificationsItemWidgetAvatar {...props} />)
	 * }
	 *
	 */
	setNotificationsItemWidgetAvatarComponent = NotificationsItemWidgetAvatarComponent => {
		this.NotificationsItemWidgetAvatarComponent = NotificationsItemWidgetAvatarComponent;
	};

	NotificationsItemWrapperComponent = null;
	/**
	 * You can use this hook to customize the NotificationsItemWrapperComponent.
	 * For example, you can use this hook to change the behavior of the component when the NotificationItem is swiped.
	 * @method
	 * @param {?React.ComponentType<NotificationsItemWrapperComponentProps>} NotificationsItemWrapperComponent
	 * @example
	 * import React from "react";
	 * import AppTouchableWithoutFeedback from "@src/components/AppTouchableOpacity";
	 * import Swipeable from "react-native-gesture-handler/Swipeable";
	 * import {RectButton} from "react-native-gesture-handler";
	 *
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *     externalCodeSetup.notificationsScreenApi.setNotificationsItemWrapperComponent(
	 *         props => {
	 *             const {
	 *                 children,
	 *                 item,
	 *                 swipeRef,
	 *                 notList,
	 *                 thisRowCollapsed,
	 *                 renderRightActions,
	 *                 onItemPress,
	 *                 wrapStyle,
	 *                 navigation
	 *             } = props;
	 *
	 *             if (!item) return null;
	 *
	 *             return !!!notList ? (
	 *                 <Swipeable
	 *                     ref={swipeRef}
	 *                     friction={2}
	 *                     overshootRight={false}
	 *                     rightThreshold={40}
	 *                     onSwipeableClose={thisRowCollapsed}
	 *                     renderRightActions={renderRightActions}
	 *                 >
	 *                     <RectButton activeOpacity={0} onPress={onItemPress} style={{flex: 1}}>
	 *                         {children}
	 *                     </RectButton>
	 *                 </Swipeable>
	 *             ) : (
	 *                 <AppTouchableWithoutFeedback
	 *                     style={wrapStyle}
	 *                     onPress={() =>
	 *                         navigateToNotifications(navigation, {
	 *                             idToOpen: item.id
	 *                         })
	 *                     }
	 *                 >
	 *                     {children}
	 *                 </AppTouchableWithoutFeedback>
	 *             );
	 *         }
	 *     );
	 * }
	 *
	 **/
	setNotificationsItemWrapperComponent = NotificationsItemWrapperComponent => {
		this.NotificationsItemWrapperComponent = NotificationsItemWrapperComponent;
	};

	NotificationsItemRowComponent = null;
	/**
	 * You can use this hook to customize the NotificationsItemRowComponent.
	 * For example, you can use this hook to modify how the content and metadata component are rendered.
	 * @method
	 * @param {?React.ComponentType<NotificationsItemRowComponentProps>} NotificationsItemRowComponent
	 * @example
	 *
	 * //In custom_code/components/NotificationsItemRowComponent.js...
	 *
	 * import React from "react"
	 * import {View, Text} from "react-native";
	 * const NotificationsItemRowComponent = ({
	 *   styles,
	 *   renderContent,
	 *   global,
	 *   colors,
	 *   item,
	 *   textColor,
	 *   navigation,
	 *   formatDateFunc,
	 *   DefaultMetadataComponent
	 * }) => <View style={styles.contentContainer}>
	 *     <View style={styles.fullWidth}>
	 *         <View>
	 *             {renderContent(
	 *                 "left",
	 *                 true,
	 *                 global,
	 *                 colors,
	 *                 item,
	 *                 textColor,
	 *                 navigation
	 *             )}
	 *         </View>
	 *
	 *         <Text style={[global.itemLightMeta, {marginTop: 6}]}>
	 *           {formatDateFunc(item.date)}
	 *         </Text>
	 *
	 *         //Same as date component above
	 *         <DefaultMetadataComponent
	 *             {...{
	 *                 global,
	 *                 formatDateFunc,
	 *                 item
	 *             }}
	 *         />
	 *     </View>
	 * </View>
	 *
	 * export default NotificationsItemRowComponent
	 *
	 * //In custom_code/index.js..
	 *
	 * import NotificationsItemRowComponent from "./components/NotificationsItemRowComponent"
	 * export const applyCustomCode = externalCodeSetup => {
	 *   externalCodeSetup.notificationsScreenApi.setNotificationsItemRowComponent(props => <NotificationsItemRowComponent {...props} />)
	 * }
	 **/
	setNotificationsItemRowComponent = NotificationsItemRowComponent => {
		this.NotificationsItemRowComponent = NotificationsItemRowComponent;
	};

	NotificationItemMoreButton = null;
	/**
	 * @ignore
	 * You can use this hook to customize the NotificationItemMoreButton.
	 * For example, you can use this hook to change the NotificationItemMoreButton's icon.
	 * @method
	 * @param {?React.ComponentType<NotificationItemMoreButtonProps>} NotificationItemMoreButton
	 * @example
	 *
	 * externalCodeSetup.notificationsScreenApi.setNotificationItemMoreButton(({colors, notList}) => {
	 *    return !!!notList && (
	 *       <Icon
	 *          icon={{fontIconName: "ellipsis-h", weight: 300}}
	 *          tintColor={colors.textIconColor}
	 *          styles={{
	 *             marginLeft: 10,
	 *             padding: 5
	 *          }}
	 *       />
	 *    )
	 * })
	 **/
	setNotificationItemMoreButton = NotificationItemMoreButton => {
		this.NotificationItemMoreButton = NotificationItemMoreButton;
	};

	NotificationsMoreButtonWrapperComponent = null;
	/**
	 * @ignore
	 * You can use this hook to customize the NotificationsMoreButtonWrapperComponent.
	 * For example, you can use this hook to change the behavior of the component when the NotificationMoreButton is tapped.
	 * @method
	 * @param {?React.ComponentType<NotificationsMoreButtonWrapperComponentProps>} NotificationsMoreButtonWrapperComponent
	 * @example
	 *
	 * //In custom_code/components/NotificationsMoreButtonWrapperComponent.js...
	 *
	 * import React from "react";
	 * import { View, Text } from "react-native"
	 * import ActionSheetButtonWrapper from "@src/components/ActionButtons/ActionSheetButtonWrapper";
	 * import AppTouchableWithoutFeedback from "@src/components/AppTouchableOpacity";
	 * import { navigateToNotifications } from "@src/utils/navigationActions";
	 * const NotificationsMoreButtonWrapperComponent = ({
	 *     global,
	 *     colors,
	 *     item,
	 *     navigation,
	 *     actionButtons,
	 *     t,
	 *     notList,
	 *     renderInnerContent,
	 *     renderSheetHeader,
	 *     shouldOpen,
	 *     wrapStyle,
	 *     children
	 * }) => {
	 *     //Default BuddyBoss implementation of Wrap component
	 *     const Wrap = () => !!!notList ? (
	 *         <ActionSheetButtonWrapper
	 *             {...{
	 *                 actionButtons,
	 *                 global,
	 *                 colors,
	 *                 t,
	 *                 object: item,
	 *                 renderInnerContent,
	 *                 renderSheetHeader
	 *             }}
	 *             disabled={false}
	 *             shouldOpen={shouldOpen}
	 *             touchableStyle={wrapStyle}
	 *         >
	 *             {children}
	 *         </ActionSheetButtonWrapper>
	 *     ) : (
	 *         <AppTouchableWithoutFeedback
	 *             style={wrapStyle}
	 *             onPress={() =>
	 *                 navigateToNotifications(navigation, {
	 *                     idToOpen: item.id
	 *                 })
	 *             }
	 *         >
	 *             {children}
	 *         </AppTouchableWithoutFeedback>
	 *     );
	 *
	 *     return <Wrap />;
	 * }
	 *
	 * export default NotificationsMoreButtonWrapperComponent;
	 *
	 * //In custom_code/index.js..
	 *
	 * ...
	 *
	 * import NotificationsMoreButtonWrapperComponent from "./components/NotificationsMoreButtonWrapperComponent";
	 * export const applyCustomCode = externalCodeSetup => {
	 *    externalCodeSetup.notificationsScreenApi.setNotificationsMoreButtonWrapperComponent(props => <NotificationsMoreButtonWrapperComponent {...props} />)
	 * }
	 **/
	setNotificationsMoreButtonWrapperComponent = NotificationsMoreButtonWrapperComponent => {
		this.NotificationsMoreButtonWrapperComponent = NotificationsMoreButtonWrapperComponent;
	};

	NotificationsItemWidgetContentComponent = null;
	/**
	 * You can use this to change or modify the notification content component of your app.
	 * @method
	 * @param {?React.ComponentType<NotificationsItemWidgetContentComponentProps>} NotificationsItemWidgetContentComponent
	 * @example <caption> Modify content according to notification data </caption>
	 *
	 * //In custom_code/components/NotificationsItemWidgetContentComponent.js...
	 *
	 *
	 * import React from "react";
	 * import { Text } from "react-native";
	 * import { RichHtmlText } from "@src/utils/htmlRender"; //Buddyboss helper component which is utilizes `import HTML from "react-native-render-html";`
	 * import HTML from "react-native-render-html";
	 *
	 * const NotificationsItemWidgetContent = (props) => {
	 *
	 *    const { item, textProps, truncate, colors, capitalizedStrippedTitle, textStyle, global, navigation } = props;
	 *
	 *    //By default, BuddyBoss uses RichHtmlText helper to display the content
	 *    const renderDefaultContent = () => <RichHtmlText
	 *        {...textProps}
	 *        limitLines={truncate}
	 *        colors={colors}
	 *        richText={capitalizedStrippedTitle}
	 *        style={
	 *            item.title
	 *                ? { ...textStyle, marginTop: 2, ...global.regularText }
	 *                : textStyle
	 *        }
	 *    />
	 *
	 *    //Create new renderer...
	 *    const verifiedUsers = [1, 2];
	 *    const actionsToMarkNotification = ["new_membership_request", "friendship_accepted"];
	 *
	 *    const modifyContent = (verifiedUsers.includes(item.secondary_item_id) && actionsToMarkNotification.includes(item.action)) ? true : false;
	 *
	 *    const modifiedContent = `<p style="color:red; fontSize: 15">${capitalizedStrippedTitle} </p>`;
	 *    const renderModifiedContent = () => <HTML
	 *	        html={modifiedContent}
	 *        renderers={{
	 *            p: (_, children, convertedCSSStyles, {key}) => {
	 *                return (
	 *                    <Text
	 *                        numberOfLines={truncate === false ? undefined : 1}
	 *                        ellipsizeMode="tail"
	 *                        key={key}
	 *                        style={convertedCSSStyles}
	 *                    >
	 *                        {children}
	 *                    </Text>
	 *                );
	 *            }
	 *        }}
	 *    />
	 *    //End modified renderer...
	 *
	 *    return (<>
	 *        {!!item.title && (
	 *            <Text
	 *                numberOfLines={1}
	 *                ellipsizeMode={"tail"}
	 *                style={{
	 *                    ...textStyle,
	 *                    marginTop: 2
	 *                }}
	 *                {...textProps}
	 *            >
	 *                {item.title}
	 *            </Text>
	 *        )}
	 *
	 *        {modifyContent ? renderModifiedContent() : renderDefaultContent()}
	 *
	 *     </>)
	 * }
	 *
	 * export default NotificationsItemWidgetContent;
	 *
	 * //In custom_code/index.js...
	 *
	 * ...
	 *
	 * import NotificationsItemWidgetContent from "./components/NotificationsItemWidgetContent"
	 * export const applyCustomCode = externalCodeSetup => {
	 *  externalCodeSetup.notificationsScreenApi.setNotificationsItemWidgetContentComponent((props) => <NotificationsItemWidgetContent {...props} />)
	 * }
	 *
	 */
	setNotificationsItemWidgetContentComponent = NotificationsItemWidgetContentComponent => {
		this.NotificationsItemWidgetContentComponent = NotificationsItemWidgetContentComponent;
	};

	NotificationsItemWidgetMetadataComponent = null;
	/**
	 * You can use this to change the bottom component of the app where the date is displayed.
	 * @method
	 * @param {?React.ComponentType<NotificationsItemWidgetMetadataComponentProps>} NotificationsItemWidgetMetadataComponent
	 * @example
	 *
	 * //In custom_code/components/NotificationsItemWidgetMetadataComponent.js...
	 *
	 * import React from "react";
	 * import {Text} from "react-native";
	 *
	 * const NotificationsItemWidgetMetadataComponent = (props) => {
	 *
	 *    const { global, formatDateFunc, item } = props;
	 *
	 *    const date = item.date; //To see how many days have passed, use: formatDateFunc(item.date)
	 *
	 *    return (
	 *        <Text style={[global.itemLightMeta, {marginTop: 6}]}>
	 *            {date}
	 *        </Text>
	 *    )
	 * }
	 *
	 * export default NotificationsItemWidgetMetadataComponent;
	 *
	 * import NotificationsItemWidgetMetadataComponent from "./components/NotificationsItemWidgetMetadataComponent";
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *  externalCodeSetup.notificationsScreenApi.setNotificationsItemWidgetMetadataComponent((props) => <NotificationsItemWidgetMetadataComponent {...props} />)
	 * }
	 */
	setNotificationsItemWidgetMetadataComponent = NotificationsItemWidgetMetadataComponent => {
		this.NotificationsItemWidgetMetadataComponent = NotificationsItemWidgetMetadataComponent;
	};

	fetchParamsFilter = params => params;

	/**
	 * It overrides the parameters that are used to fetch notifications in the Notifications screen so that you can make it as customizable as possible when calling its API.
	 * @method
	 * @param {TransformNotificationsParams} fetchParamsFilter
	 *
	 * @example <caption> Create a custom filter in notifications screen </caption>
	 *
	 * //In custom_code/components/MyCustomScreen.js...
	 *
	 * import React, { useState } from "react";
	 * import { Modal, StyleSheet, Text, View, TouchableOpacity, Button, TextInput } from "react-native";
	 * import NotificationsScreen from "@src/containers/Custom/NotificationsScreen";
	 * import { notificationsRequested } from "@src/actions/notifications";
	 * import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
	 * import { useDispatch } from "react-redux";
	 *
	 * const filter = "unread"; //Available filters:  "unread", "read"
	 * const refresh = true; //Set to true to refresh list
	 *
	 * const MyCustomScreen = props => {
	 *
	 *     const dispatch = useDispatch();
	 *
	 *     const [modalVisible, setModalVisible] = useState(false);
	 *
	 *     const [search, setSearch] = useState(false);
	 *
	 *     const handleSubmit = () => {
	 *
	 *         //Set custom parameters before fetching
	 *         getExternalCodeSetup().notificationsScreenApi.setFetchParamsFilter((props) => {
	 *
	 *             //You can add more parameters such as "subject", "keyword" etc...
	 *             return {
	 *                 ...props,
	 *                 search
	 *             }
	 *         })
	 *
	 *         //Dispatch redux action to call api using customized filters
	 *         dispatch(notificationsRequested(filter, refresh));
	 *
	 *         setModalVisible(!modalVisible)
	 *
	 *     }
	 *
	 *     return (<>
	 *         <NotificationsScreen {...props} />
	 *         <View style={styles.centeredView}>
	 *             <Modal
	 *                 animationType="slide"
	 *                 transparent={true}
	 *                 visible={modalVisible}
	 *                 onRequestClose={() => {
	 *                     Alert.alert("Modal has been closed.");
	 *                     setModalVisible(!modalVisible);
	 *                 }}
	 *             >
	 *                 <View style={{position:"absolute", bottom: 150, right: 50}}>
	 *                     <View style={styles.modalView}>
	 *                         <TextInput
	 *                             style={{paddingHorizontal: 20, marginTop: 10, fontSize: 20}}
	 *                             autoFocus
	 *                             value={search}
	 *                             onChangeText={search => setSearch(search)}
	 *                             placeholder="Search"
	 *                         />
	 *                         <Button
	 *                             onPress={() => handleSubmit()}
	 *                             title="Filter"
	 *                         />
	 *                     </View>
	 *                 </View>
	 *             </Modal>
	 *             <TouchableOpacity
	 *                 style={[styles.button, styles.buttonOpen]}
	 *                 onPress={() => setModalVisible(true)}
	 *             >
	 *                 <Text style={styles.textStyle}>Show Filter Modal</Text>
	 *             </TouchableOpacity>
	 *         </View>
	 *     </>)
	 *
	 * }
	 *
	 *
	 * const styles = StyleSheet.create({
	 *     centeredView: {
	 *         flex: 1,
	 *         justifyContent: "center",
	 *         alignItems: "center",
	 *         marginTop: 22,
	 *         position: "absolute",
	 *         bottom: 100,
	 *         right: 50
	 *     },
	 *     modalView: {
	 *         margin: 20,
	 *         backgroundColor: "white",
	 *         borderRadius: 20,
	 *         padding: 35,
	 *         alignItems: "center",
	 *         shadowColor: "#000",
	 *         shadowOffset: {
	 *             width: 0,
	 *             height: 2
	 *         },
	 *         shadowOpacity: 0.25,
	 *         shadowRadius: 4,
	 *         elevation: 5
	 *     },
	 *     button: {
	 *         borderRadius: 20,
	 *         padding: 10,
	 *         elevation: 2,
	 *         justifyContent: "center",
	 *         alignSelf: "center"
	 *     },
	 *     buttonOpen: {
	 *         backgroundColor: "#000000",
	 *     },
	 *     textStyle: {
	 *         color: "white",
	 *         fontWeight: "bold",
	 *         textAlign: "center"
	 *     },
	 * });
	 *
	 * export default MyCustomScreen;
	 *
	 * //In custom_code/index.js...
	 *
	 * import MyCustomScreen from "./components/MyCustomScreen";
	 *
	 * export const applyCustomCode = externalCodeSetup => {
	 *
	 *    externalCodeSetup.navigationApi.addNavigationRoute(
	 *       "book",
	 *       "BookScreen",
	 *       MyCustomScreen,
	 *       "All"
	 *    );
	 *    externalCodeSetup.navigationApi.addNavigationRoute(
	 *       "book",
	 *       "BookScreen",
	 *       MyCustomScreen,
	 *       "Main"
	 *    );
	 * }
	 */
	setFetchParamsFilter = fetchParamsFilter => {
		this.fetchParamsFilter = fetchParamsFilter;
	};

	NotificationsListHeaderComponent = null;
	/**
	 * It is used to modify the appearance and structure of the notifications header component in the notifications list screen.
	 * @method
	 * @param {React.ComponentType<NotificationsListHeaderComponentProps>} NotificationsListHeaderComponent
	 * @example
	 * import React from "react";
	 * import {View} from "react-native";
	 * import {CommonActions} from "@react-navigation/native";
	 * import Animated from "react-native-reanimated";
	 * import FilterSegmented from "@src/components/FilterSegmented";
	 * import AnimatedListHeader from "@src/components/AnimatedListHeader";
	 * import NotificationHeaderButtons from "@src/components/Notifications/NotificationHeaderButtons";
	 * export const applyCustomCode = externalCodeSetup => {
	 *     externalCodeSetup.notificationsScreenApi.setNotificationsListHeaderComponent(
	 *         ({
	 *             styles,
	 *             t,
	 *             screenTitle,
	 *             adjustedScroll,
	 *             _globalStyles,
	 *             colors,
	 *             filterProps,
	 *             headerIsDark,
	 *             fontSizeAdjustment,
	 *             navigation,
	 *             onMarkAllRead,
	 *             selectedFilter,
	 *             enableMarkAllRead
	 *         }) => {
	 *             const renderHeaderAction = React.useMemo(
	 *                 () => () => (
	 *                     <NotificationHeaderButtons
	 *                         onMarkAllRead={onMarkAllRead}
	 *                         enableMarkAllRead={enableMarkAllRead}
	 *                         onNotificationPref={() => {
	 *                             navigation.dispatch(
	 *                                 CommonActions.navigate({
	 *                                     name: "NotificationPreferencesScreen"
	 *                                 })
	 *                             );
	 *                         }}
	 *                         style={{
	 *                             height: 26
	 *                         }}
	 *                     />
	 *                 ),
	 *                 [onMarkAllRead, enableMarkAllRead]
	 *             );
	 *
	 *             return (
	 *                 <Animated.View style={styles.container}>
	 *                     {!!screenTitle && (
	 *                         <AnimatedListHeader
	 *                             renderAction={selectedFilter === "unread" && renderHeaderAction}
	 *                             title={t(screenTitle)}
	 *                             scrollY={adjustedScroll}
	 *                             global={_globalStyles}
	 *                             style={styles.header}
	 *                         />
	 *                     )}
	 *                     <View style={styles.filterContainer}>
	 *                         <FilterSegmented
	 *                             {...filterProps}
	 *                             headerIsDark={headerIsDark}
	 *                             global={_globalStyles}
	 *                             colors={colors}
	 *                             fontSizeAdjustment={fontSizeAdjustment}
	 *                         />
	 *                     </View>
	 *                 </Animated.View>
	 *             );
	 *         }
	 *     );
	 * };
	 *
	 */
	setNotificationsListHeaderComponent = NotificationsListHeaderComponent => {
		this.NotificationsListHeaderComponent = NotificationsListHeaderComponent;
	};

	notificationViewModelFilter = viewModel => viewModel;

	/**
	 * Sets the callback function that can change an existing notification view model object.
	 * @method
	 * @param {TransformNotificationViewModelCallback} notificationViewModelFilter
	 * @example
	 * externalCodeSetup.notificationSingleScreenApi.setNotificationViewModelFilter((viewModel) => {
	 *     return {
	 *         ...viewModel,
	 *     }
	 * })
	 */
	setNotificationViewModelFilter = notificationViewModelFilter => {
		this.notificationViewModelFilter = notificationViewModelFilter;
	};

	notificationsFiltersFilter = filters => filters;

	/**
	 * Sets the available filter function for the notifications list.
	 * @method
	 * @example <caption> Add an "all" filter </caption>
	 * notificationsScreenApi.setNotificationsFiltersFilter(() => [
	 *   "unread",
	 *   "read",
	 *   "all"
	 * ]);
	 */
	setNotificationsFiltersFilter = notificationsFiltersFilter => {
		this.notificationsFiltersFilter = notificationsFiltersFilter;
	};

	notificationsListProps = () => {};

	/**
	 * You can use this to modify the props being passed to the notifications list component
	 * @method
	 * @param {TransformNotificationListPropsCallback} notificationsListProps
	 * @example
	 * externalCodeSetup.notificationsScreenApi.setNotificationsListProps(props => {
	 *  return {
	 *      data: props.notifications
	 *  };
	 *})
	 */
	setNotificationsListProps = notificationsListProps => {
		this.notificationsListProps = notificationsListProps;
	};
}