# 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>
)
}]
})
}
# 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
Add new buttons in the main activity post and comment activity post
...
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'
]
})
}
# 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 } 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 { 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;
//Change the display content of the activity item.
//(The following codes are examples only and can be safely removed from the component)
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 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
Allow image to occupy entire image container
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
Like button changes icon and color when pressed
//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 = require("../assets/img/like-filled.png");
const regularIcon = require("../assets/img/like-outline.png")
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
Add a text before the ActivitySingle component for x page
...
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
Create a custom filter in activities screen
//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, colors } = props;
const dispatch = useDispatch();
//If showing the matched screen, show custom filter before displaying list component
if (navigation?.state?.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} />)
MyCustomScreen.navigationOptions = { header: null };
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={require("@src/assets/img/new-circle.png")}
pressHandler={onPress}
tintColor={colors.headerIconColor}
style={{
height: 28
}}
/>
</AuthWrapper>
) : null;
}
);
}