/**
* @typedef {Object} Forum
*/
/**
* @typedef {Object} ForumsGetParam
* @see {@link http://www.buddyboss.com/resources/api/#api-Forums-GetBBPForums}
* @property {Number} page Page to fetch
* @property {Number} per_page Maximum number of items to be returned in result set
* @property {String} search Limit results to those matching a string.
* @property {Array<number>} include An array of forums IDs to retrieve.
* @property {Boolean} _embed
*/
/**
* @typedef {Object} FetchForumsFactoryParams
* @property {Function} provider - Redux state provider, function with no args
* @property {Number} requiredPage
* @property {"all"} filter
* @property {?String} search
* @property {Boolean} _embed
*/
/**
* @ignore
* @typedef {Function} TransformForumFiltersCallback
* @param {Array<string>} filters
* @return {Array<string>}
*/
/**
* @typedef {Function} TransformSubFiltersFilterCallback
* @param {Array<string>} filters Available filters: `activity`, `date`, `title`, `popular`
* @return {Array<string>}
*/
/**
* @typedef {Function} TransformForumParamsCallback
* @param {ForumsGetParam} ForumsGetParam
* @return {Object}
*/
/**
* @typedef {Function} TransformForumViewModelCallback
* @param {Object} viewModel
* @param {Forum} forum
* @return {Object}
*/
/**
* @typedef {Object} ForumItemProps
* @property {ForumViewModel} forum
* @property {Object} colors App colors
* @property {Object} global App global style
* @property {Function} formatDateFunc Helper function which can be used to format dates
* @property {TranslationFunction} t
* @property {Array<Object>} actionButtons Forum actions from redux
* @return {?React.ComponentType}
*/
/**
* @typedef {Boolean} ShowSearchProps Returns `true` if "Allow forum wide search" in BuddyBoss plugin is checked
* @return {Boolean}
*/
/**
* @class
* Forums Index Screen Hooks.
* Instance name: forumsHooksApi
It is used to customize the forum options such as modifying/replacing components, adding filters and details to the forum.
* @example
* externalCodeSetup.forumsHooksApi.METHOD_NAME
*/
export class ForumsHooksApi {
/**
* @deprecated
*/
defaultFilter = "all";
/**
* Change default selected filter on forums screen
* @deprecated
*/
setDefaultFilter = filter => {
this.defaultFilter = filter;
};
forumsFiltersFilter = filters => filters;
/**
* @ignore Ignoring this since only `all` filter can be used. Adding other than that crashes the app.
* Sets the filter function capable of modifying initial forum filters array
* @method
* @param {TransformForumFiltersCallback} forumsFiltersFilter
*/
setForumsFiltersFilter = forumsFiltersFilter => {
this.forumsFiltersFilter = forumsFiltersFilter;
};
subFiltersFilter = filters => filters;
/**
* The filter can be used to set the available sub filter function within the forum.
* @method
* @param {TransformSubFiltersFilterCallback} subFiltersFilter
* @example <caption>User would like to have "Alphabetical" and "Date Created" filters only</caption>
* externalCodeSetup.forumsHooksApi.setSubFiltersFilter((filters) => {
* return ["title", "date"]; //available filters include "activity", "date", "title", "popular"
* })
*/
setSubFiltersFilter = subFiltersFilter => {
this.subFiltersFilter = subFiltersFilter;
};
fetchParamsFilter = (params, args) => params;
/**
* It overrides the parameters that are used to fetch forums in the Forums screen so that you can make it as customizable as possible when calling its API.
* @method
* @param {TransformForumParamsCallback} fetchParamsFilter
*
* @example <caption> Create a custom filter in forums screen </caption>
*
* // In custom_code/components/ForumFiltersCustom.js...
*
* import React, { useState } from "react";
* import { TextInput, View, Button, Text, Switch } from 'react-native'
* import { useDispatch } from "react-redux";
* import { forumsLoadRequest } from "@src/actions/forums";
* import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
* import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
* const hook = getExternalCodeSetup().forumsHooksApi;
* const screenName = "forums";
*
* getExternalCodeSetup().indexScreenApiHooks.setHeaderHeight((defaultHeaderHeight, filterType, navigation) => {
*
* if (filterType === screenName){
* return 300
* }
*
* return defaultHeaderHeight;
*
* });
*
* const filter = "all";
* const subfilters = {
* orderby: "name", // "date", "ID", "author", "title", "name", "modified", "parent", "rand", "menu_order", "relevance", "popular", "activity"
* order: "desc"
* }
*
* const refresh = true; //Set to true to refresh list
* const searchTerm = ""
*
* const ForumFiltersCustom = (props) => {
*
* const { navigation, route, colors } = props;
*
* const dispatch = useDispatch();
*
* //If showing the matched screen, show custom filter before displaying list component
* if (route?.params?.item?.object === screenName) {
*
* const [isEnabled, setIsEnabled] = useState(false);
*
* const toggleSwitch = () => setIsEnabled(previousState => !previousState)
*
* const handleSubmit = () => {
*
* //Set custom parameters before fetching
* hook.setFetchParamsFilter((props) => {
*
* //You can add more parameters such as "subject", "keyword" etc...
* return {
* ...props,
* subscriptions : isEnabled ? true : false
* }
* })
*
* //Dispatch redux action to call api using customized filters
* dispatch(forumsLoadRequest(filter, subfilters, refresh, searchTerm));
*
* }
*
* return <View style={{ backgroundColor: colors.whiteColor, alignItems: "center", justifyContent: "center" }}>
*
* <Text>Subscribed forums only</Text>
* <Switch
* trackColor={{ false: "#767577", true: "#81b0ff" }}
* thumbColor={isEnabled ? "#f5dd4b" : "#f4f3f4"}
* ios_backgroundColor="#3e3e3e"
* onValueChange={toggleSwitch}
* value={isEnabled}
* />
* <Button
* onPress={() => handleSubmit()}
* title="Filter"
* />
* </View>
* }
*
* return null;
*
* }
*
* export default withGlobalStyles(ForumFiltersCustom);
*
* //In custom_code/index.js...
*
* import ForumFiltersCustom from "./components/ForumFiltersCustom";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.filterScreenApiHooks.setAfterFilterComponent(ForumFiltersCustom);
* }
*
*
* @example <caption>Sort by ascending order</caption>
* externalCodeSetup.forumsHooksApi.setFetchParamsFilter(props => {
* return {
* ...props,
* order: "asc",
* }
* })
*/
setFetchParamsFilter = fetchParamsFilter => {
this.fetchParamsFilter = fetchParamsFilter;
};
/**
* @ignore
* @private
* modify forums View Model
*/
forumToViewModelFilter = (viewModel, forum) => viewModel;
/**
* @ignore Ignoring this because hook is not used in the app
* Sets the filter function capable of modifying forum view model object
* @method
* @param {TransformForumViewModelCallback} forumToViewModelFilter
*/
setForumToViewModelFilter = forumToViewModelFilter =>
(this.forumToViewModelFilter = forumToViewModelFilter);
ForumItemComponent = null;
/**
* Replaces the forum item component in the forums list.
* @method
* @param {?React.ComponentType<ForumItemProps>} ForumItemComponent
* @example <caption>Add more details in each forum items</caption>
* //In custom_code/components/ForumItem.js...
*
* import React from "react";
* import { View, Text } from "react-native";
* //Load BuddyBoss components and helper functions
* import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
* import AppAvatar from "@src/components/AppAvatar";
* import ActionSheetButton from "@src/components/ActionButtons/ActionSheetButton";
* import { getForumAvatarSource, shortContent } from "@src/utils";
* import AuthWrapper from "@src/components/AuthWrapper";
* const ForumItem = ({
* forum,
* colors,
* formatDateFunc,
* global,
* actionButtons,
* t
* }) => {
* const avatarSource = getForumAvatarSource(forum);
* const verticalSpacing = 18;
* return (
* <AppTouchableOpacity
* style={[global.forumListItem, { flexDirection: "row" }]}
* onPress={forum.toSingle}
* >
* <AppAvatar
* size={50}
* source={avatarSource}
* style={{ marginVertical: verticalSpacing }}
* />
* <View
* style={{
* flex: 1,
* flexDirection: "row",
* marginLeft: 13,
* ...global.bottomBorder,
* paddingVertical: verticalSpacing
* }}
* >
* <View
* style={{
* flex: 1
* }}
* >
* <View>
* <Text style={[global.itemTitle, { marginBottom: 4, marginTop: 1 }]}>
* {forum.title}
* </Text>
* //Load short content if there forum has any
* {forum.shortContent ? (
* <Text
* style={[global.itemDesc, { marginBottom: 8 }]}
* numberOfLines={2}
* ellipsizeMode={"tail"}
* >
* {shortContent(forum.shortContent)}
* </Text>
* ) : null}
* </View>
* <View style={[global.itemFooter]}>
* <Text style={global.itemMeta}>{forum.topicCount}</Text>
* </View>
*
* //Include more forum details...
* <View>
* <Text style={global.itemMeta}>Created {formatDateFunc(forum.date)}</Text>
* {forum?.group?.id && <Text style={global.itemMeta}>Associated group: {forum.group?.name}</Text>}
* </View>
* </View>
* //Use an action sheet to display buttons such as toggle subscription to forum
* <AuthWrapper actionOnGuestLogin={"hide"}>
* <ActionSheetButton
* touchableStyle={{ alignSelf: "center", marginLeft: 10 }}
* object={forum}
* colors={colors}
* actionButtons={actionButtons}
* headerProps={{
* id: forum.id,
* onClick: forum.toSingle,
* title: forum.title,
* description: shortContent(forum.shortContent),
* avatarSource
* }}
* global={global}
* color={colors.textIconColor}
* t={t}
* />
* </AuthWrapper>
* </View>
* </AppTouchableOpacity>
* );
* };
*
* export default ForumItem;
*
* //In custom_code/index.js
*
* ...
*
* import ForumItem from "./components/ForumItem";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.forumsHooksApi.setForumItemComponent(props => <ForumItem {...props} />)
* }
*/
setForumItemComponent = ForumItemComponent => {
this.ForumItemComponent = ForumItemComponent;
};
showSearch = setting => setting;
/**
* Use this to hide or show the search component.
* This will override the setting in BuddyBoss > Settings > Forums > Forum Features > Search within the app only.
* For example, you can have your website allow forum wide search but hide the forum component in the app by using this hook.
* @param {ShowSearchProps} showSearch
* @method
* @example
* externalCodeSetup.forumsHooksApi.setShowSearch((bbSetting) => false);
*/
setShowSearch = showSearch => {
this.showSearch = showSearch;
};
}
Source