您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

MessageContainer.js 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // @flow
  2. import React, { PureComponent } from 'react';
  3. import ChatMessageGroup from './ChatMessageGroup';
  4. type Props = {
  5. /**
  6. * The messages array to render.
  7. */
  8. messages: Array<Object>
  9. }
  10. /**
  11. * Displays all received chat messages, grouped by sender.
  12. *
  13. * @extends PureComponent
  14. */
  15. export default class MessageContainer extends PureComponent<Props> {
  16. static defaultProps = {
  17. messages: []
  18. };
  19. /**
  20. * Reference to the HTML element at the end of the list of displayed chat
  21. * messages. Used for scrolling to the end of the chat messages.
  22. */
  23. _messagesListEndRef: Object;
  24. /**
  25. * Initializes a new {@code MessageContainer} instance.
  26. *
  27. * @param {Props} props - The React {@code Component} props to initialize
  28. * the new {@code MessageContainer} instance with.
  29. */
  30. constructor(props: Props) {
  31. super(props);
  32. this._messagesListEndRef = React.createRef();
  33. }
  34. /**
  35. * Implements React's {@link Component#componentDidMount()}.
  36. *
  37. * @inheritdoc
  38. */
  39. componentDidMount() {
  40. this._scrollMessagesToBottom();
  41. }
  42. /**
  43. * Updates chat input focus.
  44. *
  45. * @inheritdoc
  46. */
  47. componentDidUpdate() {
  48. this._scrollMessagesToBottom();
  49. }
  50. /**
  51. * Implements {@code Component#render}.
  52. *
  53. * @inheritdoc
  54. */
  55. render() {
  56. const groupedMessages = this._getMessagesGroupedBySender();
  57. const messages = groupedMessages.map((group, index) => {
  58. const messageType = group[0] && group[0].messageType;
  59. return (
  60. <ChatMessageGroup
  61. className = { messageType || 'remote' }
  62. key = { index }
  63. messages = { group } />
  64. );
  65. });
  66. return (
  67. <div id = 'chatconversation'>
  68. { messages }
  69. <div ref = { this._messagesListEndRef } />
  70. </div>
  71. );
  72. }
  73. /**
  74. * Iterates over all the messages and creates nested arrays which hold
  75. * consecutive messages sent by the same participant.
  76. *
  77. * @private
  78. * @returns {Array<Array<Object>>}
  79. */
  80. _getMessagesGroupedBySender() {
  81. const messagesCount = this.props.messages.length;
  82. const groups = [];
  83. let currentGrouping = [];
  84. let currentGroupParticipantId;
  85. for (let i = 0; i < messagesCount; i++) {
  86. const message = this.props.messages[i];
  87. if (message.id === currentGroupParticipantId) {
  88. currentGrouping.push(message);
  89. } else {
  90. groups.push(currentGrouping);
  91. currentGrouping = [ message ];
  92. currentGroupParticipantId = message.id;
  93. }
  94. }
  95. groups.push(currentGrouping);
  96. return groups;
  97. }
  98. /**
  99. * Automatically scrolls the displayed chat messages down to the latest.
  100. *
  101. * @private
  102. * @returns {void}
  103. */
  104. _scrollMessagesToBottom() {
  105. this._messagesListEndRef.current.scrollIntoView({
  106. behavior: 'smooth'
  107. });
  108. }
  109. }