Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

ChatMessage.web.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // @flow
  2. import React, { PureComponent } from 'react';
  3. import { toArray } from 'react-emoji-render';
  4. import Linkify from 'react-linkify';
  5. import { translate } from '../../base/i18n';
  6. /**
  7. * The type of the React {@code Component} props of {@link Chat}.
  8. */
  9. type Props = {
  10. /**
  11. * The redux representation of a chat message.
  12. */
  13. message: Object,
  14. /**
  15. * Invoked to receive translated strings.
  16. */
  17. t: Function
  18. };
  19. /**
  20. * Displays as passed in chat message.
  21. *
  22. * @extends Component
  23. */
  24. class ChatMessage extends PureComponent<Props> {
  25. /**
  26. * Implements React's {@link Component#render()}.
  27. *
  28. * @inheritdoc
  29. * @returns {ReactElement}
  30. */
  31. render() {
  32. const { message } = this.props;
  33. let messageTypeClassname = '';
  34. let messageToDisplay = message.message;
  35. switch (message.messageType) {
  36. case 'local':
  37. messageTypeClassname = 'localuser';
  38. break;
  39. case 'error':
  40. messageTypeClassname = 'error';
  41. messageToDisplay = this.props.t('chat.error', {
  42. error: message.error,
  43. originalText: messageToDisplay
  44. });
  45. break;
  46. default:
  47. messageTypeClassname = 'remoteuser';
  48. }
  49. // replace links and smileys
  50. // Strophe already escapes special symbols on sending,
  51. // so we escape here only tags to avoid double &amp;
  52. const escMessage = messageToDisplay.replace(/</g, '&lt;')
  53. .replace(/>/g, '&gt;')
  54. .replace(/\n/g, '<br/>');
  55. const processedMessage = [];
  56. // content is an array of text and emoji components
  57. const content = toArray(escMessage, { className: 'smiley' });
  58. content.forEach(i => {
  59. if (typeof i === 'string') {
  60. processedMessage.push(
  61. <Linkify
  62. key = { i }
  63. properties = {{
  64. rel: 'noopener noreferrer',
  65. target: '_blank'
  66. }}>{ i }</Linkify>);
  67. } else {
  68. processedMessage.push(i);
  69. }
  70. });
  71. return (
  72. <div className = { `chatmessage ${messageTypeClassname}` }>
  73. <img
  74. className = 'chatArrow'
  75. src = 'images/chatArrow.svg' />
  76. <div className = 'display-name'>
  77. { message.displayName }
  78. </div>
  79. <div className = { 'timestamp' }>
  80. { ChatMessage.formatTimestamp(message.timestamp) }
  81. </div>
  82. <div className = 'usermessage'>
  83. { processedMessage }
  84. </div>
  85. </div>
  86. );
  87. }
  88. /**
  89. * Returns a timestamp formatted for display.
  90. *
  91. * @param {number} timestamp - The timestamp for the chat message.
  92. * @private
  93. * @returns {string}
  94. */
  95. static formatTimestamp(timestamp) {
  96. const now = new Date(timestamp);
  97. let hour = now.getHours();
  98. let minute = now.getMinutes();
  99. let second = now.getSeconds();
  100. if (hour.toString().length === 1) {
  101. hour = `0${hour}`;
  102. }
  103. if (minute.toString().length === 1) {
  104. minute = `0${minute}`;
  105. }
  106. if (second.toString().length === 1) {
  107. second = `0${second}`;
  108. }
  109. return `${hour}:${minute}:${second}`;
  110. }
  111. }
  112. export default translate(ChatMessage, { wait: false });