Class

TopicSingleApi

TopicSingleApi()

Topic/Discussion Single Hooks. Instance name: topicSingleApi

You can use this to customize the default topic/discussion single screen components such as the ReplyItemAvatar, ReplyItemContent, and so on.

Constructor

# new TopicSingleApi()

Example
externalCodeSetup.topicSingleApi.METHOD_NAME

Methods

# setReplyItemAvatar(ReplyItemAvatar)

You can use this hook to customize the reply item avatar in the topic single screen. For example, you can add a "verified" icon or text beside the avatar.

Parameters:
Name Type Description
ReplyItemAvatar React.ComponentType.<ReplyItemAvatarProps>
Example

Add a "Verified" text below the avatar

...

import AppAvatar from "@src/components/AppAvatar";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";

export const applyCustomCode = externalCodeSetup => {

  externalCodeSetup.topicSingleApi.setReplyItemAvatar(props => {

    const { reply, global, isNested } = props

    return <AppTouchableOpacity
      onPress={reply.navigateToProfile ? reply.navigateToProfile : () => { }}
      style={global.avatarWrap}
    >
      <AppAvatar
        size={isNested ? 30 : 40}
        name={reply.author.fullname}
        source={{
          uri: reply.author.avatarUrl
        }}
      />
      <Text>Verified</Text>
    </AppTouchableOpacity>
  })
}

# setReplyItemContent(ReplyItemContent)

You can use this hook to customize the reply item content.

Parameters:
Name Type Description
ReplyItemContent React.ComponentType.<ReplyItemContentProps>
Example

Implement default BB component

//In custom_code/components/ReplyItemContent.js...

import React from "react";
import {View} from "react-native";
import HTML from "react-native-render-html";
import ReadMore from "@src/components/ReadMore";
import AutoSizeImage from "@src/components/AutoSizeImage";
import ImageCollection from "@src/components/ImageCollection";
import {GifVideoPlayer} from "@src/components/Gif";
import EmbeddedDocumentItem from "@src/components/Documents/EmbeddedDocumentItem";

const ReplyItemContent = ({
  formatTextForDisplay,
  filterContentCss,
  reply,
  colors,
  t,
  global,
  tagsStyles,
  imagesInitialDimensions,
  computedWidth,
  referer,
  alterChildrenHTML,
  attemptDeepLink,
  aTagRenderer,
  iframeRender
}) => (
  <View style={{flex: 1, marginTop: 6}}>
    <ReadMore
      content={formatTextForDisplay(filterContentCss(reply.content))}
      size={300}
      colors={colors}
      t={t}
      global={global}
    >
      {content => (
        <HTML
          tagsStyles={{
            ...tagsStyles,
            p: {
              ...tagsStyles.p,
              marginBottom: 0
            },
            iframe: {
              marginTop: 10
            }
          }}
          baseFontStyle={global.textHtml}
          html={content}
          imagesInitialDimensions={imagesInitialDimensions}
          staticContentMaxWidth={computedWidth}
          alterChildren={alterChildrenHTML(computedWidth)}
          onLinkPress={attemptDeepLink}
          renderers={{
            a: aTagRenderer(computedWidth),
            iframe: iframeRender(referer),
            img: (htmlAttribs, children, convertedCSSStyles, passProps) => {
              return (
                <AutoSizeImage
                  url={htmlAttribs.src}
                  wrapperStyle={{
                    marginTop: convertedCSSStyles.marginTop,
                    marginBottom: convertedCSSStyles.marginBottom
                  }}
                  style={{
                    ...convertedCSSStyles,
                    paddingVertical: 100
                  }}
                />
               );
            }
          }}
         />
      )}
    </ReadMore>
    {!!reply.media && (
      <ImageCollection
        item={reply}
        containerStyle={{marginTop: 16}}
        colors={colors}
        global={global}
        t={t}
        toUserBasedOnSettings={() => reply.navigateToProfile()}
        showActionButtons={false}
      />
    )}
    {!!reply.videos && (
      <ImageCollection
        item={reply}
        containerStyle={{marginTop: 16}}
        colors={colors}
        global={global}
        t={t}
        toUserBasedOnSettings={() => reply.navigateToProfile()}
        showActionButtons={false}
      />
    )}
    {!!reply.gif?.preview_url ? (
      <View style={{marginTop: 16}}>
        <GifVideoPlayer
          url={reply.gif?.video_url}
          poster={reply.gif?.preview_url}
          width={computedWidth - 30}
          containerStyle={{backgroundColor: "#F9F9F9"}}
        />
      </View>
    ) : null}

    {reply?.documents?.length > 0 &&
      reply.documents.map(item => {
        const viewModel: DocumentViewModel = documentToViewModel(item);

        return (
          <EmbeddedDocumentItem
            {...{
              t,
              colors,
              global,
              token,
              viewModel,
              navigation
            }}
          />
        );
      })}
    </View>
);

export default ReplyItemContent

//In custom_code/index.js...

import ReplyItemContent from "./components/ReplyItemContent"
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.topicSingleApi.setReplyItemContent(props => <ReplyItemContent {...props} />)
}

# setReplyItemHeader(ReplyItemHeader)

You can use this hook to customize the reply item header which by default contains the author of the reply and its date.

Parameters:
Name Type Description
ReplyItemHeader React.ComponentType.<ReplyItemHeaderProps>
Example

Change display date format

...
export const applyCustomCode = externalCodeSetup => {
  externalCodeSetup.topicSingleApi.setReplyItemHeader(props => {
    const { global, headerTitleStyle, reply, formatDateFunc } = props;
    return <View style={global.row}>
      <Text style={[global.itemName, headerTitleStyle, { marginBottom: 0 }]}>
        {reply.author.fullname}
      </Text>
      {!reply.author.reported && (
        <Text style={[global.itemLightMeta, { marginLeft: 8 }]}>
          //{formatDateFunc(reply.date)}
          {reply.date}
        </Text>
      )}
    </View>

  })
}

# setTopicContentComponent(TopicContentComponent)

You can use this hook to customize the content of the topic/discussion in the TopicSingleScreen.

Parameters:
Name Type Description
TopicContentComponent TopicContentComponentProps
Example
...

import HTML from "react-native-render-html";
import ReadMore from "@src/components/ReadMore";
import {
    alterChildrenHTML
} from "@src/utils";
import { aTagRenderer } from "@src/utils/htmlRender";
export const applyCustomCode = (externalCodeSetup: any) => {

    externalCodeSetup.topicSingleApi.setTopicContentComponent(({
        colors,
        content,
        global,
        t,
        tagsStyles,
        attemptDeepLink,
        computedWidth,
        topic
    }) => {

        const newContent = `<a href="https://google.com/search?q=${topic.title}"> Press this to google the topic </a>`

        return <View style={{ marginTop: -4 }}>
            <ReadMore
                colors={colors}
                content={content}
                size={400}
                t={t}
                global={global}
                style={{ marginBottom: 20 }}
            >
                {content => (
                    <HTML
                        html={content + newContent}
                        tagsStyles={{
                            ...tagsStyles,
                            iframe: {
                                marginTop: 10,
                                marginBottom: 10
                            }
                        }}
                        baseFontStyle={global.textHtml}
                        onLinkPress={attemptDeepLink}
                        staticContentMaxWidth={computedWidth}
                        alterChildren={alterChildrenHTML(computedWidth)}
                        renderers={{
                            a: aTagRenderer(computedWidth)
                        }}
                    />
                )}
            </ReadMore>
        </View>
    })
}

# setTopicItemHeader(TopicItemHeader)

You can use this to customize the author name and date in the topic single screen.

Parameters:
Name Type Description
TopicItemHeader React.ComponentType.<TopicItemHeaderProps>
Example

Add a "Verified" text beside the author's name

//In custom_code/components/TopicItemHeader.js...

import React from "react";
import {View, Text, TouchableOpacity} from "react-native";
import {getAvatar} from "@src/utils";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import AppAvatar from "@src/components/AppAvatar";

const renderVerified = (author) => {
   if(author.id === 1){
       return <Text style={{fontSize: 10}}>Verified</Text>
   }

   return null;
}

const ItemHeader = ({
 item,
 global,
 formatDateFunc,
 textColor,
 linkColor,
 light,
 alignItems,
 avatarSize,
 titleStyle,
 actionButtons
}) => {

let lightStyle = {};
if (light) lightStyle = {color: "#ffffff"};

let alignStyle = {};
if (alignItems) alignStyle = {alignItems: alignItems};
return (
   <View style={[global.itemHeader, alignStyle]}>
     <View style={[global.itemLeft, {alignItems: "center"}]}>
       <AppTouchableOpacity
         onPress={item.navigateToProfile ? item.navigateToProfile : () => {}}
         style={global.avatarWrap}
       >
     <AppAvatar
       size={avatarSize}
       name={item.author.name}
       source={{
         uri: getAvatar(item.author.avatar, 96)
       }}
     />
     </AppTouchableOpacity>
       {!!item.author.name && (
         <View style={{flex: 1}}>
           <Text
             style={[
               global.itemName,
               lightStyle,
               titleStyle
             ]}
           >
             {item.author.name} {renderVerified(item.author)}
           </Text>
           <View style={{flexDirection: "row", flexWrap: "wrap"}}>
             <Text style={[global.itemMeta, lightStyle]}>
               {formatDateFunc(item.lastActive)}
             </Text>
           </View>
         </View>
        )}
       </View>
   </View>
 );
};

export default ItemHeader;

//In custom_code/index.js...

...

import TopicItemHeader from "./components/TopicItemHeader";

export const applyCustomCode = externalCodeSetup => {
 externalCodeSetup.topicSingleApi.setTopicItemHeader( (props) => <TopicItemHeader {...props} />);
}

# setTopicMetadataComponent(TopicMetadataComponent)

You can use this hook to customize the metadeta component in the TopicSingleScreen which by default, displays the number of members and replies in the discussion.

Parameters:
Name Type Description
TopicMetadataComponent TopicMetadataComponentProps
Example
externalCodeSetup.topicSingleApi.setTopicMetadataComponent(({
  global,
  topic
 }) =>
   <View style={[global.itemFooterMeta, {marginLeft: "auto"}]}>
       <Text style={global.itemMeta}>
           {topic.voiceCount} • {topic.replyCount}
       </Text>
   </View>
 )

# setTopicReplyButton(TopicReplyButton)

You can use this hook to customize the reply button which allows the users to reply to the main content of the topic/discussion.

Parameters:
Name Type Description
TopicReplyButton TopicReplyButtonProps
Example
...

import Icon from "@src/components/Icon";
import AppTouchableOpacity from "@src/components/AppTouchableOpacity";
import AuthWrapper from "@src/components/AuthWrapper";
export const applyCustomCode = (externalCodeSetup: any) => {
    externalCodeSetup.topicSingleApi.setTopicReplyButton(({
        t,
        colors,
        global,
        topic,
        topicCloseForUser,
        openClosedDiscussionModal
    }) =>
        <AuthWrapper>
            <AppTouchableOpacity
                activeOpacity={topicCloseForUser ? 0.5 : 1}
                style={[global.itemFooter, { opacity: topicCloseForUser ? 0.5 : 1 }]}
                onPress={
                    topicCloseForUser ? openClosedDiscussionModal : topic.newReply
                }
                hitSlop={{ top: 10, right: 20, bottom: 20, left: 20 }}
            >
                <Icon
                    icon={require("@src/assets/img/reply.png")}
                    webIcon={"IconReply"}
                    tintColor={colors.descLightTextColor}
                    style={{
                        width: 14,
                        height: 12
                    }}
                />
                <Text
                    style={[global.itemMeta, { marginLeft: 6, color: colors.textColor }]}
                >
                    {t("topic:reply")}
                </Text>
            </AppTouchableOpacity>
        </AuthWrapper>
    )
}

# setTopicTitleComponent(TopicTitleComponent)

You can use this hook to customize the title of the topic/discussion in the TopicSingleScreen.

Parameters:
Name Type Description
TopicTitleComponent TopicTitleComponentProps
Example
externalCodeSetup.topicSingleApi.setTopicTitleComponent(({
  global,
  topic
}) => <Text style={[global.topicSingleTitle, { marginBottom: 20, color: "red" }]}>
    {topic.title}
  </Text>
)