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 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // @flow
  2. import React from 'react';
  3. import { toArray } from 'react-emoji-render';
  4. import { translate } from '../../../base/i18n';
  5. import { Linkify } from '../../../base/react';
  6. import AbstractChatMessage, {
  7. type Props
  8. } from '../AbstractChatMessage';
  9. import PrivateMessageButton from '../PrivateMessageButton';
  10. /**
  11. * Renders a single chat message.
  12. */
  13. class ChatMessage extends AbstractChatMessage<Props> {
  14. /**
  15. * Implements React's {@link Component#render()}.
  16. *
  17. * @inheritdoc
  18. * @returns {ReactElement}
  19. */
  20. render() {
  21. const { message } = this.props;
  22. const messageToDisplay = message.messageType === 'error'
  23. ? this.props.t('chat.error', {
  24. error: message.error,
  25. originalText: message.message
  26. })
  27. : message.message;
  28. const processedMessage = [];
  29. // content is an array of text and emoji components
  30. const content = toArray(messageToDisplay, { className: 'smiley' });
  31. content.forEach(i => {
  32. if (typeof i === 'string') {
  33. processedMessage.push(<Linkify key = { i }>{ i }</Linkify>);
  34. } else {
  35. processedMessage.push(i);
  36. }
  37. });
  38. return (
  39. <div className = 'chatmessage-wrapper'>
  40. <div className = 'replywrapper'>
  41. <div className = 'chatmessage'>
  42. { this.props.showDisplayName && this._renderDisplayName() }
  43. <div className = 'usermessage'>
  44. { processedMessage }
  45. </div>
  46. { message.privateMessage && this._renderPrivateNotice() }
  47. </div>
  48. { message.privateMessage && message.messageType !== 'local'
  49. && <PrivateMessageButton
  50. participantID = { message.id }
  51. reply = { true }
  52. showLabel = { false } /> }
  53. </div>
  54. { this.props.showTimestamp && this._renderTimestamp() }
  55. </div>
  56. );
  57. }
  58. _getFormattedTimestamp: () => string;
  59. _getPrivateNoticeMessage: () => string;
  60. /**
  61. * Renders the display name of the sender.
  62. *
  63. * @returns {React$Element<*>}
  64. */
  65. _renderDisplayName() {
  66. return (
  67. <div className = 'display-name'>
  68. { this.props.message.displayName }
  69. </div>
  70. );
  71. }
  72. /**
  73. * Renders the message privacy notice.
  74. *
  75. * @returns {React$Element<*>}
  76. */
  77. _renderPrivateNotice() {
  78. return (
  79. <div className = 'privatemessagenotice'>
  80. { this._getPrivateNoticeMessage() }
  81. </div>
  82. );
  83. }
  84. /**
  85. * Renders the time at which the message was sent.
  86. *
  87. * @returns {React$Element<*>}
  88. */
  89. _renderTimestamp() {
  90. return (
  91. <div className = 'timestamp'>
  92. { this._getFormattedTimestamp() }
  93. </div>
  94. );
  95. }
  96. }
  97. export default translate(ChatMessage);