Class

AppPagesApi

AppPagesApi()

App Page Hooks Instance name: appPagesHooksApi.

Modifies the appearance and functionality of the app pages.

Constructor

# new AppPagesApi()

Example
externalCodeSetup.appPagesHooksApi.METHOD_NAME

Methods

# setActivitiesItemWidgetComponent(ActivitiesItemWidgetComponentnullable)

It is used to modify the appearance and structure of the activities widget item of an app page.

Parameters:
Name Type Attributes Description
ActivitiesItemWidgetComponent React.ComponentType.<ActivitiesItemWidgetComponentProps> <nullable>
Example

Use the default widget component and also modify the content display

//In custom_code/components/ActivitiesItemWidget.js...

import React from "react";
import { View, StyleSheet, Text } from "react-native";
import AppAvatar from "@src/components/AppAvatar";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import { getAvatar } from "@src/utils";
import { dateRenderer, spanRenderer } from "@src/utils/htmlRender";
import { FontWeights } from "@src/styles/global";
import { stripActivityTags } from "@src/utils/buddypress";
import HTML from "react-native-render-html";
import ActivityPrivacyButton from "@src/components/Activity/Privacy/ActivityPrivacyButton";

const ActivityHeader = (props) => {

   const {
       user,
       item,
       global,
       colors,
       tagsStyles,
       attemptDeepLink,
       showAvatar,
       style,
       textColor,
       setItemHeight = () => { },
       onChangePrivacy,
       privacyModalVisible,
       contentWrapperStyle,
       avatarSize,
       hidePrivacy
   } = props;

   const lightText = colors.descLightTextColor;

   let activityContent = item.action;

   //(The following codes are examples only and can be safely removed from the component)
   //Change the display content of the activity item.
   const status = `<span>(User status: verified)</span>`; //Create html element for displaying verified status
   activityContent += status;
   //End

   let avatarName = item?.user?.name || "";
   if (item?.user?.id === user?.id) avatarName = user.name; // user is unavailable during guest login

   const showPrivacy =
       !hidePrivacy &&
       item.can_edit &&
       (item.type === "activity_update" || item.type === "activity_comment") &&
       item.component !== "groups";

   const onLayout = ({
       nativeEvent: {
           layout: { height }
       }
   }) => {
       setItemHeight(height);
   };

   const tColor = textColor || colors.textColor;

   return (
       <View style={[global.row, styles.header, style]}>
           {showAvatar && (
               <AppTouchableOpacity onPress={item.authorClick}>
                   <AppAvatar
                       userId={item.user.user_id}
                       size={avatarSize || 40}
                       name={avatarName}
                       source={
                           item.avatarUrl
                               ? { uri: getAvatar(item.avatarUrl, 96) }
                               : require("@src/assets/img/default/default-member-img.png")
                       }
                   />
               </AppTouchableOpacity>
           )}
           <View
               onLayout={onLayout}
               style={[
                   styles.text,
                   { marginLeft: showAvatar ? 10 : 0 },
                   contentWrapperStyle
               ]}
           >
               <HTML
                   classesStyles={{ "activity-to": { marginHorizontal: 3 } }}
                   tagsStyles={{
                       ...tagsStyles,
                       rawtext: {
                           ...global.activityHtmlrawtext,
                           color: tColor
                       },
                       p: { ...global.activityHtmlp, color: tColor },
                       a: {
                           ...global.activityHtmla,
                           color: tColor,
                           textDecorationLine: "none"
                       }
                   }}
                   baseFontStyle={Object.assign(
                       {},
                       global.activityHtml,
                       textColor ? { color: textColor } : {}
                   )}
                   html={stripActivityTags(activityContent)}
                   onLinkPress={attemptDeepLink(false)}
                   renderers={{
                       a: dateRenderer,
                       span: spanRenderer
                   }}
               />

               <Text style={[global.activityDate, { color: lightText, marginTop: 3 }]}>
                   {item.dateRecorded}
               </Text>
           </View>
           {showPrivacy &&
               !!item.privacy &&
               item.privacy !== "media" && (
                   <ActivityPrivacyButton
                       privacyModalVisible={privacyModalVisible}
                       privacy={item.privacy}
                       onPress={onChangePrivacy}
                       colors={colors}
                       global={global}
                       style={{ width: 18, height: 13 }}
                   />
               )}
       </View>
   );
};

const styles = StyleSheet.create({
   item: {},
   header: {
       alignItems: "flex-start",
       justifyContent: "space-between",
       marginBottom: 11
   },
   text: {
       flex: 1
   }
});

export default ActivityHeader;

//In custom_code/index.js..

...
import ActivitiesItemWidget from "./components/ActivitiesItemWidget";
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.appPagesHooksApi.setActivitiesItemWidgetComponent( (props) => <ActivitiesItemWidget {...props} />);
}

# setActivitiesWidgetComponent(ActivitiesWidgetComponentnullable)

It is used to modify the appearance and structure of the activities block of an app page. You can set a component to display various activities widgets in your app pages similar to the ones you have in your home screen.

Parameters:
Name Type Attributes Description
ActivitiesWidgetComponent React.ComponentType.<ActivitiesWidgetComponentProps> <nullable>
Example

Feature an activity

//In custom_code/components/ActivitiesWidget.js

import React from 'react';
import { View } from 'react-native';
import { globalStyle } from "@src/styles/global";
import { useSelector } from "react-redux"; //use useSelector to get state from redux
import WidgetTitle from "@src/components/Widgets/WidgetTitle"; //Use BuddyBoss WidgetTitle component
import FastImage from 'react-native-fast-image';
import { ItemTitle } from "@src/components/TextComponents"; //Use BuddyBoss ItemTitle component
const ActivitiesWidget = (props) => {
   const globalStyles = useSelector((state) => globalStyle(state.config.styles)) // Get style from redux
   const { colors, global } = globalStyles;

   const featuredActivity = props.activities[0];

   return (<View
       style={[
           global.widget,
           {
               backgroundColor: props.bgColor,
               borderBottomColor: colors.borderColor
           }
       ]}
   >
       <View style={global.widgetInner}>

           <WidgetTitle
               colors={colors}
               global={global}
               style={{ marginTop: 5 }}
               title={"Featured Activity"}
               seeMoreHidden={false}
               seeMoreHandler={props.onActivitiesSeeAllClick} //Use props passed to redirect to "all activities" screen
               seeMoreLabel={"See all activities"}
           />

           <View>
                   <FastImage
                       style={{ width: "auto", height: 200 }}
                       source={{ uri: featuredActivity.bp_media_ids[0].url }} />

                   <View style={{marginTop: 10, marginLeft: 20}}>
                     <ItemTitle global={global}>Author: {featuredActivity.name} </ItemTitle>
                   </View>
           </View>
       </View>
   </View>)
}

export default ActivitiesWidget;

//In custom_code/index.js

...

import ActivitiesWidget from "./components/ActivitiesWidget";
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.appPagesHooksApi.setActivitiesWidgetComponent( (props) => <ActivitiesWidget {...props} />);
};

# setActivitiesWidgetTitle(ActivitiesWidgetTitlenullable)

You can use this to change the activities widget's title.

Parameters:
Name Type Attributes Description
ActivitiesWidgetTitle React.ComponentType.<ActivitiesWidgetTitleProps> <nullable>
Example

Add Icon to WidgetTitle

...

import Icon from "@src/components/Icon";
import WidgetTitle from "@src/components/Widgets/WidgetTitle";

export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setActivitiesWidgetTitle((props) => {

   const localIcon = require("./assets/img/like-filled.png");
   const WidgetIconComp = (
     <Icon
       icon={localIcon}
       tintColor={props.colors.textColor}
       styles={{
         marginLeft: 2,
         marginRight: 11,
         height: 19,
         width: 19,
         opacity: 0.45
       }}
     />
   );

   const newProps = {
     ...props,
     WidgetIcon: WidgetIconComp
   }

   return <WidgetTitle {...newProps} />;

 })
}

# setCoursesWidgetComponent(CoursesWidgetComponentnullable)

You can use this filter to set a component that displays course widgets in other app pages such as in a home screen. Do keep in mind that this hook overrides the components you use in the Course Categories screen and enables you to have more design flexibility to the courses section. So if you want to change only the widget in any app page course options, you refer to our documentation on coursesHooksApi.WidgetItemCourseComponent.

Parameters:
Name Type Attributes Description
CoursesWidgetComponent React.ComponentType.<CoursesWidgetComponentProps> <nullable>
Example

Display a promotional banner in place of the widget items

//In custom_code/components/CoursesWidget.js
import React from 'react';
import { View, Alert } from 'react-native';
import { globalStyle } from "@src/styles/global";
import { useSelector } from "react-redux"; //use useSelector to get state from redux
import WidgetTitle from "@src/components/Widgets/WidgetTitle"; //Use BuddyBoss WidgetTitle component
import { TouchableOpacity } from 'react-native-gesture-handler';
import FastImage from 'react-native-fast-image';
const CoursesWidget = (props) => {
   const globalStyles = useSelector((state) => globalStyle(state.config.styles)) // Get style from redux
   const { colors, global } = globalStyles;

   return (<View
       style={[
           global.widget,
           {
               backgroundColor: props.bgColor,
               borderBottomColor: colors.borderColor
           }
           ]}
        >
       <View style={global.widgetInner}>

           //Use BB component that can display Courses title and a See all link
           <WidgetTitle
               colors={colors}
               global={global}
               style={{ marginTop: 5 }}
               title={props.title}
               seeMoreHidden={false}
               seeMoreHandler={props.onCourseSeeAllClick} //Use props passed to redirect to all courses screen
               seeMoreLabel={props.t("home:seeAllCourses")}
           />

            //Display a promotional banner here
            <View>
                <TouchableOpacity onPress={() => Alert.alert("Redirecting you to our best selling courses...")}>
                    <FastImage
                        style={{ width: "auto", height: 200 }}
                        source={{ uri: "https://link-to-image.png" }} />
                </TouchableOpacity>
            </View>
        </View>
     </View>)
}

export default CoursesWidget;


//In custom_code/index.js...

 ...

 import CoursesWidget from "./components/CoursesWidget";
 export const applyCustomCode = externalCodeSetup => {
   externalCodeSetup.appPagesHooksApi.setCoursesWidgetComponent((props) => <CoursesWidget {...props} />);
 };

# setCoursesWidgetTitle(CoursesWidgetTitlenullable)

You can use this to change the courses widget's title.

Parameters:
Name Type Attributes Description
CoursesWidgetTitle React.ComponentType.<CoursesWidgetTitleProps> <nullable>
Example

Create your own widget title and change how See All button is handled

...

import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import Icon from "@src/components/Icon";
export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setCoursesWidgetTitle((props) => {

   const {
     colors,
     global,
     style,
     icon,
     title,
     textColor,
     seeMoreHidden,
     seeMoreHandler,
     seeMoreLabel,
     courses,
     t,
     navigation
   } = props;

   const goToCoursesTab = () => {
     const routeName = "CoursesScreenTabRoute3"; //You can check the name of tab routes by doing a console.log inside the setFilterBottomTabsRoutes hook
     const action = navigation.navigate(routeName);
     navigation.dispatch(action);
   }

   return <View style={[global.row, global.widgetHeader, style]}>
     <View style={[global.row, { flex: 1 }]}>

       {icon && typeof icon === "string" ? (
         <Icon
           icon={{ uri: icon }}
           tintColor={colors.textColor}
           styles={{
             marginLeft: 2,
             marginRight: 11,
             height: 19,
             width: 19,
             opacity: 0.45
           }}
         />
       ) : null}

       <Text
         style={[
           global.widgetTitle,
           textColor && { color: textColor },
           { marginRight: "auto" }
         ]}
       >
         {title}
       </Text>
     </View>
     {!seeMoreHidden && (
       <AppTouchableOpacity
         style={global.widgetSeeLink}
         onPress={() => goToCoursesTab()}
       >
         <Text style={global.seeLink}>{seeMoreLabel}</Text>
       </AppTouchableOpacity>
     )}
   </View>

 })
}

# setForumsWidgetTitle(ForumsWidgetTitlenullable)

You can use this to change the forums widget's title.

Parameters:
Name Type Attributes Description
ForumsWidgetTitle React.ComponentType.<ForumsWidgetTitleProps> <nullable>
Example
...

import WidgetTitle from "@src/components/Widgets/WidgetTitle";

export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setForumsWidgetTitle((props) => {

   const newProps = {
     ...props,
     seeMoreHandler: () => console.log("Change handler function")
   }

   return <View style={{ backgroundColor: "gray", padding: 10 }}>
     <WidgetTitle {...newProps} />
   </View>

 })
}

# setGroupsWidgetTitle(GroupsWidgetTitlenullable)

You can use this to change the groups widget's title.

Parameters:
Name Type Attributes Description
GroupsWidgetTitle React.ComponentType.<GroupsWidgetTitleProps> <nullable>
Example

Display total number of groups from redux state

...

import {useSelector} from "react-redux";
import WidgetTitle from "@src/components/Widgets/WidgetTitle";

export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setGroupsWidgetTitle((props) => {

   const count = useSelector(state => state.socialGroups.all.count);

   const newProps = {
     ...props,
     seeMoreLabel: (count) ? `See all ${count} groups` : `See all`
   }

   return <WidgetTitle {...newProps} />;

 })
}

# setHomePageTitleIcon(icon)

Set an icon in any of the app pages if the app page is in the main navigation (or bottom navigation bar) at index 0. It can be used to automatically replace the default Home screen logo which can be found in the BuddyBoss WordPress admin > BuddyBoss App > Branding > Images.

Parameters:
Name Type Description
icon LocalImageSource
Example
externalCodeSetup.appPagesHooksApi.setHomePageTitleIcon("https://link-to-image.png");

# setLinksWidgetTitle(LinksWidgetTitlenullable)

You can use this to change the quick links widget's title.

Parameters:
Name Type Attributes Description
LinksWidgetTitle React.ComponentType.<LinksWidgetTitleProps> <nullable>
Example

Add a Go To Link button which can use deep link handler with the help of HOCs

...

import { compose } from "recompose";
import { withNavigation } from "react-navigation";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import WidgetTitle from "@src/components/Widgets/WidgetTitle";
import withDeeplinkClickHandler from "@src/components/hocs/withDeeplinkClickHandler";
import withGlobalStyles from "@src/components/hocs/withGlobalStyles"

export const applyCustomCode = externalCodeSetup => {

 const TouchComponent = (props) => (
   <AppTouchableOpacity
     style={props.global.widgetSeeLink}
     onPress={() => props.attemptDeepLink(false)(null, "https://buddyboss.com")}
   >
     <Text style={props.global.seeLink}>Go To Link</Text>
   </AppTouchableOpacity>
 )

 const TouchWithHOC = compose(
   withNavigation,
   withDeeplinkClickHandler,
   withGlobalStyles
 )(TouchComponent);

 externalCodeSetup.appPagesHooksApi.setLinksWidgetTitle((props) => {

   const {
     global,
     quickLinks,
     textColor,
     title
   } = props;

   return <View style={[global.row, global.widgetHeader]}>
     <View style={[global.row, { flex: 1 }]}>

       <Text
         style={[
           global.widgetTitle,
           textColor && { color: textColor },
           { marginRight: "auto" }
         ]}
       >
         {title}
       </Text>
     </View>
     <TouchWithHOC />
   </View>

 })
}

# setMembersWidgetTitle(MembersWidgetTitlenullable)

You can use this to change the members widget's title.

Parameters:
Name Type Attributes Description
MembersWidgetTitle React.ComponentType.<MembersWidgetTitleProps> <nullable>
Example

Hide See All button

...
import WidgetTitle from "@src/components/Widgets/WidgetTitle";

export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setMembersWidgetTitle((props) => {

   const newProps = {
     ...props,
     seeMoreHidden: true
   }

   return <WidgetTitle {...newProps} />;

 })
}

# setNotificationsWidgetTitle(NotificationsWidgetTitlenullable)

You can use this to change the notifications widget's title.

Parameters:
Name Type Attributes Description
NotificationsWidgetTitle React.ComponentType.<NotificationsWidgetTitleProps> <nullable>
Example
...
import WidgetTitle from "@src/components/Widgets/WidgetTitle";
export const applyCustomCode = externalCodeSetup => {
 externalCodeSetup.appPagesHooksApi.setNotificationsWidgetTitle((props) => {
  return <View style={{backgroundColor: "cyan"}}><WidgetTitle {...props} /></View>;
 })
}

# setTopicItemWidgetComponent(TopicItemWidgetComponentnullable)

It is used to modify the appearance and structure of the topics/discussions widget item of an app page.

Parameters:
Name Type Attributes Description
TopicItemWidgetComponent React.ComponentType.<TopicItemWidgetComponentProps> <nullable>
Example

Add more details to the topic item

//In custom_code/components/TopicItemWidget.js...
import React from "react";
import {View, Text, Image, StyleSheet, Platform} from "react-native";
import {getAvatar} from "@src/utils";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import AppAvatar from "@src/components//AppAvatar";
import {titleTrim} from "@src/utils";
const margin = Platform.OS === "ios" ? 16 : 14;

const TopicItemWidget = ({topic, global, colors, isLast, textColor}) => {

return (
  <AppTouchableOpacity onPress={topic.toSingle}>
   <View
     style={[
       styles.itemInner,
       styles.border,
       {
          borderBottomColor: isLast ? "transparent" : colors.borderColor,
          marginBottom: isLast ? 0 : margin - 1
       }
     ]}
   >
     <AppTouchableOpacity
       onPress={topic.navigateToProfile ? topic.navigateToProfile : () => {}}
       style={styles.itemAvatarWrap}
     >
       <AppAvatar
         size={40}
         name={topic.author.name}
         source={{
           uri: getAvatar(topic.author.avatar, 78)
         }}
       />
         </AppTouchableOpacity>
           <View
             style={{
               flex: 1
             }}
           >
             <Text
               style={[
                 global.itemTitle,
                 textColor && {color: textColor},
                 {marginBottom: 5, marginTop: 2}
               ]}
             >
               {titleTrim(topic.title)}
             </Text>
             <Text
               style={[
                 textColor && {color: textColor},
                 {marginBottom: 5, marginTop: 2}
               ]}
             >
               {topic.shortContent}
             </Text>
             <View style={global.row}>
               <Text style={global.itemMeta}>{topic.author.name}</Text>
               <View style={global.dotSep} />
               <Text style={global.itemMeta}>{topic.voiceCount}</Text>
               <View style={global.dotSep} />
               <Text style={[global.itemMeta, {flexShrink: 1}]} numberOfLines={1}>
                 {topic.replyCount}
               </Text>
             </View>
           </View>
         </View>
       </AppTouchableOpacity>
  );
};

export default TopicItemWidget;

const styles = StyleSheet.create({
	itemInner: {
	  alignItems: "flex-start",
   flexDirection: "row"
 },
 itemAvatarWrap: {
   marginRight: 10,
   marginTop: 3
 },
 border: {
   paddingBottom: margin,
   borderBottomWidth: StyleSheet.hairlineWidth
 }
});

//In custom_code/index.js...

import TopicItemWidget from "./components/TopicItemWidget"
export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setTopicItemWidgetComponent((props) => {
   return <TopicItemWidget {...props} />
 });
}

# setTopicsWidgetComponent(TopicsWidgetComponentPropsnullable)

It is used to modify the appearance and structure of the topics/discussions block of an app page.

Parameters:
Name Type Attributes Description
TopicsWidgetComponentProps React.ComponentType.<TopicsWidgetComponentProps> <nullable>
Example

Use the default topics widget component but without the "See all" link

//In custom_code/components/TopicWidget.js

import React from "react";
import {View} from "react-native";
import WidgetItemTopic from "@src/components/Widgets/WidgetItemTopic";
import {topicToViewModel} from "@src/utils/index";
import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
import WidgetTitleIcon from "@src/components/Widgets/WidgetTitleIcon";
import WidgetTitle from "@src/components/Widgets/WidgetTitle";
import {compose} from "recompose";
import {bindActionCreators} from "redux";
import * as TopicActions from "@src/actions/topics";
import withProfileNavigation from "@src/components/hocs/withProfileNavigation";
import {useDispatch} from "react-redux";

const TopicWidget = (props) => {

   const dispatch = useDispatch();

   const topicActions = bindActionCreators(TopicActions, dispatch);

   const {
       global,
       colors,
       t,
       bgColor,
       icon,
       toUserBasedOnSettings,
       lastItem,
       onTopicSeeAllClick,
       title,
       topics
   } = props;

   const textColor = props.parentStyle?.textColor;

   if (!topics || !Array.isArray(topics) || topics.length === 0) return null;

   const WidgetIcon = <WidgetTitleIcon icon={icon} color={colors.textColor} />;

   return (
       <View style={[global.widget, {backgroundColor: bgColor}]}>
           <View style={global.widgetInner}>
               <WidgetTitle
                   colors={colors}
                   global={global}
                   WidgetIcon={WidgetIcon}
                   textColor={textColor}
                   title={title}
                   seeMoreHidden={true}
                   seeMoreHandler={onTopicSeeAllClick}
                   seeMoreLabel={t("home:seeAllTopics")}
               />
               <View style={global.widgetContent}>
                   {topics.map((topic, index) => {
                       const viewModel = topicToViewModel(topic, {
                           topicActions,
                           toUserBasedOnSettings,
                           t
                       });
                       return (
                           <WidgetItemTopic
                               isLast={index + 1 === topics.length}
                               key={topic.id}
                               topic={viewModel}
                               colors={colors}
                               global={global}
                               textColor={textColor}
                           />
                       );
                   })}
               </View>
           </View>

           {!lastItem && <View style={global.widgetBorder} />}
       </View>
   );
}

export default compose(
	withProfileNavigation,
	withGlobalStyles
)(TopicWidget);

//In custom_code/index.js...

import TopicWidget from "./components/TopicWidget";
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.appPagesHooksApi.setTopicsWidgetComponent( (props) => <TopicWidget {...props} />);
}

# setTopicsWidgetTitle(TopicsWidgetTitlenullable)

You can use this to change the topics widget's title.

Parameters:
Name Type Attributes Description
TopicsWidgetTitle React.ComponentType.<TopicsWidgetTitleProps> <nullable>
Example

Use BB WidgetTitle component in a container while modifying some of its props

...

import WidgetTitle from "@src/components/Widgets/WidgetTitle";
export const applyCustomCode = externalCodeSetup => {

 externalCodeSetup.appPagesHooksApi.setTopicsWidgetTitle((props) => {

   const newProps = {
     ...props,
     title: "See all Discussions",
     textColor: "white"
   }

   return <View style={{backgroundColor: "gray", padding: 10}}>
       <WidgetTitle {...newProps} />
   </View>

 })
}