/**
* @typedef {Object} Forum
*/
/**
* @typedef {Object} ForumViewModel
* @property {Number} id Forum id
* @property {String} title Forum title
* @property {String} shortContent Html for displaying forum's description
* @property {Boolean} can_report Returns true if forum can be reported
* @property {Boolean} reported Returns true if forum is already reported
* @property {Object} author Details of forum author
* @property {String} date Date of when forum was created
* @property {String} modified Date of when forum was last modified
* @property {String} lastActive Date of when last activity in forum
* @property {Object} actionStates contains `subscribed` field which returns `true` if user is subscribed to forum
* @property {String} replyCount Number of replies
* @property {String} topicCount Number of discussions
* @property {Object} group Group associated with the forum
* @property {String} content Html for displaying forum's description
* @property {String} coverImage Link to forum's cover image
* @property {String} coverImageThumbnail Link to forum's thumbnail cover image
* @property {Boolean} canCreateTopic Returns true if user can create a topic in the forum
* @property {Boolean} canSeeTopics Returns true if user can create a topic in the forum
* @property {Boolean} canSeeSubForums Returns true if user can see sub forums in the forum
* @property {Array} subForums Sub forums associated to forum
* @property {Function} subscribe Function to subscribe to forum
* @property {Function} toSingle Function navigate to forum item
* @property {Function} navigateToProfile Function to navigate to a user's profile
*/
/**
* @typedef {Object} ForumHeaderProps
* @property { Boolean } hideShortContent Returns true if forum short content is hidden
* @property { Object } colors App colors
* @property { Object } global App global style
* @property { ForumViewModel } forum
* @property {Function} formatDateFunc Helper function which can be used to format dates
* @property {Number} HEADER_HEIGHT Default height of header used for ForumHeader component
* @property {Boolean} disableActionButtons Returns true if actions buttons are disabled
* @property {Array<Object>} actionButtons Default action buttons such as creating a discussion or toggling subscription to a forum
* @property {TranslationFunction} t
* @property {Function} navigateToGroup Function to navigate to associated group
*/
/**
* @typedef {Function} TransformForumActionButtonsCallback
* @property {Array.<Object>} action Contains objects for default action buttons
*/
/**
* @typedef {Object} BeforeForumDetailsComponentProps
* @property {ForumViewModel} forum
*/
/**
* @typedef {Object} ForumDetailsComponentProps
* @property {String} contentStyle Suggested content style
* @property {Boolean} hideShortContent Returns true if a hook was used to indicate that short content should be hidden
* @property {Object} global App global style
* @property {ForumViewModel} forum
* @property {String} forumShortContent Formatted forum short content
* @property {React.ComponentType} ForumBottomSheetWrapper Reusable component derived from src/components/ActionButtons/ActionSheetButtonWrapper
*/
/**
* @typedef {Object} AfterForumDetailsComponentProps
* @property {ForumViewModel} forum
*/
/**
* @typedef {Object} AfterForumProfileHeaderProps
* @property {ForumViewModel} forum
*/
/**
* @typedef {Object} HeaderRightComponentProps
* @property {TranslationFunction} t
* @property {ForumViewModel} forum
* @property {Object} colors App colors
* @property {Object} global App global style
* @property {String} headerColor Header color used in app
* @property {Array<Object>} actionButtons Contains objects for forum actions such as Create Discussion and Subscribe
*/
/**
* @typedef {Object} AssociatedGroupComponentProps
* @property {TranslationFunction} t
* @property {Object} colors App colors
* @property {Object} global App global style
* @property {NavigationService} navigate
* @property {String} uri Contains link to group's image
* @property {String} name Group name
* @property {String} subtitle Outputs the value of `forums:associatedGroup` translation
*
*/
/**
* @class
* Forum Single Screen Hooks.
* Instance name: forumSingleHooksApi
You can use this hook to customize the different aspects of the forum such as adding components after forum details, hiding short content on the forum and so on.
* @example
* externalCodeSetup.forumSingleHooksApi.METHOD_NAME
*/
export class ForumSingleHooksApi {
ForumHeaderRenderer = null;
/**
* Adds a component below a forum's cover image and replaces components for displaying associated groups and components generated by hooks such as `forumSingleHooksApi.BeforeDetailsComponent`.
* @method
* @param {?React.ComponentType<ForumHeaderProps>} ForumHeaderRenderer
* @example <caption>Header component with more information display</caption>
* ...
*
* import HTML from "react-native-render-html";
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.forumSingleHooksApi.setForumHeaderRenderer((props) => {
* const { forum, formatDateFunc } = props
* return <View style={{ padding: 10 }}>
*
* <Text> {forum.title} </Text>
* <HTML html={forum.content} />
* <Text> Created {formatDateFunc(forum.date)} </Text>
* <Text> Last modified {formatDateFunc(forum.modified)} </Text>
* </View>
* })
* }
*
*/
setForumHeaderRenderer = ForumHeaderRenderer => {
this.ForumHeaderRenderer = ForumHeaderRenderer;
};
forumSingleHideShortContent = false;
/**
* Hides forum short content text located below the forum title and is overlaid on top of forum cover image
* @method
* @example
* externalCodeSetup.forumSingleHooksApi.hideForumSingleShortContent();
*/
hideForumSingleShortContent = () => {
this.forumSingleHideShortContent = true;
};
forumSingleHeaderHeight = null;
/**
* You can use it to set the height of the forum header.
* Please keep in mind that the cover image, title and short content might be affected depending on height set.
* @method
* @param {Number} height
* @example
* externalCodeSetup.forumSingleHooksApi.setForumSingleHeaderHeight(100);
*/
setForumSingleHeaderHeight = height => {
this.forumSingleHeaderHeight = height;
};
customHeaderBackground = null;
/**
* It is used to replace the forum's cover image with your preferred image for the header background.
* @method
* @param {String} customHeaderBackground
* @example
* externalCodeSetup.forumSingleHooksApi.setCustomHeaderBackground('https://link-to-image.png')
*/
setCustomHeaderBackground = customHeaderBackground => {
this.customHeaderBackground = customHeaderBackground;
};
filteredForumActionButtons = actions => actions;
/**
* Append or prepend action buttons inside the forum action sheet.
* By default, only Create Discussion and Subscribe buttons are inside. Use this function to add more buttons.
* @method
* @param {TransformForumActionButtonsCallback} filteredForumActionButtons
* @example
*
* externalCodeSetup.forumSingleHooksApi.setFilteredForumActionButtons((action) => {
*
* const share = () => {
* //Create share function
* }
*
* const btnA = {
* label: 'Share link',
* doFunction: () => () => share(),
* icon: {fontIconName: "hand-pointer", weight: "400"}
* }
*
* return [...action, btnA];
*
* })
*/
setFilteredForumActionButtons = filteredForumActionButtons => {
this.filteredForumActionButtons = filteredForumActionButtons;
};
BeforeDetailsComponent = null;
/**
* It used to add a component before the forum details.
* For example you can add a component before the forum short content description, title and other details.
* @method
* @param {React.ComponentType<BeforeForumDetailsComponentProps>} BeforeDetailsComponent
* @example <caption>Add a component before forum title, short content and other details</caption>
*
* externalCodeSetup.forumSingleHooksApi.setBeforeDetailsComponent((props) => {
* const { forum } = props;
* return <View style={{ padding: 10 }}>
* <Text style={{color: "#fff"}}> Forum created by: {forum.author.name} </Text>
* </View>
* })
*/
setBeforeDetailsComponent = BeforeDetailsComponent => {
this.BeforeDetailsComponent = BeforeDetailsComponent;
};
ForumDetailsComponent = null;
/**
* Replaces the forum details component
* @method
* @param {React.ComponentType<ForumDetailsComponentProps>} ForumDetailsComponent
* @example <caption>Instead of short content, include the forum author</caption>
* ...
*
* const {width: DEVICE_WIDTH, height: DEVICE_HEIGHT} = Dimensions.get("window");
* export const applyCustomCode = externalCodeSetup => {
*
* const ForumDetailsComponent = ({ contentStyle, hideShortContent, global, forum, forumShortContent, ForumBottomSheetWrapper, textStyle }) => {
* return (
* <View style={[styles.coverImage]}>
* <Text
* numberOfLines={2}
* ellipsizeMode="tail"
* style={[
* global.textHeaderTitle,
* {
* textAlign: "center",
* marginTop: 0
* },
* textStyle
* ]}
* >
* {forum.title}
* </Text>
*
* <ForumBottomSheetWrapper>
* <Text
* ellipsizeMode="tail"
* numberOfLines={DEVICE_HEIGHT < 700 ? 1 : 2}
* style={[
* global.textSmall,
* {
* textAlign: "center",
* marginTop: 12
* },
* textStyle
* ]}
* >
* This forum is moderated by {forum.author.name}
* </Text>
* </ForumBottomSheetWrapper>
*
* </View>
* )
* }
*
* externalCodeSetup.forumSingleHooksApi.setForumDetailsComponent((props) => <ForumDetailsComponent {...props} />)
* };
*
* const styles = StyleSheet.create({
* coverImage: {
* paddingBottom: 14,
* paddingHorizontal: GUTTER * 2,
* flex: 1,
* width: "100%",
* justifyContent: "flex-end",
* marginBottom: 20
* }
* });
*
*/
setForumDetailsComponent = ForumDetailsComponent => {
this.ForumDetailsComponent = ForumDetailsComponent;
};
AfterDetailsComponent = null;
/**
* It is used to add a component after the forum details.
* For example you can add a component after the forum title, short content description and more to display further details of the forum.
* @method
* @param {React.ComponentType<AfterForumDetailsComponentProps>} AfterDetailsComponent
* @example <caption>Add a component after forum title, short content and other details</caption>
* externalCodeSetup.forumSingleHooksApi.setAfterDetailsComponent((props) => {
* const { forum } = props;
* return <View style={{ padding: 10 }}>
* <Text style={{color: "#fff"}}> Forum created by: {forum.author.name} </Text>
* </View>
* })
*/
setAfterDetailsComponent = AfterDetailsComponent => {
this.AfterDetailsComponent = AfterDetailsComponent;
};
AfterProfileHeader = null;
/**
* It used to add a component after the header.
* @method
* @param {React.ComponentType<AfterForumProfileHeaderProps>} AfterProfileHeader
* @example <caption>Add a touchable component after the forum header consisting of cover image and associated group components</caption>
* ...
*
* import FastImage from "react-native-fast-image";
* export const applyCustomCode = externalCodeSetup => {
* const AfterForumProfileHeader = ({ forum }) => {
* const goToAuthorProfile = () => {
* //Redirect to author profile
* }
* return (
* <TouchableOpacity onPress={ goToAuthorProfile }>
* <FastImage style={{ width: "auto", height: 100 }} source={{ uri: "https://link-to-image.png" }} />
* </TouchableOpacity>
* )
* }
*
* externalCodeSetup.forumSingleHooksApi.setAfterProfileHeader(AfterForumProfileHeader)
* }
*/
setAfterProfileHeader = AfterProfileHeader => {
this.AfterProfileHeader = AfterProfileHeader;
};
HeaderRightComponent = null;
/**
* Replaces the headerRightComponent in forumSingleScreen.
* By default, headerRightComponent contains actions such as "Create Discussion" and "Subscribe"
* @method
* @param {React.ComponentType<HeaderRightComponentProps>} HeaderRightComponent
* @example <caption>Users would like to use Create Discussion and Subscribe buttons outside of an action sheet.</caption>
* //(In custom_code/components/ForumHeaderButtons.js)
*
* import React from 'react';
* import { Button } from 'react-native';
* import {useDispatch} from "react-redux";
*
* export const ForumHeaderButtons = ({actionButtons, forum, t}) => {
*
* //Use redux's dispatch to call actionButtons' functions.
* //actionButtons[0] = create discussion, actionButtons[1] = subscribe/unsubscribe
*
* const dispatch = useDispatch();
* return <>
* <Button onPress={() => dispatch(actionButtons[0].doFunction(forum))} title={t(actionButtons[0].label)} />
* <Button onPress={() => dispatch(actionButtons[1].doFunction(forum))} title={t(actionButtons[1].label)} />
* </>
* }
* export default ForumHeaderButtons;
*
* //(In custom_code/index.js)
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.forumSingleHooksApi.setHeaderRightComponent(({ t, forum, colors, global, headerColor, actionButtons, ...rest }) => {
* //Pass the necessary props to the custom component
* return <ForumHeaderButtons forum={forum} actionButtons={actionButtons} t={t}/>
* })
* }
*
*/
setHeaderRightComponent = HeaderRightComponent => {
this.HeaderRightComponent = HeaderRightComponent;
};
AssociatedGroupComponent = null;
/**
* Replaces the Associated Group section in forumSingleScreen.
* For example, you can use this to remove the image and label "Associated Group" in the Associated Group component.
* @method
* @param {React.ComponentType<AssociatedGroupComponentProps>} AssociatedGroupComponent
* @example <caption>User would like to remove the image and label "Associated Group" in the Associated Group component</caption>
* ...
*
* import { FontWeights } from "@src/styles/global";
* import Icon from "@src/components/Icon";
* export const applyCustomCode = externalCodeSetup => {
*
* externalCodeSetup.forumSingleHooksApi.setAssociatedGroupComponent(({ t,
* colors,
* global,
* navigate,
* uri,
* name,
* subtitle }) => {
*
* return <View
* style={{
* ...global.bottomBorder,
* borderTopWidth: StyleSheet.hairlineWidth,
* borderTopColor: colors.borderColor,
* paddingHorizontal: 20,
* paddingVertical: 12,
* backgroundColor: colors.bodyBg
* }}>
* <TouchableWithoutFeedback onPress={navigate}>
*
* <View style={global.row}>
* <View style={{ marginLeft: 10, flex: 1 }}>
* <Text
* style={[
* global.textAlt,
* {
* fontSize: 15,
* fontWeight: FontWeights.medium,
* maxWidth: "95%"
* }
* ]}
* numberOfLines={1}
* ellipsizeMode={"tail"}
* >
* {name}
* </Text>
* </View>
* <Icon
* icon={{fontIconName: "u-turn-left", weight: 400}}
* webIcon={"IconArrowBack"}
* tintColor={colors.textIconColor}
* styles={{
* width: 20,
* height: 20
* }}
* />
* </View>
* </TouchableWithoutFeedback>
* </View>
* })
*
* };
*
*
* @example <caption>User would like to remove the Associated Group Component</caption>
* externalCodeSetup.forumSingleHooksApi.setAssociatedGroupComponent(() => {
* return null
* })
*/
setAssociatedGroupComponent = AssociatedGroupComponent => {
this.AssociatedGroupComponent = AssociatedGroupComponent;
};
}
Source