import React from 'react' ; import { Alert , Platform , StyleProp , View , ViewStyle } from 'react-native' ; import BaseMarkdown , { ASTNode , getUniqueID , MarkdownIt , MarkdownProps , } from 'react-native-markdown-display' ; import { useNavigation } from '@react-navigation/core' ; import mentionFlowDock from 'markdown-it-flowdock' ; import { NO_USERNAME_ALERT , NO_USERNAME_SUB_ALERT } from '../constants' ; import { CustomImage } from '../core-ui/CustomImage' ; import { Text } from '../core-ui/Text' ; import { makeStyles } from '../theme' ; type Props = Omit < MarkdownProps , 'rules' | 'style' > & { content : string ; fontColor ? : string ; style ? : StyleProp < ViewStyle > ; imageUrls ? : Array < string > ; mentionColor ? : string ; listOfMention ? : Array < string > ; nonClickable ? : boolean ; } ; const ios = Platform . OS === 'ios' ; export function Markdown ( props ) { const { navigate } = useNavigation ( ) ; let styles = useStyles ( ) ; let { content , fontColor , mentionColor , style , listOfMention , nonClickable , imageUrls = [ ] , ... otherProps } = props ; content = content || '' ; let image = 0 ; styles = fontColor ? { ... styles , ... { body : { ... styles . body , color : fontColor } } } : styles ; const markdownItInstance = MarkdownIt ( { typographer : true } ) . use ( mentionFlowDock , { containerClassName : 'mention' , } ) ; const onPressMention = ( username ) => { if ( listOfMention ?. includes ( username ) ) { navigate ( 'UserInformation' , { username } ) ; } else { Alert . alert ( NO_USERNAME_ALERT , NO_USERNAME_SUB_ALERT , [ { text : t ( 'Got it' ) } , ] ) ; } } ; const renderImage = ( node ) => { let { src } = node . attributes ; const uploadRegex = /upload:\/\//g ; src = uploadRegex . test ( src ) ? imageUrls [ image ] || '' : src ; image += 1 ; return < CustomImage src = { src } key = { getUniqueID ( ) } style = { styles . image } / > ; } ; const renderMention = ( { key , content } ) => ( < Text key = { key } variant = "bold" style = { mentionColor === 'primary' ? styles . mentionByMe : styles . mention } onPress = { ( ) => { ! nonClickable && onPressMention ( content ) ; } } > { `@${ content }` } < /Text>); const renderHashtag = ( { key , content } ) => ( < Text key = { key } > { t ( '#{content}' , { content } ) } < /Text>); return ( < View style = { style } > < BaseMarkdown markdownit = { markdownItInstance } rules = { { image : renderImage , mention : renderMention , hashtag : renderHashtag , } } style = { styles } { ... otherProps } > { content } < /BaseMarkdown> < /View>); } const useStyles = makeStyles ( ( { colors , fontSizes , headingFontSizes , spacing } ) => ( { body : { fontSize : fontSizes . m , margin : 0 , padding : 0 , color : colors . textNormal , } , heading1 : { fontSize : headingFontSizes . h1 , paddingVertical : spacing . m } , heading2 : { fontSize : headingFontSizes . h2 , paddingVertical : spacing . m } , heading3 : { fontSize : headingFontSizes . h3 , paddingVertical : spacing . m } , heading4 : { fontSize : headingFontSizes . h4 , paddingVertical : spacing . m } , heading5 : { fontSize : headingFontSizes . h5 , paddingVertical : spacing . m } , heading6 : { fontSize : headingFontSizes . h6 , paddingVertical : spacing . m } , hr : { backgroundColor : colors . border , marginVertical : spacing . m } , table : { borderColor : colors . border } , tr : { borderColor : colors . border } , paragraph : { marginTop : 0 , marginBottom : spacing . m } , image : { paddingVertical : spacing . l } , bullet_list_icon : { flex : 1 , fontSize : ios ? 52 : 28 , lineHeight : ios ? 36 : 24 , textAlign : 'right' , marginLeft : 0 , } , ordered_list_icon : { flex : 1 , fontSize : fontSizes . m , lineHeight : ios ? 0 : 16 , textAlign : 'right' , marginLeft : 0 , } , bullet_list_content : { flex : 8 } , ordered_list_content : { flex : 8 } , blockquote : { color : colors . textNormal , backgroundColor : colors . border , paddingHorizontal : spacing . l , paddingTop : spacing . l , marginBottom : spacing . l , } , code_inline : { color : colors . textNormal , backgroundColor : colors . border , } , code_block : { color : colors . textNormal , borderColor : colors . grey , backgroundColor : colors . border , padding : spacing . xl , marginBottom : spacing . m , borderRadius : 4 , } , fence : { color : colors . textNormal , borderColor : colors . grey , backgroundColor : colors . border , padding : spacing . xl , marginBottom : spacing . m , borderRadius : 8 , } , mentionByMe : { color : colors . pureWhite , } , mention : { color : colors . primary , } , } ) ) ;