chat-store.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import EventEmitter from '../../../utils/EventEmitter'
  2. import { appendMessage, prependMessages } from './message-list-appender'
  3. import { getJSON, postJSON } from '../../../infrastructure/fetch-json'
  4. export const MESSAGE_LIMIT = 50
  5. export class ChatStore {
  6. constructor(user, projectId) {
  7. this.messages = []
  8. this.loading = false
  9. this.atEnd = false
  10. this._user = user
  11. this._projectId = projectId
  12. this._nextBeforeTimestamp = null
  13. this._justSent = false
  14. this._emitter = new EventEmitter()
  15. this._onNewChatMessage = message => {
  16. const messageIsFromSelf =
  17. message && message.user && message.user.id === this._user.id
  18. if (!messageIsFromSelf || !this._justSent) {
  19. this.messages = appendMessage(this.messages, message)
  20. this._emitter.emit('updated')
  21. this._emitter.emit('message-received', message)
  22. window.dispatchEvent(
  23. new CustomEvent('Chat.MessageReceived', { detail: { message } })
  24. )
  25. }
  26. this._justSent = false
  27. }
  28. window._ide.socket.on('new-chat-message', this._onNewChatMessage)
  29. }
  30. destroy() {
  31. window._ide.socket.removeListener(
  32. 'new-chat-message',
  33. this._onNewChatMessage
  34. )
  35. this._emitter.off() // removes all listeners
  36. }
  37. on(event, fn) {
  38. this._emitter.on(event, fn)
  39. }
  40. off(event, fn) {
  41. this._emitter.off(event, fn)
  42. }
  43. loadMoreMessages() {
  44. if (this.atEnd) {
  45. return
  46. }
  47. this.loading = true
  48. this._emitter.emit('updated')
  49. let url = `/project/${window.project_id}/messages?limit=${MESSAGE_LIMIT}`
  50. if (this._nextBeforeTimestamp) {
  51. url += `&before=${this._nextBeforeTimestamp}`
  52. }
  53. return getJSON(url).then(response => {
  54. const messages = response || []
  55. this.loading = false
  56. if (messages.length < MESSAGE_LIMIT) {
  57. this.atEnd = true
  58. }
  59. messages.reverse()
  60. this.messages = prependMessages(this.messages, messages)
  61. this._nextBeforeTimestamp = this.messages[0]
  62. ? this.messages[0].timestamp
  63. : undefined
  64. this._emitter.emit('updated')
  65. })
  66. }
  67. sendMessage(message) {
  68. if (!message) {
  69. return
  70. }
  71. const body = {
  72. content: message,
  73. _csrf: window.csrfToken
  74. }
  75. this._justSent = true
  76. this.messages = appendMessage(this.messages, {
  77. user: this._user,
  78. content: message,
  79. timestamp: Date.now()
  80. })
  81. const url = `/project/${this._projectId}/messages`
  82. this._emitter.emit('updated')
  83. return postJSON(url, { body })
  84. }
  85. }