# new ProfileScreenHooksApi()
Example
externalCodeSetup.profileScreenHooksApi.METHOD_NAME
Members
# setUserFollowingComponent
You can use this to replace the user's following and/or follower details component.
Example
const UserFollowingComponent = (props) => (
<View style={{ flexDirection: "row" }}>
<Text> {props.user.followers} Followers </Text>
<Text> {props.user.following} Following </Text>
</View>
)
externalCodeSetup.profileScreenHooksApi.setUserFollowingComponent(UserFollowingComponent)
Methods
# addHandleInputFieldCallback(onHandledInput)
You can use this hook to add a callback to a function when an input field on the profile Edit screen is changed. For example, you can add a function to display a prompt whenever the word 'Bar' is typed in a specific profile field.
Parameters:
Name | Type | Description |
---|---|---|
onHandledInput |
OnChangeEventListenerCallback |
Example
If "Food" is selected when editing the value in a profile field, change the available field sets in the edit profile screen
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.profileScreenHooksApi.addHandleInputFieldCallback(props => {
const { id, newValue } = props;
if (id === 24) {
if (newValue.includes("Food")) {
//If "Food" is selected, display the first field set only
externalCodeSetup.profileScreenHooksApi.setEditProfileFieldSets(fieldSets => {
return [...fieldSets].splice(0,1);
});
} else {
//Reset field sets
externalCodeSetup.profileScreenHooksApi.setEditProfileFieldSets(fieldSets => fieldSets);
}
}
})
}
# setActionButton(ActionButton)
You can use this hook to replace the action button in the profile header component.
Parameters:
Name | Type | Description |
---|---|---|
ActionButton |
React.ComponentType.<ActionButtonProps> |
Example
...
export const applyCustomCode = externalCodeSetup => {
const RoundIconButton = ({
global,
button,
color,
style,
t,
withLabel,
labelStyle,
loading,
first,
last,
highlight
}) => (
<>
<View
style={[
{justifyContent: "center", alignItems: "center"},
highlight
? global.wrappedIconButtonHighlight
: styles.roundActionButton,
!first && !withLabel && {marginLeft: 10},
!last && !withLabel && {marginRight: 10},
style
]}
activeOpacity={1}
>
{!loading &&
button.icon && (
<Icon
tintColor={highlight ? "#fff" : color || "#000"}
icon={button.icon}
styles={{height: 26, width: 26}}
/>
)}
{loading && (
<ActivityIndicator
animating={true}
style={styles.indicator}
color={color}
size="small"
/>
)}
</View>
{withLabel && (
<View style={{height: 40, paddingTop: 10}}>
<Text
ellipsizeMode="tail"
numberOfLines={2}
style={
[global.actionIconText, {textAlign: "center"}, labelStyle]
}
>
{t(button.label)}
</Text>
</View>
)}
</>
);
const styles = StyleSheet.create({
indicator: {opacity: 0.45},
roundActionButton: {
backgroundColor: "#EDEEF2",
borderRadius: 24,
width: 48,
height: 48,
justifyContent: "center",
alignItems: "center",
marginHorizontal: 5
}
});
externalCodeSetup.profileScreenHooksApi.setActionButton((props) => <RoundIconButton {...props} />)
}
# setAfterDetailsComponent(AfterDetailsComponent)
You can use this to add a component after the profile details. For example, you can add more information about your profile in the custom component.
Parameters:
Name | Type | Description |
---|---|---|
AfterDetailsComponent |
React.ComponentType.<AfterProfileDetailsComponentProps> |
Example
const AfterDetailsComponent = ({ user }) => (
<Text>Last activity: {user.lastActivity}</Text>
)
externalCodeSetup.profileScreenHooksApi.setAfterDetailsComponent(AfterDetailsComponent)
# setAfterProfileHeader(AfterProfileHeader)
It adds a component after the profile header.
Parameters:
Name | Type | Description |
---|---|---|
AfterProfileHeader |
React.ComponentType.<AfterProfileHeaderProps> |
Example
const AfterProfileHeader = (props) => (
<View style={{ marginLeft: 20 }}>
<Text> User Points: {props.user.points} </Text>
</View>
)
externalCodeSetup.profileScreenHooksApi.setAfterProfileHeader(AfterProfileHeader)
# setBeforeDetailsComponent(BeforeDetailsComponent)
You can use it to add a component before the profile details.
Parameters:
Name | Type | Description |
---|---|---|
BeforeDetailsComponent |
React.ComponentType.<BeforeProfileDetailsComponentProps> |
Example
const BeforeDetailsComponent = ({user}) => (
<Text>User Type: {user.type}</Text>
)
externalCodeSetup.profileScreenHooksApi.setBeforeDetailsComponent(BeforeDetailsComponent)
# setCustomHeaderBackground(customHeaderBackground)
Replaces cover image for all profiles in the profile screen
Parameters:
Name | Type | Description |
---|---|---|
customHeaderBackground |
String | Resource to replace cover image |
Example
externalCodeSetup.profileScreenHooksApi.setCustomHeaderBackground('https://link-to-image.png')
# setEditProfileComponentDidUpdateCallback(onComponentDidUpdate)
You can use this hook to set a callback function in the Edit Profile screen's componentDidUpdate function. For example, you can use this to make a network request (or call an API) if a state's value is changed.
Parameters:
Name | Type | Description |
---|---|---|
onComponentDidUpdate |
EditProfileComponentDidUpdateCallback |
Example
Change edit profile field values based on WebView's message
//In custom_code/MyCustomScreen.js...
import React, { useState } from 'react';
import { View, Text, StyleSheet, Button, Modal, TouchableOpacity } from "react-native";
import isEqual from 'lodash.isequal';
import { WebView } from 'react-native-webview';
import EditScreen from "@src/containers/Custom/Profile/Xprofile/Edit";
import { backButton } from "@src/utils";
import { getExternalCodeSetup } from '../../src/externalCode/externalRepo';
const MyHTML = require('./../html/sample.html');
const MyModal = ({ modalVisible, setModalVisible, updateStoreValues }) => {
//You can change this according to the message sent by the webview's source
const matchedMessage = "Clicked!";
return <View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
setModalVisible(!modalVisible);
}}
style={{
margin: 15
}}
>
<WebView
source={MyHTML}
onMessage={event => {
const message = event.nativeEvent.data;
if (message == matchedMessage) {
updateStoreValues()
}
}}
/>
<TouchableOpacity
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableOpacity>
</Modal>
</View>
}
const MyCustomScreen = (props) => {
const matchedValue = "gmap";
const [modalVisible, setModalVisible] = useState(false);
const [callbackUpdateStoreValues, setCallbackUpdateStoreValues] = useState(null);
//Set condition when to open modal. If the field matches the value of matchedValue, then it will open the modal.
getExternalCodeSetup().profileScreenHooksApi.addHandleInputFieldCallback(props => {
const { id, newValue, groupKey } = props;
if (groupKey === 1 && id === 3) {
if (newValue === matchedValue) {
setModalVisible(true)
}
}
})
getExternalCodeSetup().profileScreenHooksApi.setEditProfileComponentDidUpdateCallback(paramProps => {
const {
prevProps,
prevState,
props,
state,
updateStoreValues } = paramProps;
//Update callbackUpdateStoreValues only when there are updates in the EditProfile component
if (!isEqual(state.updates, prevState.updates) && Object.keys(prevState.updates).length !== 0) {
const updateValues = () => {
//You can get the appropriate groupKey and id by doing a console.log for state and/or prevState.
//In this case, we're updating the store values of groupKey = 1 and id = 1 with a the webViewInput value.
const groupKey = 1,
id = 1,
property = "value",
webViewInput = "Updated from web view";
updateStoreValues(groupKey, id, property, webViewInput);
}
setCallbackUpdateStoreValues(() => () => updateValues());
}
});
return <>
<EditScreen />
<MyModal
modalVisible={modalVisible}
setModalVisible={setModalVisible}
updateStoreValues={callbackUpdateStoreValues}
/>
</>
}
MyCustomScreen.navigationOptions = ({ navigation, screenProps }) => {
const { t, colors, calcFontSize, global } = screenProps;
const { borderColor } = colors;
const { params = {} } = navigation.state;
const hideBackButton = true;
let headerLeft = params.renderHeaderLeft
? params.renderHeaderLeft()
: backButton({
navigation,
headerColor: colors.headerIconColor,
text: t("common:back"),
textStyle: global.headerText,
colors
});
if (hideBackButton) {
headerLeft = null;
}
return {
headerTitle: (
<Text
ellipsizeMode="tail"
numberOfLines={1}
style={global.appHeaderTitle}
>
{t("profile:editXprofile")}
</Text>
),
tabBarVisible: false,
headerLeft: headerLeft,
headerRight: params.renderHeaderRight ? params.renderHeaderRight() : null,
headerStyle: {
...StyleSheet.flatten(global.header),
borderBottomColor: borderColor,
borderBottomWidth: StyleSheet.hairlineWidth
}
};
};
export default MyCustomScreen;
const styles = StyleSheet.create({
centeredView: {
justifyContent: "center",
alignItems: "center",
},
button: {
position: "absolute",
bottom: 80,
width: "50%",
borderRadius: 20,
padding: 10,
elevation: 2,
alignSelf: "center"
},
buttonClose: {
backgroundColor: "#2196F3",
},
textStyle: {
color: "white",
fontWeight: "bold",
textAlign: "center"
}
});
//In custom_code/html/sample.html...
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<head>
<style>
body {
background-color: #18222d;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div>
<button type="button" onclick="clicked()">Click Me!</button>
</div>
<script>
const OS = "ios";
const sendMessageToRN = (message) => {
if (OS === "ios") {
if (window.ReactNativeWebView.postMessage.length !== 1) {
setTimeout(sendMessageToRN(message), 200);
} else {
window.ReactNativeWebView.postMessage(message);
}
} else {
window.ReactNativeWebView.postMessage(message);
setTimeout(() => window.ReactNativeWebView.postMessage(message), 50);
}
}
const clicked = () => {
sendMessageToRN("Clicked!")
}
</script>
</body>
</html>
//In custom_code/index.js...
...
import MyCustomScreen from "./components/MyCustomScreen";
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.navigationApi.replaceScreenComponent("EditXprofile", MyCustomScreen);
}
# setEditProfileFieldSets(editProfileFieldSets)
Sets the field sets and the filters available on the Edit Profile screen.
Parameters:
Name | Type | Description |
---|---|---|
editProfileFieldSets |
TransformEditProfileFieldSetsCallback |
Example
Delete a field from a field set
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.profileScreenHooksApi.setEditProfileFieldSets(fieldSets => {
const modifiedFieldSets = fieldSets.map(obj => {
if (obj.id === 1){
//Delete a field from the field set
const fields = obj.fields.slice(1);
return {
...obj,
fields: fields
}
}
return obj;
});
return modifiedFieldSets;
});
}
# setEditProfileFieldSetsFilter(editProfileFieldSetsFilter)
Sets the filters available on the Edit Profile screen as the filter tabs. For example, you can use this hook to remove a specific filter. However, this does not remove the corresponding field set of the removed filter.
Parameters:
Name | Type | Description |
---|---|---|
editProfileFieldSetsFilter |
TransformEditProfileFieldSetsFilterCallback |
Example
Change name of filter with id 1
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.profileScreenHooksApi.setEditProfileFieldSetsFilter(props => {
if (Array.isArray(props.filters)){
const modifiedFilters = props.filters.map(obj => {
if (obj.id === 1){
return {
...obj,
name: "New name"
}
}
return obj;
})
return {
...props,
filters: modifiedFilters
};
}
return props;
});
}
# setHeaderRightComponent(HeaderRightComponent)
You can use it to add a component on the top right corner of the profile screen for users.
Parameters:
Name | Type | Description |
---|---|---|
HeaderRightComponent |
React.ComponentType.<HeaderRightComponent> |
Example
//In custom_code/components/ProfileHeaderButton.js
...
import { Alert } from "react-native";
import IconButton from "@src/components/IconButton";
import { globalStyle } from "@src/styles/global";
import { useSelector } from "react-redux"; //use useSelector to get state from redux
export const ProfileHeaderButton = () => {
const globalStyles = useSelector((state) => globalStyle(state.config.styles)) // Get style from redux
const user = useSelector((state) => state.user.userObject); // Get user from redux
const { colors } = globalStyles;
return (
<IconButton
icon={require("@src/assets/img/plus-circle.png")}
pressHandler={() => Alert.alert(`Hello ${user.nicename}!`) }// Do something here such as call api requests
tintColor={colors.headerIconColor}
style={{
height: 28
}}
/>
)
}
//In custom_code/index.js
...
import { ProfileHeaderButton } from "./components/ProfileHeaderButton";
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.profileScreenHooksApi.setHeaderRightComponent(() => <ProfileHeaderButton />)
};
# setHideHandle(hideHandle)
Hides user handle in profile header by passing it as a true
value.
Parameters:
Name | Type | Description |
---|---|---|
hideHandle |
Boolean |
Example
externalCodeSetup.profileScreenHooksApi.setHideHandle(true)
# setIgnoreTabsFilter(ignoreTabsFilter)
You can use this to set a function that is capable of hiding specific profile menu items.
Parameters:
Name | Type | Description |
---|---|---|
ignoreTabsFilter |
TransformProfileIgnoredSubscreensCallback |
Example
externalCodeSetup.profileScreenHooksApi.setIgnoreTabsFilter((
list,
isOwnAccount
) => [
...list,
"activities",
"friends"
])
# setTabsList(tabsList)
You can use this hook to add or modify existing tabs in the profile screen. For example, you can add a new route in profile screen tab list
Parameters:
Name | Type | Description |
---|---|---|
tabsList |
TransformProfileSubscreensListCallback |
Example
Add a new route in profile screen tab list
...
import {NavigationActions} from "react-navigation";
export const applyCustomCode = externalCodeSetup => {
//Register a new route
externalCodeSetup.navigationApi.addNavigationRoute(
"book",
"BookScreen",
() => <Text>Custom Book Screen</Text>,
"All"
);
//Add new menu item to profile screen tab list
externalCodeSetup.profileScreenHooksApi.setTabsList((
list,
navigation,
user,
isOwnAccount
) => {
return [
...list,
{
icon: require("@src/assets/img/about.png"), //Set icon
label: "Book", //Set label of menu
onPress: () => navigation.navigate(
NavigationActions.navigate({
routeName: "book",
params: { //Pass params if needed
user,
isOwnAccount
},
key: user.id
})
)
}
]
})
}
# setUserAvatar(UserAvatar)
You can use it to replace the user avatar component.
Parameters:
Name | Type | Description |
---|---|---|
UserAvatar |
React.ComponentType.<UserAvatarProps> |
Example
...
import AvatarImageUpload from "@src/components/AvatarImageUpload"
export const applyCustomCode = externalCodeSetup => {
const UserAvatar = (props) => {
return (
<>
<Text>Tap avatar to edit</Text>
<AvatarImageUpload
isOwnAccount={props.isOwnAccount}
user={props.user}
size={100}
imagePickerProps={{ cropping: true, cropperCircleOverlay: true }}
/>
</>
)
}
externalCodeSetup.profileScreenHooksApi.setUserAvatar(UserAvatar)
# setUserFullNameComponent(UserFullNameComponent)
You can use this to replace the user full name component and customize the name display according to your app preferences.
Parameters:
Name | Type | Description |
---|---|---|
UserFullNameComponent |
React.ComponentType.<UserFullNameComponentProps> |
Example
const UserFullNameComponent = (props) => (
<View>
<Text style={{fontSize: 20, color: "red"}}>
{props.user.fullname}
</Text>
</View>
)
externalCodeSetup.profileScreenHooksApi.setUserFullNameComponent(UserFullNameComponent)
# setUserHandleComponent(UserHandleComponent)
It is used to replace the default user handle component.
Parameters:
Name | Type | Description |
---|---|---|
UserHandleComponent |
React.ComponentType.<UserHandleComponentProps> |
Example
const UserHandleComponent = (props) => (
<Text style={{color: "blue", fontSize: 30}}> @{props.user.nicename} </Text>
)
externalCodeSetup.profileScreenHooksApi.setUserHandleComponent(UserHandleComponent)
# setUserRegisteredComponent(UserRegisteredComponent)
It is used to replace user registration details component.
Parameters:
Name | Type | Description |
---|---|---|
UserRegisteredComponent |
React.ComponentType.<UserRegisteredComponentProps> |
Example
const UserRegisteredComponent = (props) => (
<View style={{ marginVertical: 5 }}>
<Text>Date registered: {props.formatDateFunc(props.user.registeredDate)}</Text>
</View>
)
externalCodeSetup.profileScreenHooksApi.setUserRegisteredComponent(UserRegisteredComponent)
# setUserTypeComponent(UserTypeComponent)
You can use this to replace the user type component for the various app users.
Parameters:
Name | Type | Description |
---|---|---|
UserTypeComponent |
React.ComponentType.<UserTypeComponentProps> |
Example
const UserTypeComponent = (props) => (
<View>
<Text>
User type: {props.user.type}
</Text>
</View>
)
externalCodeSetup.profileScreenHooksApi.setUserTypeComponent(UserTypeComponent);
# setViewProfileFieldSets(viewProfileFieldSets)
Used to set and modify the field sets in the View Profile screen. You can show/hide the field sets in the View Profile screen.
Parameters:
Name | Type | Description |
---|---|---|
viewProfileFieldSets |
TransformViewProfileFieldSetsCallback |
Example
export const applyCustomCode = externalCodeSetup => {
externalCodeSetup.profileScreenHooksApi.setViewProfileFieldSets(fieldSets => {
if (Array.isArray(fieldSets)){
const modifiedFieldSets = [...fieldSets].slice(1);
return modifiedFieldSets;
}
return fieldSets;
})
}