/**
* @typedef {Object} Group
*/
/**
* @typedef {Object} Tab
* @property {String} icon
* @property {String} label
* @property {Number} count Indicates badge value
* @property {Boolean} loading
* @property {Function} onPress Default function of the tab
*/
/**
* @typedef {Function} TransformPrivateGroupIgnoredItemsCallback
* @param {Array<string>} list - list of items that should not show to non-members if group is private
* @return {Array<string>}
*/
/**
* @typedef {Function} TransformGroupActionButtonsCallback
* @param {Array<Object>} action Contains group's default action
* @returns {Array<Object>}
*/
/**
* @typedef {Function} TransformGroupTabListCallback
* @param {Array<Tab>} tabs Tabs in groups screen
*/
/**
* @typedef {Object} GroupHeaderAvatarProps
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
*/
/**
* @typedef {Object} BeforeGroupDetailsComponentProps
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
*/
/**
* @typedef {Object} AfterGroupDetailsComponentProps
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
*/
/**
* @typedef {Object} GroupHeaderButtonsProps
* @property {Function} OldButtonComponent Default button component displayed for the group. Ex: "Request to Join", "Member", etc.
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
* @property {Object} currentUser Details about the currently logged-in user
* @property {TranslationFunction} t
* @property {Array<Object>} filteredActions Helper functions used in group details
* @property {Function} onLinkPress Helper function to be used when a link in html is pressed
* @property {String} buttonTextColor
* @property {Object} buttonStyle
*/
/**
* @typedef {Object} GroupDetailsComponentProps
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
* @property {TranslationFunction} t
* @property {Array<Object>} filteredActions Helper functions used in group details
* @property {Function} onLinkPress Helper function to be used when a link in html is pressed
*/
/**
* @typedef {Object} AfterGroupProfileHeaderProps
* @property {Object} global App global style
* @property {Object} color App colors
* @property {GroupViewModel} group
*/
/**
* @class
* Group Single Hooks.
* Instance name: socialGroupSingleApi
You can customize the Social Group options such as replacing group avatars, adding components before/after the group details, modifying the default group action buttons and much more.
* @example
* externalCodeSetup.socialGroupSingleApi.METHOD_NAME
*/
export class SocialGroupSingleApi {
filterTabs = tabs => tabs;
/**
* You can use it to modify the tab list on the Groups screen.
* @method
* @param {TransformGroupTabListCallback} tabFilter
* @example
* externalCodeSetup.socialGroupSingleApi.setTabFilter((props) => {
*
* const customTab = {
* icon: require("@src/assets/img/about.png"),
* label: "About",
* onPress: () => Alert.alert("This group was created by the admin"),
* count: false,
* loading: false
* }
*
* return [
* ...props,
* customTab
* ];
* })
*/
setTabFilter = tabFilter => (this.filterTabs = tabFilter);
privateGroupTabIgnoreFilter = tabs => tabs;
/**
* @ignore
* Reason for ignore: privateGroupTabIgnoreFilter is not being used in the app
* Filters the list of items that should not show to non-members if group is private
* @param {TransformPrivateGroupIgnoredItemsCallback} filterFunction
*/
setPrivateGroupTabFilter = filterFunction => {
this.privateGroupTabIgnoreFilter = filterFunction;
};
GroupHeaderAvatar = null;
/**
* You can use it to replace the group header avatar. For example, you change the default group avatar if the group does not have an avatar.
* @method
* @param {React.ComponentType<GroupHeaderAvatarProps>} GroupHeaderAvatar
* @example <caption> Change default group avatar if group has not avatar </caption>
*
* ...
* import Animated from "react-native-reanimated";
* import AppImage from "@src/components/AppImage";
* import {DEVICE_WIDTH} from "@src/styles/global";
* export const applyCustomCode = externalCodeSetup => {
*
* const GroupHeaderAvatar = (props) => {
*
* const { global, colors, group } = props;
* const avatarSize = Math.min(DEVICE_WIDTH * 0.3, 110);
* let customUri = group.avatar;
*
* if (group.avatar.includes("mystery-group")) {
* customUri = 'https://link-to-image.png'
* }
*
* return <Animated.View
* style={[
* {
* marginBottom: 18,
* marginTop: "auto"
* },
* !!group.coverImage && {
* borderRadius: 18,
* backgroundColor: "#fff",
* borderWidth: 3,
* borderColor: "#fff",
* ...global.shadowBelow
* }
* ]}
* >
* <AppImage
* source={{uri: customUri}}
* style={[{ width: avatarSize, height: avatarSize, borderRadius: 18 }]}
* resizeMode={"contain"}
* />
* </Animated.View>
* }
*
* externalCodeSetup.socialGroupSingleApi.setGroupHeaderAvatar(GroupHeaderAvatar);
* }
*/
setGroupHeaderAvatar = GroupHeaderAvatar => {
this.GroupHeaderAvatar = GroupHeaderAvatar;
};
customHeaderBackground = null;
/**
* Replaces a group's cover image
* @method
* @param {String} customHeaderBackground
* @example
* externalCodeSetup.socialGroupSingleApi.setCustomHeaderBackground('https://link-to-image.png')
*/
setCustomHeaderBackground = customHeaderBackground => {
this.customHeaderBackground = customHeaderBackground;
};
BeforeDetailsComponent = null;
/**
* You can use it to add a component before the group details such as the title and group description.
* @method
* @param {React.ComponentType<BeforeGroupDetailsComponentProps>} BeforeDetailsComponent
* @example
* const BeforeDetailsComponent = (props) => {
* return !props.group.isMember && <Text>You are not a member of this group. To see all available items, please join the group.</Text>
* }
*
* externalCodeSetup.socialGroupSingleApi.setBeforeDetailsComponent(BeforeDetailsComponent)
*/
setBeforeDetailsComponent = BeforeDetailsComponent => {
this.BeforeDetailsComponent = BeforeDetailsComponent;
};
AfterDetailsComponent = null;
/**
* You can customize the Social Group options such as replacing group avatars, adding components before/after the group details, modifying the default group action buttons and much more.
* @method
* @param {React.ComponentType<AfterGroupDetailsComponentProps>} AfterDetailsComponent - jsx to render after details display
* @example
* const AfterDetailsComponent = (props) => {
* return <Button title="Open this group in a web browser" onPress={() => props.group.navigateToWeb()} />
* }
* externalCodeSetup.socialGroupSingleApi.setAfterDetailsComponent(AfterDetailsComponent)
*/
setAfterDetailsComponent = AfterDetailsComponent => {
this.AfterDetailsComponent = AfterDetailsComponent;
};
GroupDetailsComponent = null;
/**
* Replaces the group details component and lets you compose your own component to display the group details.
* @method
* @param {React.ComponentType<GroupDetailsComponentProps>} GroupDetailsComponent - jsx to render a component that replaces the group details
* @example <caption> Default component structure </caption>
*
* //In custom_code/GroupDetailsComponent.js...
*
* import React from "react";
* import {View, Text, Animated} from "react-native";
* import HTML from "react-native-render-html";
* import htmlclean from "htmlclean";
* import {
* groupMembersCountTranslation,
* groupStatusTranslation
* } from "@src/utils"; //BuddyBoss translation helper functions
* import GroupActionSheetWrapper from "@src/components/Group/GroupActionSheetWrapper";
* import {DEVICE_WIDTH, GUTTER} from "@src/styles/global";
*
* const widthWithGutter = DEVICE_WIDTH - GUTTER * 2;
*
* const GroupDetailsComponent = ({ global, colors, group, truncated, textStyle, t, filteredActions, onLinkPress }) => (
* <>
* <Text
* numberOfLines={1}
* style={[
* global.textHeaderTitle,
* {
* textAlign: "center",
* maxWidth: widthWithGutter,
* marginTop: 0,
* marginBottom: 3
* },
* textStyle
* ]}
* >
* {group.title}
* </Text>
* <Animated.View
* style={[
* global.screenMetas,
* {
* marginTop: 0,
* marginBottom: 11
* }
* ]}
* >
* <Text
* style={[
* global.textHeaderMeta,
* { maxWidth: widthWithGutter, textAlign: "center", opacity: 0.8 },
* textStyle
* ]}
* >
* {groupStatusTranslation(t, group)} •{" "}
* {groupMembersCountTranslation(t, group)}
* </Text>
* </Animated.View>
* {!!group.shortContent && (
* <Animated.View style={{ maxWidth: 300 }}>
* <GroupActionSheetWrapper
* actionButtons={filteredActions}
* {...{
* global,
* colors,
* t,
* group,
* onLinkPress
* }}
* >
* <View>
* <HTML
* html={htmlclean(truncated.html)}
* tagsStyles={{
* p: { marginTop: 0 },
* a: global.textHeaderShortContent
* }}
* baseFontStyle={{
* ...global.textHeaderShortContent,
* ...textStyle
* }}
* onLinkPress={(event, url) => {
* if (onLinkPress) {
* onLinkPress(event, url);
* }
* }}
* />
* </View>
* </GroupActionSheetWrapper>
* </Animated.View>
* )}
* </>
* );
*
* export default GroupDetailsComponent;
*
* //In custom_code/index.js...
*
* ...
*
* import GroupDetailsComponent from "./GroupDetailsComponent";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.socialGroupSingleApi.setGroupDetailsComponent(GroupDetailsComponent)
* }
*/
setGroupDetailsComponent = GroupDetailsComponent => {
this.GroupDetailsComponent = GroupDetailsComponent;
};
GroupHeaderButtons = null;
/**
* You can add new components near the default group button section.
* @method
* @param {React.ComponentType<GroupHeaderButtonsProps>} GroupHeaderButtons
* @example <caption> Add buttons that can open the group in a web browser </caption>
* const GroupHeaderButtons = (props) => {
*
* const {OldButtonComponent, group} = props;
*
* const NavigateToForum = () => <TouchableOpacity onPress={() => group.navigateToForum()}>
* <Text> Go to forum </Text>
* </TouchableOpacity>
*
* const OpenInWeb = () => <TouchableOpacity onPress={() => group.navigateToWeb()}>
* <Text> Open in browser </Text>
* </TouchableOpacity>
*
* return (
* <View style={{flexDirection: "column"}}>
* <NavigateToForum />
* <OpenInWeb />
* <OldButtonComponent />
* </View>
* )
*
* }
*
* externalCodeSetup.socialGroupSingleApi.setGroupHeaderButtons(GroupHeaderButtons);
*
* @example <caption> Default component structure </caption>
*
* //In custom_code/GroupHeaderButton.js...
*
* import React from "react";
* import GroupActionSheetWrapper from "@src/components/Group/GroupActionSheetWrapper";
* import AvatarActionButton from "@src/components/ActionButtons/AvatarActionButton";
* import AuthWrapper from "@src/components/AuthWrapper";
* import ActionButtonList from "@src/components/ActionButtons/ActionButtonList";
*
* const GroupHeaderButton = ({group, currentUser, global, colors, t, onLinkPress, filteredActions, buttonTextColor, buttonStyle}) => {
*
* return group.isMember ? (
* <GroupActionSheetWrapper
* actionButtons={filteredActions}
* {...{
* global,
* colors,
* t,
* group,
* onLinkPress
* }}
* >
* <AvatarActionButton
* user={currentUser}
* style={{
* ...buttonStyle,
* paddingLeft: 3,
* paddingRight: 13
* }}
* {...{
* global,
* colors,
* t,
* title: group.role,
* titleStyle: {
* ...global.textHeaderActionButton,
* color: colors.primaryColor
* },
* color: buttonTextColor
* }}
* />
* </GroupActionSheetWrapper>
* ) : (
* <AuthWrapper>
* <ActionButtonList
* hideIcons={true}
* actionButtons={filteredActions}
* object={group}
* color={buttonTextColor}
* t={t}
* buttonStyle={{
* ...buttonStyle,
* marginHorizontal: 5,
* paddingVertical: 0
* }}
* textStyle={global.textHeaderActionButton}
* />
* </AuthWrapper>
* );
*
* }
*
* export default GroupHeaderButton;
*
* //In custom_code/index.js...
*
* import GroupHeaderButton from "./components/GroupHeaderButton";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.socialGroupSingleApi.setGroupHeaderButtons(GroupHeaderButton)
* }
*/
setGroupHeaderButtons = GroupHeaderButtons => {
this.GroupHeaderButtons = GroupHeaderButtons;
};
AfterProfileHeader = null;
/**
* It adds a component after the group header but places it before the group items list.
* @method
* @param {React.ComponentType<AfterGroupProfileHeaderProps>} AfterProfileHeader
* @example
* const AfterProfileHeader = (props) => {
* const {group} = props;
* return group.hasForum && <View style={{margin: 10}}>
* <Button onPress={() => group.subscribeClick()} title="Subscribe/Unsubscribe to group forum" />
* </View>
* }
*
* externalCodeSetup.socialGroupSingleApi.setAfterProfileHeader(AfterProfileHeader)
*/
setAfterProfileHeader = AfterProfileHeader => {
this.AfterProfileHeader = AfterProfileHeader;
};
filteredGroupActionButtons = actions => actions;
/**
* Append or prepend action buttons.
* You can use this to modify the group's default action buttons.
* `doFunction` can be used to dispatch a redux action.
* @method
* @param {TransformGroupActionButtonsCallback} filteredGroupActionButtons
* @example
*
* externalCodeSetup.socialGroupSingleApi.setFilteredGroupActionButtons((action) => {
*
* const requestDeliveryRedux = {
* label: 'Request for food delivery',
* isNavigation: true,
* doFunction: () => ({ type: "FOOD_DELIVERY_REQUEST" }) //Call custom redux action FOOD_DELIVERY_REQUEST
* }
*
* return [...action, requestDeliveryRedux];
*
* })
*/
setFilteredGroupActionButtons = filteredGroupActionButtons => {
this.filteredGroupActionButtons = filteredGroupActionButtons;
};
}
Source