chat-pane.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import React, { useEffect } from 'react'
  2. import PropTypes from 'prop-types'
  3. import MessageList from './message-list'
  4. import MessageInput from './message-input'
  5. import InfiniteScroll from './infinite-scroll'
  6. import Icon from '../../../shared/components/icon'
  7. import { useTranslation } from 'react-i18next'
  8. function ChatPane({
  9. atEnd,
  10. loading,
  11. loadMoreMessages,
  12. messages,
  13. resetUnreadMessages,
  14. sendMessage,
  15. userId
  16. }) {
  17. useEffect(() => {
  18. loadMoreMessages()
  19. }, [])
  20. const shouldDisplayPlaceholder = !loading && messages.length === 0
  21. const messageContentCount = messages.reduce(
  22. (acc, { contents }) => acc + contents.length,
  23. 0
  24. )
  25. return (
  26. <aside className="chat">
  27. <InfiniteScroll
  28. atEnd={atEnd}
  29. className="messages"
  30. fetchData={loadMoreMessages}
  31. isLoading={loading}
  32. itemCount={messageContentCount}
  33. >
  34. <div>
  35. {loading && <LoadingSpinner />}
  36. {shouldDisplayPlaceholder && <Placeholder />}
  37. <MessageList
  38. messages={messages}
  39. userId={userId}
  40. resetUnreadMessages={resetUnreadMessages}
  41. />
  42. </div>
  43. </InfiniteScroll>
  44. <MessageInput
  45. resetUnreadMessages={resetUnreadMessages}
  46. sendMessage={sendMessage}
  47. />
  48. </aside>
  49. )
  50. }
  51. function LoadingSpinner() {
  52. const { t } = useTranslation()
  53. return (
  54. <div className="loading">
  55. <Icon type="fw" modifier="refresh" spin />
  56. {` ${t('loading')}...`}
  57. </div>
  58. )
  59. }
  60. function Placeholder() {
  61. const { t } = useTranslation()
  62. return (
  63. <>
  64. <div className="no-messages text-center small">{t('no_messages')}</div>
  65. <div className="first-message text-center">
  66. {t('send_first_message')}
  67. <br />
  68. <Icon type="arrow-down" />
  69. </div>
  70. </>
  71. )
  72. }
  73. ChatPane.propTypes = {
  74. atEnd: PropTypes.bool,
  75. loading: PropTypes.bool,
  76. loadMoreMessages: PropTypes.func.isRequired,
  77. messages: PropTypes.array.isRequired,
  78. resetUnreadMessages: PropTypes.func.isRequired,
  79. sendMessage: PropTypes.func.isRequired,
  80. userId: PropTypes.string.isRequired
  81. }
  82. export default ChatPane