message-list.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. import moment from 'moment'
  4. import Message from './message'
  5. const FIVE_MINUTES = 5 * 60 * 1000
  6. function formatTimestamp(date) {
  7. if (!date) {
  8. return 'N/A'
  9. } else {
  10. return `${moment(date).format('h:mm a')} ${moment(date).calendar()}`
  11. }
  12. }
  13. function indexFromEnd(list, index) {
  14. return list.length - index - 1
  15. }
  16. function MessageList({ messages, resetUnreadMessages, userId }) {
  17. function shouldRenderDate(messageIndex) {
  18. if (messageIndex === 0) {
  19. return true
  20. } else {
  21. const message = messages[messageIndex]
  22. const previousMessage = messages[messageIndex - 1]
  23. return message.timestamp - previousMessage.timestamp > FIVE_MINUTES
  24. }
  25. }
  26. return (
  27. // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
  28. <ul
  29. className="list-unstyled"
  30. onClick={resetUnreadMessages}
  31. onKeyDown={resetUnreadMessages}
  32. >
  33. {messages.map((message, index) => (
  34. // new messages are added to the beginning of the list, so we use a reversed index
  35. <li key={indexFromEnd(messages, index)} className="message">
  36. {shouldRenderDate(index) && (
  37. <div className="date">
  38. <time
  39. dateTime={
  40. message.timestamp
  41. ? moment(message.timestamp).format()
  42. : undefined
  43. }
  44. >
  45. {formatTimestamp(message.timestamp)}
  46. </time>
  47. </div>
  48. )}
  49. <Message message={message} userId={userId} />
  50. </li>
  51. ))}
  52. </ul>
  53. )
  54. }
  55. MessageList.propTypes = {
  56. messages: PropTypes.arrayOf(PropTypes.shape({ timestamp: PropTypes.number }))
  57. .isRequired,
  58. resetUnreadMessages: PropTypes.func.isRequired,
  59. userId: PropTypes.string.isRequired
  60. }
  61. export default MessageList