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

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. /**
  10. * Renders a single chat message.
  11. */
  12. class ChatMessage extends AbstractChatMessage<Props> {
  13. /**
  14. * Implements React's {@link Component#render()}.
  15. *
  16. * @inheritdoc
  17. * @returns {ReactElement}
  18. */
  19. render() {
  20. const { message } = this.props;
  21. const messageToDisplay = message.messageType === 'error'
  22. ? this.props.t('chat.error', {
  23. error: message.error,
  24. originalText: message.message
  25. })
  26. : message.message;
  27. // replace links and smileys
  28. // Strophe already escapes special symbols on sending,
  29. // so we escape here only tags to avoid double &amp;
  30. const escMessage = messageToDisplay.replace(/</g, '&lt;')
  31. .replace(/>/g, '&gt;')
  32. .replace(/\n/g, '<br/>');
  33. const processedMessage = [];
  34. // content is an array of text and emoji components
  35. const content = toArray(escMessage, { className: 'smiley' });
  36. content.forEach(i => {
  37. if (typeof i === 'string') {
  38. processedMessage.push(<Linkify key = { i }>{ i }</Linkify>);
  39. } else {
  40. processedMessage.push(i);
  41. }
  42. });
  43. return (
  44. <div className = 'chatmessage-wrapper'>
  45. <div className = 'chatmessage'>
  46. { this.props.showDisplayName && this._renderDisplayName() }
  47. <div className = 'usermessage'>
  48. { processedMessage }
  49. </div>
  50. </div>
  51. { this.props.showTimestamp && this._renderTimestamp() }
  52. </div>
  53. );
  54. }
  55. _getFormattedTimestamp: () => string;
  56. /**
  57. * Renders the display name of the sender.
  58. *
  59. * @returns {React$Element<*>}
  60. */
  61. _renderDisplayName() {
  62. return (
  63. <div className = 'display-name'>
  64. { this.props.message.displayName }
  65. </div>
  66. );
  67. }
  68. /**
  69. * Renders the time at which the message was sent.
  70. *
  71. * @returns {React$Element<*>}
  72. */
  73. _renderTimestamp() {
  74. return (
  75. <div className = 'timestamp'>
  76. { this._getFormattedTimestamp() }
  77. </div>
  78. );
  79. }
  80. }
  81. export default translate(ChatMessage);