message-list-utils.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { Message, ServerMessageEntry } from '../context/chat-context'
  2. export function appendMessage(
  3. messageList: Message[],
  4. message: ServerMessageEntry,
  5. uniqueMessageIds: string[]
  6. ) {
  7. if (uniqueMessageIds.includes(message.id)) {
  8. return { messages: messageList, uniqueMessageIds }
  9. }
  10. uniqueMessageIds = uniqueMessageIds.slice(0)
  11. uniqueMessageIds.push(message.id)
  12. messageList = messageList.slice(0).concat({
  13. id: message.id,
  14. user: message.user,
  15. timestamp: message.timestamp,
  16. content: message.content,
  17. pending: message.pending,
  18. edited: Boolean(message.edited_at),
  19. })
  20. return { messages: messageList, uniqueMessageIds }
  21. }
  22. export function prependMessages(
  23. messageList: Message[],
  24. messages: ServerMessageEntry[],
  25. uniqueMessageIds: string[]
  26. ) {
  27. const listCopy = messageList.slice(0)
  28. uniqueMessageIds = uniqueMessageIds.slice(0)
  29. messages
  30. .slice(0)
  31. .reverse()
  32. .forEach(message => {
  33. if (uniqueMessageIds.includes(message.id)) {
  34. return
  35. }
  36. uniqueMessageIds.push(message.id)
  37. listCopy.unshift({
  38. id: message.id,
  39. user: message.user,
  40. timestamp: message.timestamp,
  41. content: message.content,
  42. edited: Boolean(message.edited_at),
  43. })
  44. })
  45. return { messages: listCopy, uniqueMessageIds }
  46. }
  47. export function confirmMessage(
  48. updatedMessage: Message,
  49. messageList: Message[]
  50. ) {
  51. // Find our message and change its ID from the temporary one we generated
  52. // on creation to the ID assigned to it by the server. This is so that the
  53. // message can be deleted later, for which we need the server ID.
  54. const ownMessageIndex = messageList.findIndex(
  55. message => message.pending && message.content === updatedMessage.content
  56. )
  57. if (ownMessageIndex === -1) {
  58. throw new Error("Couldn't find own message in local state")
  59. }
  60. const messageWithOldId = messageList[ownMessageIndex]
  61. const newMessageList = [...messageList]
  62. newMessageList.splice(ownMessageIndex, 1, {
  63. ...messageWithOldId,
  64. pending: false,
  65. id: updatedMessage.id,
  66. user: updatedMessage.user,
  67. timestamp: updatedMessage.timestamp,
  68. content: updatedMessage.content,
  69. })
  70. return {
  71. messages: newMessageList,
  72. uniqueMessageIds: Array.from(
  73. new Set(newMessageList.map(message => message.id))
  74. ),
  75. }
  76. }
  77. export function deleteMessage(messageId: string, messageList: Message[]) {
  78. const messageIndex = messageList.findIndex(
  79. message => message.id === messageId
  80. )
  81. if (messageIndex === -1) {
  82. throw new Error(`Message with id ${messageId} not found in message list`)
  83. }
  84. const newMessageList = [...messageList]
  85. const message = newMessageList[messageIndex]
  86. newMessageList.splice(messageIndex, 1, {
  87. ...message,
  88. deleted: true,
  89. })
  90. return {
  91. messages: newMessageList,
  92. }
  93. }
  94. export function editMessage(
  95. messageId: string,
  96. content: string,
  97. messageList: Message[]
  98. ) {
  99. const messageIndex = messageList.findIndex(
  100. message => message.id === messageId
  101. )
  102. if (messageIndex === -1) {
  103. throw new Error(`Message with id ${messageId} not found in message list`)
  104. }
  105. const newMessageList = [...messageList]
  106. const message = newMessageList[messageIndex]
  107. newMessageList.splice(messageIndex, 1, {
  108. ...message,
  109. content,
  110. edited: true,
  111. })
  112. return {
  113. messages: newMessageList,
  114. }
  115. }