logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://hacktivis.me/git/pleroma-fe.git

chats.js (8627B)


  1. import { reactive } from 'vue'
  2. import { find, omitBy, orderBy, sumBy } from 'lodash'
  3. import chatService from '../services/chat_service/chat_service.js'
  4. import { parseChat, parseChatMessage } from '../services/entity_normalizer/entity_normalizer.service.js'
  5. import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
  6. import { promiseInterval } from '../services/promise_interval/promise_interval.js'
  7. const emptyChatList = () => ({
  8. data: [],
  9. idStore: {}
  10. })
  11. const defaultState = {
  12. chatList: emptyChatList(),
  13. chatListFetcher: null,
  14. openedChats: reactive({}),
  15. openedChatMessageServices: reactive({}),
  16. fetcher: undefined,
  17. currentChatId: null,
  18. lastReadMessageId: null
  19. }
  20. const getChatById = (state, id) => {
  21. return find(state.chatList.data, { id })
  22. }
  23. const sortedChatList = (state) => {
  24. return orderBy(state.chatList.data, ['updated_at'], ['desc'])
  25. }
  26. const unreadChatCount = (state) => {
  27. return sumBy(state.chatList.data, 'unread')
  28. }
  29. const chats = {
  30. state: { ...defaultState },
  31. getters: {
  32. currentChat: state => state.openedChats[state.currentChatId],
  33. currentChatMessageService: state => state.openedChatMessageServices[state.currentChatId],
  34. findOpenedChatByRecipientId: state => recipientId => find(state.openedChats, c => c.account.id === recipientId),
  35. sortedChatList,
  36. unreadChatCount
  37. },
  38. actions: {
  39. // Chat list
  40. startFetchingChats ({ dispatch, commit }) {
  41. const fetcher = () => dispatch('fetchChats', { latest: true })
  42. fetcher()
  43. commit('setChatListFetcher', {
  44. fetcher: () => promiseInterval(fetcher, 5000)
  45. })
  46. },
  47. stopFetchingChats ({ commit }) {
  48. commit('setChatListFetcher', { fetcher: undefined })
  49. },
  50. fetchChats ({ dispatch, rootState, commit }, params = {}) {
  51. return rootState.api.backendInteractor.chats()
  52. .then(({ chats }) => {
  53. dispatch('addNewChats', { chats })
  54. return chats
  55. })
  56. },
  57. addNewChats (store, { chats }) {
  58. const { commit, dispatch, rootGetters } = store
  59. const newChatMessageSideEffects = (chat) => {
  60. maybeShowChatNotification(store, chat)
  61. }
  62. commit('addNewUsers', chats.map(k => k.account).filter(k => k))
  63. commit('addNewChats', { dispatch, chats, rootGetters, newChatMessageSideEffects })
  64. },
  65. updateChat ({ commit }, { chat }) {
  66. commit('updateChat', { chat })
  67. },
  68. // Opened Chats
  69. startFetchingCurrentChat ({ commit, dispatch }, { fetcher }) {
  70. dispatch('setCurrentChatFetcher', { fetcher })
  71. },
  72. setCurrentChatFetcher ({ rootState, commit }, { fetcher }) {
  73. commit('setCurrentChatFetcher', { fetcher })
  74. },
  75. addOpenedChat ({ rootState, commit, dispatch }, { chat }) {
  76. commit('addOpenedChat', { dispatch, chat: parseChat(chat) })
  77. dispatch('addNewUsers', [chat.account])
  78. },
  79. addChatMessages ({ commit }, value) {
  80. commit('addChatMessages', { commit, ...value })
  81. },
  82. resetChatNewMessageCount ({ commit }, value) {
  83. commit('resetChatNewMessageCount', value)
  84. },
  85. clearCurrentChat ({ rootState, commit, dispatch }, value) {
  86. commit('setCurrentChatId', { chatId: undefined })
  87. commit('setCurrentChatFetcher', { fetcher: undefined })
  88. },
  89. readChat ({ rootState, commit, dispatch }, { id, lastReadId }) {
  90. const isNewMessage = rootState.chats.lastReadMessageId !== lastReadId
  91. dispatch('resetChatNewMessageCount')
  92. commit('readChat', { id, lastReadId })
  93. if (isNewMessage) {
  94. rootState.api.backendInteractor.readChat({ id, lastReadId })
  95. }
  96. },
  97. deleteChatMessage ({ rootState, commit }, value) {
  98. rootState.api.backendInteractor.deleteChatMessage(value)
  99. commit('deleteChatMessage', { commit, ...value })
  100. },
  101. resetChats ({ commit, dispatch }) {
  102. dispatch('clearCurrentChat')
  103. commit('resetChats', { commit })
  104. },
  105. clearOpenedChats ({ rootState, commit, dispatch, rootGetters }) {
  106. commit('clearOpenedChats', { commit })
  107. },
  108. handleMessageError ({ commit }, value) {
  109. commit('handleMessageError', { commit, ...value })
  110. },
  111. cullOlderMessages ({ commit }, chatId) {
  112. commit('cullOlderMessages', chatId)
  113. }
  114. },
  115. mutations: {
  116. setChatListFetcher (state, { commit, fetcher }) {
  117. const prevFetcher = state.chatListFetcher
  118. if (prevFetcher) {
  119. prevFetcher.stop()
  120. }
  121. state.chatListFetcher = fetcher && fetcher()
  122. },
  123. setCurrentChatFetcher (state, { fetcher }) {
  124. const prevFetcher = state.fetcher
  125. if (prevFetcher) {
  126. prevFetcher.stop()
  127. }
  128. state.fetcher = fetcher && fetcher()
  129. },
  130. addOpenedChat (state, { _dispatch, chat }) {
  131. state.currentChatId = chat.id
  132. state.openedChats[chat.id] = chat
  133. if (!state.openedChatMessageServices[chat.id]) {
  134. state.openedChatMessageServices[chat.id] = chatService.empty(chat.id)
  135. }
  136. },
  137. setCurrentChatId (state, { chatId }) {
  138. state.currentChatId = chatId
  139. },
  140. addNewChats (state, { chats, newChatMessageSideEffects }) {
  141. chats.forEach((updatedChat) => {
  142. const chat = getChatById(state, updatedChat.id)
  143. if (chat) {
  144. const isNewMessage = (chat.lastMessage && chat.lastMessage.id) !== (updatedChat.lastMessage && updatedChat.lastMessage.id)
  145. chat.lastMessage = updatedChat.lastMessage
  146. chat.unread = updatedChat.unread
  147. chat.updated_at = updatedChat.updated_at
  148. if (isNewMessage && chat.unread) {
  149. newChatMessageSideEffects(updatedChat)
  150. }
  151. } else {
  152. state.chatList.data.push(updatedChat)
  153. state.chatList.idStore[updatedChat.id] = updatedChat
  154. }
  155. })
  156. },
  157. updateChat (state, { _dispatch, chat: updatedChat, _rootGetters }) {
  158. const chat = getChatById(state, updatedChat.id)
  159. if (chat) {
  160. chat.lastMessage = updatedChat.lastMessage
  161. chat.unread = updatedChat.unread
  162. chat.updated_at = updatedChat.updated_at
  163. }
  164. if (!chat) { state.chatList.data.unshift(updatedChat) }
  165. state.chatList.idStore[updatedChat.id] = updatedChat
  166. },
  167. deleteChat (state, { _dispatch, id, _rootGetters }) {
  168. state.chats.data = state.chats.data.filter(conversation =>
  169. conversation.last_status.id !== id
  170. )
  171. state.chats.idStore = omitBy(state.chats.idStore, conversation => conversation.last_status.id === id)
  172. },
  173. resetChats (state, { commit }) {
  174. state.chatList = emptyChatList()
  175. state.currentChatId = null
  176. commit('setChatListFetcher', { fetcher: undefined })
  177. for (const chatId in state.openedChats) {
  178. chatService.clear(state.openedChatMessageServices[chatId])
  179. delete state.openedChats[chatId]
  180. delete state.openedChatMessageServices[chatId]
  181. }
  182. },
  183. setChatsLoading (state, { value }) {
  184. state.chats.loading = value
  185. },
  186. addChatMessages (state, { chatId, messages, updateMaxId }) {
  187. const chatMessageService = state.openedChatMessageServices[chatId]
  188. if (chatMessageService) {
  189. chatService.add(chatMessageService, { messages: messages.map(parseChatMessage), updateMaxId })
  190. }
  191. },
  192. deleteChatMessage (state, { chatId, messageId }) {
  193. const chatMessageService = state.openedChatMessageServices[chatId]
  194. if (chatMessageService) {
  195. chatService.deleteMessage(chatMessageService, messageId)
  196. }
  197. },
  198. resetChatNewMessageCount (state, _value) {
  199. const chatMessageService = state.openedChatMessageServices[state.currentChatId]
  200. chatService.resetNewMessageCount(chatMessageService)
  201. },
  202. // Used when a connection loss occurs
  203. clearOpenedChats (state) {
  204. const currentChatId = state.currentChatId
  205. for (const chatId in state.openedChats) {
  206. if (currentChatId !== chatId) {
  207. chatService.clear(state.openedChatMessageServices[chatId])
  208. delete state.openedChats[chatId]
  209. delete state.openedChatMessageServices[chatId]
  210. }
  211. }
  212. },
  213. readChat (state, { id, lastReadId }) {
  214. state.lastReadMessageId = lastReadId
  215. const chat = getChatById(state, id)
  216. if (chat) {
  217. chat.unread = 0
  218. }
  219. },
  220. handleMessageError (state, { chatId, fakeId, isRetry }) {
  221. const chatMessageService = state.openedChatMessageServices[chatId]
  222. chatService.handleMessageError(chatMessageService, fakeId, isRetry)
  223. },
  224. cullOlderMessages (state, chatId) {
  225. chatService.cullOlderMessages(state.openedChatMessageServices[chatId])
  226. }
  227. }
  228. }
  229. export default chats