You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ChatMessage.js 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // @flow
  2. import React from 'react';
  3. import { Text, View } from 'react-native';
  4. import { getLocalizedDateFormatter, translate } from '../../../base/i18n';
  5. import { Avatar } from '../../../base/participants';
  6. import { connect } from '../../../base/redux';
  7. import AbstractChatMessage, {
  8. _mapStateToProps as _abstractMapStateToProps,
  9. type Props as AbstractProps
  10. } from '../AbstractChatMessage';
  11. import styles from './styles';
  12. /**
  13. * Size of the rendered avatar in the message.
  14. */
  15. const AVATAR_SIZE = 32;
  16. /**
  17. * Formatter string to display the message timestamp.
  18. */
  19. const TIMESTAMP_FORMAT = 'H:mm';
  20. type Props = AbstractProps & {
  21. /**
  22. * True if the chat window has a solid BG so then we have to adopt in style.
  23. */
  24. _solidBackground: boolean
  25. }
  26. /**
  27. * Renders a single chat message.
  28. */
  29. class ChatMessage extends AbstractChatMessage<Props> {
  30. /**
  31. * Implements {@code Component#render}.
  32. *
  33. * @inheritdoc
  34. */
  35. render() {
  36. const { message } = this.props;
  37. const timeStamp = getLocalizedDateFormatter(
  38. message.createdAt).format(TIMESTAMP_FORMAT);
  39. const localMessage = message.messageType === 'local';
  40. // Style arrays that need to be updated in various scenarios, such as
  41. // error messages or others.
  42. const detailsWrapperStyle = [
  43. styles.detailsWrapper
  44. ];
  45. const textWrapperStyle = [
  46. styles.textWrapper
  47. ];
  48. const timeTextStyles = [
  49. styles.timeText
  50. ];
  51. if (localMessage) {
  52. // The wrapper needs to be aligned to the right.
  53. detailsWrapperStyle.push(styles.ownMessageDetailsWrapper);
  54. // The bubble needs to be differently styled.
  55. textWrapperStyle.push(styles.ownTextWrapper);
  56. } else if (message.system) {
  57. // The bubble needs to be differently styled.
  58. textWrapperStyle.push(styles.systemTextWrapper);
  59. }
  60. if (this.props._solidBackground) {
  61. timeTextStyles.push(styles.solidBGTimeText);
  62. }
  63. return (
  64. <View style = { styles.messageWrapper } >
  65. {
  66. // Avatar is only rendered for remote messages.
  67. !localMessage && this._renderAvatar()
  68. }
  69. <View style = { detailsWrapperStyle }>
  70. <View style = { textWrapperStyle } >
  71. {
  72. // Display name is only rendered for remote
  73. // messages.
  74. !localMessage && this._renderDisplayName()
  75. }
  76. <Text style = { styles.messageText }>
  77. { message.text }
  78. </Text>
  79. </View>
  80. <Text style = { timeTextStyles }>
  81. { timeStamp }
  82. </Text>
  83. </View>
  84. </View>
  85. );
  86. }
  87. /**
  88. * Renders the avatar of the sender.
  89. *
  90. * @returns {React$Element<*>}
  91. */
  92. _renderAvatar() {
  93. const { _avatarURL } = this.props;
  94. return (
  95. <View style = { styles.avatarWrapper }>
  96. <Avatar
  97. size = { AVATAR_SIZE }
  98. uri = { _avatarURL } />
  99. </View>
  100. );
  101. }
  102. /**
  103. * Renders the display name of the sender.
  104. *
  105. * @returns {React$Element<*>}
  106. */
  107. _renderDisplayName() {
  108. const { message } = this.props;
  109. return (
  110. <Text style = { styles.displayName }>
  111. { message.user.name }
  112. </Text>
  113. );
  114. }
  115. }
  116. /**
  117. * Maps part of the Redux state to the props of this component.
  118. *
  119. * @param {Object} state - The Redux state.
  120. * @param {Props} ownProps - The own props of the component.
  121. * @returns {{
  122. * _solidBackground: boolean
  123. * }}
  124. */
  125. function _mapStateToProps(state, ownProps) {
  126. return {
  127. ..._abstractMapStateToProps(state, ownProps),
  128. _solidBackground: state['features/base/conference'].audioOnly
  129. };
  130. }
  131. export default translate(connect(_mapStateToProps)(ChatMessage));