Class

ProfileScreenHooksApi

ProfileScreenHooksApi()

ProfileScreen Hooks. Instance name: profileScreenHooksApi

You can use this hook to personalize the profile screen by adding components before/after profile headers, blog details, custom header backgrounds and more.

Constructor

# new ProfileScreenHooksApi()

Example
externalCodeSetup.profileScreenHooksApi.METHOD_NAME

Members

# activityFiltersSubFilter

Deprecated:
  • Yes

# 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;

 })
}