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.3KB

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