Source

externalCode/messagesScreen.js

/**
 * @typedef {Object} MessageSingleComponentProps
 * @property {Object} item Message data
 * @property {Number} index
 * @property {MemberViewModel} user
 * @property {Function} toThread Helper function to redirect user to the message thread screen
 * @property {TranslationFunction} t
 * @property {Object} global App global style
 * @property {Object} colors App colors
 */

/**
 * @typedef {Function} TransformMessagesParams
 * @param {FetchMessagesParams}
 * @return {Object}
 */

/**
 * @typedef {Object} FetchMessagesParams
 * @see {@link https://www.buddyboss.com/resources/api/#api-Messages-GetBBThreads}
 * @property {Number} per_page Maximum number of items to be returned in result set.
 * @property {Number} page Current page of the collection.
 */

/**
 * @class
 * Messages Screen Hooks.
 * Instance name: messagesScreenApi
  
   You can use this hook to customize the message list screen parts such as the date, avatar, message preview and more.
 * @example
 * externalCodeSetup.messagesScreenApi.METHOD_NAME
 */
export class MessagesScreenApi {
	MessageSingleComponent = null;
	/**
	 * You can use this hook to modify the message item row and its components such as the date, avatar and message preview.
	 * @method
	 * @param {?React.ComponentType<MessageSingleComponentProps>} MessageSingleComponent
	 * @example <caption> Hide avatars and message preview </caption>
	 *
	 * //In custom_code/components/MessageSingle.js...
	 * import React from "react";
	 * import {View, StyleSheet, Text} from "react-native";
	 * import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
	 * import {withSettings} from "@src/components/hocs/withSettings";
	 * import {formatDate} from "@src/utils";
	 * import {GUTTER} from "@src/styles/global";
	 * import {RichHtmlText} from "@src/utils/htmlRender";
	 * import {AvatarIcon, MessagesAvatars} from "@src/components/Messages/MessageSingle"; //Get avatar components from BuddyBoss app code. You can also create your own component to use
	 *
	 * const dotSize = 10;
	 * const dotGap = 8;
	 *
	 * const MessageSingle = props => {
	 *    const {item, index, global, colors, t, toThread} = props;
	 *
	 *    return (
	 *      <AppTouchableOpacity
	 *        onPress={toThread(item)}
	 *        style={[styles.item, index === 0 ? {paddingTop: 0} : {}]}
	 *      >
	 *        <View style={[global.row, styles.itemInner]}>
	 *          <View
	 *            style={[
	 *              global.row,
	 *              {
	 *                justifyContent: "space-between",
	 *                flex: 1,
	 *                paddingLeft: item.unread ? GUTTER - dotSize : GUTTER + dotGap
	 *              }
	 *            ]}
	 *          >
	 *          {item.unread && (
	 *            <View style={[styles.dot, {backgroundColor: colors.linkColor}]} />
	 *          )}
	 *            // <MessagesAvatars
	 *            //    item={item}
	 *            //    global={global}
	 *            //    circleColor={colors.bodyFrontBg}
	 *            // />
	 *            <View style={[styles.text, global.bottomBorder]}>
	 *              <View
	 *                style={[
	 *                  global.row,
	 *                  {
	 *                    marginBottom: 3,
	 *                    justifyContent: "space-between",
	 *                    alignItems: "flex-start"
	 *                  }
	 *                ]}
	 *              >
	 *              <View style={{flex: 1}}>
	 *                <RichHtmlText
	 *                  colors={colors}
	 *                  numberOfLines={1}
	 *                  richText={item.title}
	 *                  style={global.itemAuthorName}
	 *                />
	 *              </View>
	 *              <Text style={[global.itemLightMeta]}>{item.date}</Text>
	 *            </View>
	 *            // <View style={[global.row]}>
	 *            //  <Text
	 *            //    style={[
	 *            //      global.messageExcerpt,
	 *            //      {flex: 1},
	 *            //      item.unread ? {color: colors.textColor} : {}
	 *            //    ]}
	 *            //  >
	 *            //  <Text>{`${item.lastSenderName}`}</Text>
	 *            //    {item.excerpt}
	 *            //  </Text>
	 *            // </View>
	 *          </View>
	 *        </View>
	 *      </View>
	 *    </AppTouchableOpacity>
	 *  );
	 * };
	 *
	 * const styles = StyleSheet.create({
	 *  item: {
	 *    flex: 1,
	 *    paddingRight: GUTTER
	 *  },
	 *  itemInner: {
	 *    flex: 1,
	 *    justifyContent: "space-between"
	 *  },
	 *  text: {
	 *    paddingTop: 15,
	 *    paddingBottom: 15,
	 *    marginLeft: 12,
	 *    flex: 1
	 *  },
	 *  dot: {
	 *    marginRight: dotGap,
	 *    borderRadius: 5,
	 *    width: dotSize,
	 *    height: dotSize
	 *  }
	 * });
	 * export default withSettings(MessageSingle);
	 *
	 * //In custom_code/index.js...
	 *
	 * ...
	 *
	 * import MessageSingle from "./components/MessageSingle";
	 * export const applyCustomCode = externalCodeSetup => {
	 *  externalCodeSetup.messagesScreenApi.setMessageSingleComponent((props) => <MessageSingle {...props} />)
	 * }
	 *
	 */
	setMessageSingleComponent = MessageSingleComponent => {
		this.MessageSingleComponent = MessageSingleComponent;
	};

	fetchParamsFilter = params => params;

	/**
	 * It overrides the parameters that are used to fetch messages in the Messages screen so that you can make it as customizable as possible when calling its API.
	 * @method
	 * @param {TransformMessagesParams} fetchParamsFilter
	 *
	 *  @example <caption> Create a custom filter in messages screen </caption>
	 *
	 * //In custom_code/MessagesFiltersCustom.js ...
	 * import React, { useState } from "react";
	 * import { TextInput, View, Button, Text, Switch } from 'react-native'
	 * import { useDispatch } from "react-redux";
	 * import { messagesRequested } from "@src/actions/messages";
	 * import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
	 * import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
	 *
	 * const hook = getExternalCodeSetup().messagesScreenApi;
	 * const screenName = "messages";
	 *
	 * getExternalCodeSetup().indexScreenApiHooks.setHeaderHeight((defaultHeaderHeight, filterType, navigation) => {
	 *     return 250
	 * });
	 *
	 * const filter = "all";
	 * const subfilters = ""
	 *
	 * const refresh = true; //Set to true to refresh list
	 * const searchTerm = ""
	 *
	 *
	 * const MessagesFiltersCustom = (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,
	 *                    type: isEnabled ? "all" : "unread"
	 *                }
	 *            })
	 *
	 *            //Dispatch redux action to call api using customized filters
	 *            dispatch(messagesRequested(filter, subfilters, refresh, searchTerm));
	 *
	 *        }
	 *
	 *        return <View style={{ backgroundColor: colors.whiteColor, flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
	 *
	 *            <Text>Show All Messages</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(MessagesFiltersCustom);
	 *
	 * //In custom_code/index.js...
	 *
	 * ...
	 *
	 * import MessagesFiltersCustom from "./components/MessagesFiltersCustom";
	 * export const applyCustomCode = externalCodeSetup => {
	 *    externalCodeSetup.filterScreenApiHooks.setAfterFilterComponent(MessagesFiltersCustom);
	 * }
	 *
	 * @example <caption> Limit results of messages </caption>
	 *
	 * externalCodeSetup.messagesScreenApi.setFetchParamsFilter(props => {
	 *   return {
	 *      ...props,
	 *      per_page: 1,
	 *      search: "hello"
	 *   }
	 * });
	 */
	setFetchParamsFilter = fetchParamsFilter => {
		this.fetchParamsFilter = fetchParamsFilter;
	};
}