import * as React from "react";
export const API_NAME = "blogApi";
/**
* @typedef { Object } BlogSubFilterProps
* @property { Array<Object> } categories
* @property { Array<Object> } year Year values in the sub filter
*/
/**
* @typedef {Function} TransformBlogSubFiltersFilterCallback
* @property { BlogSubFilterProps }
* @return {Object}
*/
/**
* @typedef {Object} BlogItemProps
* @property {Object} global App global style
* @property {Object} colors App colors
* @property {BlogViewModel} item
* @property {Number} index
* @property {TranslationFunction} t
* @property {Number} currentUserId
* @property {Boolean} allowBookmark Returns `true` if item can be bookmarked
* @property {Function} bookmarkActions Toogles the bookmark action
* @property {Boolean} isSavedItems Returns `true` if currently viewing saved items only
*/
/**
* @typedef {Function} TransformBlogParams
* @param {FetchBlogParams}
* @return {Object}
*/
/**
* @typedef {Object} FetchBlogParams
* @see {@link https://www.buddyboss.com/resources/api/#api-Blogs-GetBBBlogs}
* @property {Number} per_page Maximum number of items to be returned in result set.
* @property {Number} page Current page of the collection.
* @property {String} search Limit results to those matching a string.
* @property {String} order
* @property {String} orderby
* @property {Number} author ID of the user whose blogs user can post to.
*/
/**
* @typedef {Object} BookmarkComponentProps
* @property {Object} global App global style
* @property {Object} styles Default styles
* @property {Function} onPress Toggles bookmark function
* @property {Object} hitSlop Default hit slop assigned to the button
* @property {Object} animatedStyle Bookmark animation
* @property {Boolean} fixAlignRight Returns `true` if fix for alignRight should be added
* @property {Boolean} bookmarked Returns `true` item is bookmarked
* @property {String} fontIconName Default icon name
* @property {String} fontIconVariant Default icon variant
* @property {String} tintColor Tint color of bookmark
* @property {Boolean} withUnderlay Returns `true` if underlay style should be used
* @property {String} underlayTheme Returns underlay theme to be used
* @property {NavigationService} navigation
*/
/**
* @class
* Blog Screen Hooks.
* Instance name: blogApi
* @example
* externalCodeSetup.blogApi.METHOD_NAME
*/
export class BlogApi {
showSearch = true;
/**
* You can use this to remove the search component from the blog and forums screen.
* For example, the search bar that is by default at the top of the blog screen would be hidden.
* @method
* @example
* externalCodeSetup.blogApi.hideSearch();
*/
hideSearch = () => {
this.showSearch = false;
};
subFilterProps = subFilterProps => subFilterProps;
/**
* Sets the available sub filter function for blogs.
* For example, you can define the items in the year sub filter.
* @method
* @param {TransformBlogSubFiltersFilterCallback} subFiltersFilter
* @example <caption>User would like to specify a year subfilter</caption>
* externalCodeSetup.blogApi.setSubFiltersFilter((filters) => {
* return {
* categories: [
* {
* value: "",
* translatedLabel: "subFilter:all_blog_categories"
* }
* ],
* year: [
* {
* value: "",
* translatedLabel: "subFilter:all_years"
* },
* {
* label: "2021",
* value: "2021"
* },
* {
* label: "2000",
* value: "2000"
* }
* ]
* }
* });
*
* @example <caption>User would like to remove the sub filters</caption>
* externalCodeSetup.blogApi.setSubFiltersFilter((filters) => {});
*/
setSubFiltersFilter = subFilterProps => {
this.subFilterProps = subFilterProps;
};
BlogItemComponent = null;
/**
* Replaces the blog item component in the blog list.
* @method
* @param {?React.ComponentType<BlogItemProps>} BlogItemComponent
* @example
* //In custom_code/components/BlogItem.js...
* import React, {useState} from "react";
* import {View, StyleSheet, Text} from "react-native";
* import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
* import {ItemTitle} from "@src/components/TextComponents";
* import {GUTTER} from "@src/styles/global";
* import IconButton from "@src/components/IconButton";
* import BookmarkButton from "@src/components/Blog/BookmarkButton";
*
* import AppImage from "@src/components/AppImage";
* import {AccessAuthWrapper} from "@src/components/AccessControl/AccessWrapper";
* import Icon from "@src/components/Icon";
* import * as Animatable from "react-native-animatable";
*
* const BlogItem = props => {
* const {
* item,
* global,
* colors,
* allowBookmark,
* bookmarkActions,
* index,
* isSavedItems,
* navigation
* } = props;
*
* const itemHeight = global.blogItemImageStyle.height + styles.item.marginTop;
* const [startItemRemoveAnimation, setStartItemRemoveAnimation] = useState(
* false
* );
*
* const animation = {
* from: {
* opacity: 1,
* height: itemHeight,
* transform: [{scaleY: 1}]
* },
* to: {
* opacity: 0,
* height: 0,
* transform: [{scaleY: 0.6}]
* }
* };
*
* return (
* <Animatable.View
* duration={500}
* onAnimationEnd={() => {
* bookmarkActions && bookmarkActions(item);
* }}
* style={[styles.container]}
* {...startItemRemoveAnimation && {animation}}
* >
* <AccessAuthWrapper item={item}>
* <AppTouchableOpacity
* onPress={item.onClick}
* style={[styles.item, index === 0 ? {paddingTop: 0} : {}]}
* >
* <View style={[global.row, styles.viewContainer]}>
* <View style={[styles.imageAccessAuthWrapper]}>
* {item.featuredImage.fontIconName ? (
* <Icon
* icon={item.featuredImage}
* styles={global.blogItemImageStyle}
* />
* ) : (
* <AppImage
* style={[global.blogItemImageStyle]}
* resizeMode="cover"
* source={item.featuredImage}
* />
* )}
* </View>
*
* <View style={[global.bottomBorder, styles.infoContainer]}>
* <ItemTitle
* global={global}
* numberOfLines={2}
* style={[global.blogItemTitle, {color: colors.headingsColor}]}
* >
* {item.title}
* </ItemTitle>
*
* <Text style={[global.blogItemAuthorText]}>{item.authorName}</Text>
*
* <View style={{flex: 1}} />
*
* <View
* style={[global.row, {alignItems: "center", paddingTop: 10}]}
* >
* <Text style={global.textMeta}>{item.date}</Text>
*
* {item.allowComments && <View style={global.dotSep} />}
*
* {item.allowComments && (
* <IconButton
* icon={{fontIconName: "comment-square-dots", weight: 400}}
* tintColor={colors.textIconColor}
* size={20}
* renderText={() => (
* <Text style={[styles.iconText, global.activityCount]}>
* {item.commentCount}
* </Text>
* )}
* />
* )}
* {allowBookmark && (
* <BookmarkButton
* global={global}
* colors={colors}
* item={item}
* navigation={navigation}
* is_bookmarked={item.bb_bookmark.is_bookmarked}
* disableBouncingAnimation={isSavedItems}
* onPress={() => {
* if (isSavedItems) setStartItemRemoveAnimation(true);
* else bookmarkActions && bookmarkActions(item);
* }}
* />
* )}
* </View>
* </View>
* </View>
* </AppTouchableOpacity>
* </AccessAuthWrapper>
* </Animatable.View>
* );
* };
*
* const styles = StyleSheet.create({
* container: {
* flex: 1
* },
* item: {
* flex: 1,
* marginTop: 16,
* paddingHorizontal: GUTTER
* },
* infoContainer: {
* marginLeft: 16,
* paddingRight: 16,
* paddingBottom: 10,
* flex: 1
* },
* viewContainer: {
* justifyContent: "space-between",
* flex: 1,
* alignItems: "flex-start"
* },
* iconText: {marginLeft: 6, alignSelf: "center"}
* });
*
* export default BlogItem;
*
* //In custom_code/index.js
*
* ...
*
* import BlogItem from "./components/BlogItem";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.blogApi.setBlogItemComponent(props => <BlogItem {...props} />)
* }
*/
setBlogItemComponent = BlogItemComponent => {
this.BlogItemComponent = BlogItemComponent;
};
fetchParamsFilter = params => params;
/**
* It overrides the parameters that are used to fetch blog posts in the Blog screen so that you can make it as customizable as possible when calling its API.
* @method
* @param {TransformBlogParams} fetchParamsFilter
*
* @example <caption> Create a custom filter in blog screen </caption>
*
* //In components/BlogFiltersCustom.js...
*
* import React, { useState } from "react";
* import { TextInput, View, Button } from 'react-native'
* import { useDispatch } from "react-redux";
* import { blogRequested } from "@src/actions/blog/blog";
* import { getExternalCodeSetup } from "@src/externalCode/externalRepo";
* import withGlobalStyles from "@src/components/hocs/withGlobalStyles";
* import DatePicker from 'react-native-datepicker'
*
* const hook = getExternalCodeSetup().blogApi;
* hook.hideSearch();
*
* const screenName = "blog";
*
* const filter = "all";
* const subfilters = ""
*
* const refresh = true; //Set to true to refresh list
* const searchTerm = ""
* const userId = 1; //Define author id
*
*
* const BlogFiltersCustom = (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 [date, setDate] = useState(new Date())
*
* const handleSubmit = () => {
*
* //Set custom parameters before fetching
* hook.setFetchParamsFilter((props) => {
*
* //You can add more parameters such as "subject", "keyword" etc...
* return {
* ...props,
* date
* }
* })
*
* //Dispatch redux action to call api using customized filters
* dispatch(blogRequested(filter, subfilters, refresh, searchTerm, userId));
*
* }
*
* return <View style={{ backgroundColor: colors.whiteColor, flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
* <DatePicker
* style={{ width: 200 }}
* date={date}
* mode="date"
* format="YYYY-MM-DD"
* confirmBtnText="Confirm"
* cancelBtnText="Cancel"
* customStyles={{
* dateIcon: {
* position: 'absolute',
* left: 0,
* top: 4,
* marginLeft: 0
* },
* dateInput: {
* marginLeft: 36
* }
* }}
* onDateChange={(date) => { setDate(date) }}
* />
* <Button
* onPress={() => handleSubmit()}
* title="Filter"
* />
* </View>
* }
*
* return null;
*
* }
*
* export default withGlobalStyles(BlogFiltersCustom);
*
* //In custom_code/index.js...
*
* ...
*
* import BlogFiltersCustom from "./components/BlogFiltersCustom";
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.filterScreenApiHooks.setAfterFilterComponent(BlogFiltersCustom);
* }
*/
setFetchParamsFilter = fetchParamsFilter => {
this.fetchParamsFilter = fetchParamsFilter;
};
BookmarkComponent = null;
/**
* You can use this hook to modify the bookmark component.
* @method
* @param {?React.ComponentType<BookmarkComponentProps>} BookmarkComponent
* @example <caption> Change background color of bookmarks </caption>
*
*
* import React from "react";
* import {View, TouchableOpacity, Animated} from "react-native";
* import IconButton from "@src/components/IconButton";
*
* export const applyCustomCode = externalCodeSetup => {
* externalCodeSetup.blogApi.setBookmarkComponent(props => {
* const {
* global,
* styles,
* onPress,
* hitSlop,
* animatedStyle,
* fixAlignRight,
* bookmarked,
* fontIconName,
* fontIconVariant,
* tintColor,
* withUnderlay,
* underlayTheme
* } = props;
* return (
* <View style={[global.column, styles.bookmarkContainer]}>
* <TouchableOpacity
* onPress={onPress}
* activeOpacity={0.5}
* hitSlop={hitSlop}
* >
* <Animated.View style={animatedStyle}>
* <IconButton
* fixAlignRight={fixAlignRight}
* //Commented out both props to make IconButton use touchableStyle props...
* // withUnderlay={withUnderlay}
* // underlayTheme={underlayTheme}
* icon={{
* fontIconName: fontIconName,
* fontIconVariant: fontIconVariant
* }}
* tintColor={tintColor}
* size={20}
* touchableStyle={{
* backgroundColor: "darkgray",
* width: 32,
* height: 32,
* borderRadius: 16,
* alignItems: "center",
* justifyContent: "center"
* }}
* />
* </Animated.View>
* </TouchableOpacity>
* </View>
* );
* });
* }
*/
setBookmarkComponent = BookmarkComponent => {
this.BookmarkComponent = BookmarkComponent;
};
}
Source