# new ActivitiesScreenHooksApi()
Example
externalCodeSetup.activitiesScreenApi.METHOD_NAME
Methods
# setActivityButtonsFilter(activityButtonsFilter)
It sets the filter functions so that you can change the "Activity" action buttons/ call-to-action buttons. The activity buttons for this filter can be used to add or modify buttons include like, comment, or edit buttons in the activity list screen.
Parameters:
Name | Type | Description |
---|---|---|
activityButtonsFilter |
ActivityButtonsFilterCallback | Function that changes call-to-action/activity buttons in the activity list screen |
Example
...
import { Text, TouchableOpacity } from 'react-native'
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.activitiesScreenApi.setActivityButtonsFilter((buttons, item, actionsList, settings) => {
//Do something onPress
const onPress = () => {
//Call api...
}
return [
...buttons,
{
// use false if it should be hidden.
// User can also use data from item. For example, instead of static boolean value, user can use `item.can_comment` if button should show if user can also comment
permissionField: true,
jsx: (
<TouchableOpacity onPress={onPress}>
<Text>Share</Text>
</TouchableOpacity>
)
}]
})
}
# setActivityCommentAvatar(ActivityCommentAvatar)
You can use this to customize the author avatar of the activity comments.
Parameters:
Name | Type | Description |
---|---|---|
ActivityCommentAvatar |
React.ComponentType.<ActivityCommentAvatarProps> |
Example
...
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import AppAvatar from "@src/components/AppAvatar";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.activitiesScreenApi.setActivityCommentAvatar(
({handleAuthorClick, userId, size, source}) => (
<AppTouchableOpacity onPress={handleAuthorClick}>
<AppAvatar
userId={userId}
size={size}
source={source}
/>
</AppTouchableOpacity>
)
);
}
# setActivityCommentButtonsFilter(activityCommentButtonsFilter)
It overrides the filters used in the ActivityComment component.
You can use this together with setActivityButtonsFilter
to add or remove buttons in the ActivityComment component.
Parameters:
Name | Type | Description |
---|---|---|
activityCommentButtonsFilter |
TransformActivityCommentButtons |
Example
...
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.activitiesScreenApi.setActivityButtonsFilter(
(buttons, item, actionsList, settings) => {
//Do something onPress
const onPress = () => {
console.log(item);
};
//Add a share "Like" button
let newButtons = [
{
id: "reply",
permissionField: true,
jsx: (
<TouchableOpacity onPress={onPress}>
<Text>Share</Text>
</TouchableOpacity>
)
},
...buttons
];
//Replace the "Reply" button and add a new button
if (item.parentId){
newButtons = [
{
id: "custom",
permissionField: true,
jsx: (
<TouchableOpacity onPress={onPress}>
<Text>Custom | </Text>
</TouchableOpacity>
)
},
{
id: "reply",
permissionField: true,
jsx: (
<TouchableOpacity onPress={onPress}>
<Text>Reply</Text>
</TouchableOpacity>
)
},
buttons[1], //Delete button
buttons[2] //Show more button
]
}
return newButtons;
}
);
//Allow ActivityComment to render the button with the 'custom' id
externalCodeSetup.activitiesScreenApi.setActivityCommentButtonsFilter(filters => {
return [
...filters,
'custom'
]
})
}
# setActivityCommentHeaderComponent(ActivityCommentHeaderComponentnullable)
You can use this to customize the author name and post date of the activity comments. For example, you can add a "verified" badge beside the author's name using this hook.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
ActivityCommentHeaderComponent |
React.ComponentType.<ActivityCommentHeaderComponentProps> |
<nullable> |
Example
externalCodeSetup.activitiesScreenApi.setActivityCommentHeaderComponent(
props => {
const {styles, handleAuthorClick, username, date} = props;
return (
<View style={styles.textContainer}>
<Text style={styles.textInnerContainer}>
<Text onPress={handleAuthorClick} style={styles.text}>
{username}
</Text>
{" "}
{date}
</Text>
</View>
);
}
);
# setActivityHeaderComponent(ActivityHeaderComponentnullable)
It is used to modify the appearance and structure of the activities header component in the activities list screen.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
ActivityHeaderComponent |
React.ComponentType.<ActivityHeaderComponentProps> |
<nullable> |
Example
//In custom_code/components/ActivityHeader.js...
import React from "react";
import {View, StyleSheet, Text, useWindowDimensions} from "react-native";
import AppAvatar from "@src/components/AppAvatar";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import {dateRenderer, spanRenderer} from "@src/utils/htmlRender";
import {stripActivityTags} from "@src/utils/buddypress";
import ActivityPrivacyButton from "@src/components/Activity/Privacy/ActivityPrivacyButton";
import {getProfileImageSource} from "@src/components/Profile/Xprofile/utils";
import {withDefaultProfileImageSettings} from "@src/components/hocs/withDefaultProfileImageSettings";
import CustomHTML from "@src/components/HTML";
import Icon from "@src/components/Icon";
import {filters} from "@src/reducers/activities";
import {BuddyPressScopes} from "@src/services/enums/buddyPress";
const ActivityHeader = props => {
const {
t,
user,
item,
global,
colors,
tagsStyles,
attemptDeepLink,
showAvatar,
style,
textColor,
setItemHeight = () => {},
onChangePrivacy,
privacyModalVisible,
contentWrapperStyle,
avatarSize,
hidePrivacy,
profileAvatarType,
enableProfileGravatar,
defaultProfileAvatarType,
defaultCustomProfileAvatarImage,
activitiesFilter,
isGroupScreen,
renderActivityOptions
} = props;
const lightText = colors.descLightTextColor;
let avatarName = item.user?.name || "";
const {is_pinned} = item;
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 showPin = isGroupScreen
? item.component === BuddyPressScopes.groups
: activitiesFilter === filters[0] && item.isGroupPost === false;
const onLayout = ({
nativeEvent: {
layout: {height}
}
}) => {
setItemHeight(height);
};
const {width} = useWindowDimensions();
const tColor = textColor || colors.textColor;
return (
<View style={[global.row, styles.header, style]}>
{showAvatar && (
<AppTouchableOpacity onPress={item.authorClick}>
<AppAvatar
size={avatarSize || 40}
name={avatarName}
source={getProfileImageSource(item.user, {
avatarType: profileAvatarType,
enableGravatar: enableProfileGravatar,
defaultAvatarType: defaultProfileAvatarType,
defaultCustomAvatarImage: defaultCustomProfileAvatarImage
})}
/>
</AppTouchableOpacity>
)}
<View
onLayout={onLayout}
style={[
styles.text,
{marginLeft: showAvatar ? 10 : 0},
contentWrapperStyle
]}
>
<CustomHTML
allowedAllTags
classesStyles={{"activity-to": {marginHorizontal: 3}}}
tagsStyles={{
...tagsStyles,
rawtext: {
...global.activityHtmlrawtext,
color: tColor
},
p: {...global.activityHtmlp, color: tColor},
a: {
...global.activityHtmla,
color: tColor,
textDecorationLine: "none"
}
}}
contentWidth={width}
baseStyle={Object.assign(
{},
global.activityHtml,
textColor ? {color: textColor} : {}
)}
renderersProps={{
a: {onPress: attemptDeepLink(false)}
}}
source={{html: stripActivityTags(item.action)}}
renderers={{
a: dateRenderer,
span: spanRenderer
}}
/>
<View style={[global.row, {marginTop: 3}]}>
<Text style={[global.activityDate, {color: lightText}]}>
{item.dateRecorded} {`${item.is_edited ? `(${t("edited")})` : ""}`}
</Text>
{showPrivacy &&
!!item.privacy &&
item.privacy !== "media" && (
<ActivityPrivacyButton
hideBorder={true}
privacyModalVisible={privacyModalVisible}
privacy={item.privacy}
onPress={onChangePrivacy}
colors={colors}
global={global}
/>
)}
</View>
</View>
{showPin &&
is_pinned && (
<View style={styles.pinContainer}>
<Icon
icon={{fontIconName: "thumbtack", weight: "400"}}
tintColor={colors.textIconColor}
size={20}
/>
</View>
)}
{renderActivityOptions && renderActivityOptions()}
</View>
);
};
const styles = StyleSheet.create({
item: {},
header: {
alignItems: "flex-start",
justifyContent: "space-between",
marginBottom: 11
},
pinContainer: {
alignSelf: "flex-start",
marginTop: 2,
height: 26,
width: 26,
alignItems: "center",
justifyContent: "center"
},
text: {
flex: 1
}
});
export default withDefaultProfileImageSettings(ActivityHeader);
//In custom_code/index.js..
...
import ActivityHeader from "./components/ActivityHeader";
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.activitiesScreenApi.setActivityHeaderComponent(props => <ActivityHeader {...props} />)
}
# setActivityImageComponent(ActivityImageComponentnullable)
You can use this hook to replace an activity image. For example, you can use this to change the component's dimensions.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
ActivityImageComponent |
React.ComponentType.<ActivityImageComponentProps> |
<nullable> |
Example
import ProgressiveImage from "@src/components/ProgressiveImage";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.activitiesScreenApi.setActivityImageComponent(({
thumbnail,
source,
styles,
resizeMode
}) => {
const customStyle = {
...styles.container,
width: '100%'
}
return (
<ProgressiveImage
thumbnailSource={{
uri: thumbnail
}}
source={{
uri: source
}}
style={styles.image}
containerStyle={customStyle}
resizeMode='cover'
/>
);
});
}
# setActivityLikeComponent(ActivityLikeComponentnullable)
You can use this hook to replace the default "Like"/"Thumbs up" button to any of your preferred buttons in the Activities List screen.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
ActivityLikeComponent |
React.ComponentType.<ActivityLikeComponentProps> |
<nullable> |
Example
//In custom_code/components/ActivityLikeButton.js...
import React from "react";
import IconButton from "@src/components/IconButton";
const ActivityLikeButton = props => {
const {
pressHandler,
tintColor,
touchableStyle,
colors,
style,
renderText,
item } = props;
const likedIcon = {fontIconName: "thumbs-up", weight: 300}
const regularIcon = {fontIconName: "thumbs-up", weight: 400}
return (
<IconButton
icon={item.isFavorite ? likedIcon : regularIcon}
pressHandler={pressHandler}
tintColor={item.isFavorite ? "#A1DAD9" : tintColor}
touchableStyle={touchableStyle}
style={style}
renderText={renderText}
/>
);
};
export default ActivityLikeButton;
//In custom_code/index.js...
...
import ActivityLikeButton from './components/ActivityLikeButton';
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.activitiesScreenApi.setActivityLikeComponent(props => <ActivityLikeButton {...props} />)
}
# setActivityToViewModelFilter(activityToViewModelFilter)
A ViewModel object contains a field that the app requires when viewing an activity.
It helps UI-related data to be stored, managed, and configured in a conscious way.
You can use the filter function below to change the current activity viewModel.
For example, some of the fields you can change include content
, isMine
, can_edit
, and commentCount
.
Parameters:
Name | Type | Description |
---|---|---|
activityToViewModelFilter |
ActivityViewModelFilterCallback | Function that changes activity ViewModel |
Example
externalCodeSetup.activitiesScreenApi.setActivityToViewModelFilter((viewModel, activity, depend) => {
return {
...viewModel,
//Setting the following below as false will remove the buttons that allows a user to comment, delete, favorite and edit
can_comment: false,
can_delete: false,
can_favorite: false,
can_edit: false
}
return viewModel;
})
# setAfterActivityContentComponent(AfterActivityContentComponent)
You can use this hook to add a component after each ActivityContent component.
Parameters:
Name | Type | Description |
---|---|---|
AfterActivityContentComponent |
React.ComponentType.<AfterActivityContentComponentProps> |
Example
...
externalCodeSetup.activitiesScreenApi.setAfterActivityContentComponent(
props => (
<TouchableOpacity>
<View style={{marginVertical: 5}}>
<Text style={{fontSize: 13}}>John and 35 others liked this post</Text>
</View>
</TouchableOpacity>
)
);
# setAfterActivitySingleComponent(AfterActivitySingleComponentnullable)
You can use this hook to add a component after each ActivitySingle component.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
AfterActivitySingleComponent |
React.ComponentType.<AfterActivitySingleComponentProps> |
<nullable> |
Example
...
externalCodeSetup.activitiesScreenApi.setAfterActivitySingleComponent(props => <Text>Hello World</Text>)
# setBeforeActivitySingleComponent(BeforeActivitySingleComponentnullable)
You can use this hook to add a component before each ActivitySingle component.
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
BeforeActivitySingleComponent |
React.ComponentType.<BeforeActivitySingleComponentProps> |
<nullable> |
Example
...
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.activitiesScreenApi.setBeforeActivitySingleComponent(({
item,
index,
currentUser
}) => {
const numberPerPage = 10;
const page = Math.ceil(index / numberPerPage);
if (page < 2){
return <Text>Hi {currentUser?.name}!</Text>
}
return null;
})
}
# setFetchParamsFilter(fetchParamsFilter)
It overrides the parameters that are used to fetch activities in the Activities screen and enables you to add more parameters when fetching an activity so that you can make it as customizable as possible when calling its API.
Parameters:
Name | Type | Description |
---|---|---|
fetchParamsFilter |
TransformActivitiesParams |
Example
//In components/ActivitiesBeforeList.js...
import React, { useState } from "react";
import { TextInput, View, Button } from 'react-native'
import { useDispatch } from "react-redux";
import { activitiesRequested } from "@src/actions/activities";
import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
const hook = getExternalCodeSetup().activitiesScreenApi;
const screenName = "book";
const filter = "favorites"; //"just-me", "friends", "groups", "favorites", "mentions", "following"
const subfilters = {type: "new_member"}; // "-1", "new_member", "new_avatar", "updated_profile", "activity_update", "activity_comment", "friendship_accepted", "friendship_created", "created_group", "joined_group", "group_details_updated", "bbp_topic_create", "bbp_reply_create"
const refresh = true; //Set to true to refresh list
const searchTerm = "Tony"
const ActivitiesBeforeList = (props) => {
const { navigation, route, colors } = props;
const dispatch = useDispatch();
//If showing the matched screen, show custom filter before displaying list component
if (route?.params?.item?.object === screenName) {
const [act, setAct] = useState('')
const handleSubmit = () => {
//Set custom parameters before fetching
hook.setFetchParamsFilter((props) => {
//You can add more parameters such as "subject", "keyword" etc...
return {
...props,
display_comments: false,
someActivities: act,
}
})
//Dispatch redux action to call api using customized filters
dispatch(activitiesRequested(filter, subfilters, refresh, searchTerm));
}
return <View style={{ backgroundColor: colors.whiteColor}}>
<TextInput
style={{paddingHorizontal: 20, marginTop: 10, fontSize: 20}}
autoFocus
value={act}
onChangeText={act => setAct(act)}
placeholder="Search for an Activity"
/>
<Button
onPress={() => handleSubmit()}
title="Filter"
/>
</View>
}
return null;
}
export default withGlobalStyles(ActivitiesBeforeList);
//In components/MyCustomScreen.js...
import React from 'react';
import ActivitiesScreen from "@src/containers/Custom/ActivitiesScreen";
const MyCustomScreen = props => (<ActivitiesScreen {...props} showSearch={false} hideFilters={true} headerHeight={250} />)
export default MyCustomScreen;
//In custom_code/index.js...
...
import ActivitiesBeforeList from "./components/ActivitiesBeforeList";
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.filterScreenApiHooks.setAfterFilterComponent(ActivitiesBeforeList);
externalCodeSetup.navigationApi.addNavigationRoute(
"book",
"BookScreen",
MyCustomScreen,
"All"
);
externalCodeSetup.navigationApi.addNavigationRoute(
"book",
"BookScreen",
MyCustomScreen,
"Main"
);
}
# setHeaderActionComponent(HeaderActionComponent)
You can use this hook to customize the "create post" button located at the upper right section of the activities screen.
Parameters:
Name | Type | Description |
---|---|---|
HeaderActionComponent |
React.ComponentType.<HeaderActionComponentProps> |
Example
...
import IconButton from "@src/components/IconButton";
import AuthWrapper from "@src/components/AuthWrapper";
export const applyCustomCode = (externalCodeSetup) => {
externalCodeSetup.activitiesScreenApi.setHeaderActionComponent(
({canCreateActivity, onPress, colors}) => {
return canCreateActivity ? (
<AuthWrapper>
<IconButton
icon={{fontIconName: "pencil", weight: 200}} //pencil, round-filled
pressHandler={onPress}
tintColor={colors.headerIconColor}
style={{
height: 28
}}
/>
</AuthWrapper>
) : null;
}
);
}