import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import PropTypes from 'prop-types'; import moment from 'moment'; import Touchable from 'react-native-platform-touchable'; import isEqual from 'deep-equal'; import Markdown from '../markdown'; import openLink from '../../utils/openLink'; import sharedStyles from '../../views/Styles'; import { COLOR_BACKGROUND_CONTAINER, COLOR_BORDER } from '../../constants/colors'; import { withSplit } from '../../split'; const styles = StyleSheet.create({ button: { flex: 1, flexDirection: 'row', alignItems: 'center', marginTop: 6, alignSelf: 'flex-start', backgroundColor: COLOR_BACKGROUND_CONTAINER, borderColor: COLOR_BORDER, borderWidth: 1, borderRadius: 4 }, attachmentContainer: { flex: 1, borderRadius: 4, flexDirection: 'column', padding: 15 }, authorContainer: { flex: 1, flexDirection: 'row', alignItems: 'center' }, author: { flex: 1, fontSize: 16, ...sharedStyles.textColorNormal, ...sharedStyles.textMedium }, time: { fontSize: 12, marginLeft: 10, ...sharedStyles.textColorDescription, ...sharedStyles.textRegular, fontWeight: '300' }, fieldsContainer: { flex: 1, flexWrap: 'wrap', flexDirection: 'row' }, fieldContainer: { flexDirection: 'column', padding: 10 }, fieldTitle: { fontSize: 14, ...sharedStyles.textColorNormal, ...sharedStyles.textSemibold }, fieldValue: { fontSize: 14, ...sharedStyles.textColorNormal, ...sharedStyles.textRegular }, marginTop: { marginTop: 4 } }); const Title = React.memo(({ attachment, timeFormat }) => { if (!attachment.author_name) { return null; } const time = attachment.ts ? moment(attachment.ts).format(timeFormat) : null; return ( {attachment.author_name ? {attachment.author_name} : null} {time ? { time } : null} ); }, () => true); const Description = React.memo(({ attachment, baseUrl, user, getCustomEmoji, useMarkdown }) => { const text = attachment.text || attachment.title; if (!text) { return null; } return ( ); }, (prevProps, nextProps) => { if (prevProps.attachment.text !== nextProps.attachment.text) { return false; } if (prevProps.attachment.title !== nextProps.attachment.title) { return false; } return true; }); const Fields = React.memo(({ attachment }) => { if (!attachment.fields) { return null; } return ( {attachment.fields.map(field => ( {field.title} {field.value} ))} ); }, (prevProps, nextProps) => isEqual(prevProps.attachment.fields, nextProps.attachment.fields)); const Reply = React.memo(({ attachment, timeFormat, baseUrl, user, index, getCustomEmoji, useMarkdown, split }) => { if (!attachment) { return null; } const onPress = () => { let url = attachment.title_link || attachment.author_link; if (!url) { return; } if (attachment.type === 'file') { url = `${ baseUrl }${ url }?rc_uid=${ user.id }&rc_token=${ user.token }`; } openLink(url); }; return ( 0 && styles.marginTop, split && sharedStyles.tabletContent]} background={Touchable.Ripple('#fff')} > <Description attachment={attachment} timeFormat={timeFormat} baseUrl={baseUrl} user={user} getCustomEmoji={getCustomEmoji} useMarkdown={useMarkdown} /> <Fields attachment={attachment} /> </View> </Touchable> ); }, (prevProps, nextProps) => isEqual(prevProps.attachment, nextProps.attachment) && prevProps.split === nextProps.split); Reply.propTypes = { attachment: PropTypes.object, timeFormat: PropTypes.string, baseUrl: PropTypes.string, user: PropTypes.object, index: PropTypes.number, useMarkdown: PropTypes.bool, getCustomEmoji: PropTypes.func, split: PropTypes.bool }; Reply.displayName = 'MessageReply'; Title.propTypes = { attachment: PropTypes.object, timeFormat: PropTypes.string }; Title.displayName = 'MessageReplyTitle'; Description.propTypes = { attachment: PropTypes.object, baseUrl: PropTypes.string, user: PropTypes.object, useMarkdown: PropTypes.bool, getCustomEmoji: PropTypes.func }; Description.displayName = 'MessageReplyDescription'; Fields.propTypes = { attachment: PropTypes.object }; Fields.displayName = 'MessageReplyFields'; export default withSplit(Reply);