chatsActions.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import { history } from '../App'
  2. import { gql } from '../helpers'
  3. import {
  4. actionPromise,
  5. actionChatList,
  6. actionChatOne,
  7. actionChatLeft,
  8. actionAboutMe,
  9. store,
  10. } from '../reducers'
  11. import { actionGetAllLastMsg } from './msgActions'
  12. import { actionUploadFile } from './mediaActions'
  13. // в массив newMemders передавать объекты только с полем _id
  14. const actionUpdateChat = (title, members, chatId) =>
  15. actionPromise(
  16. 'updateChat',
  17. gql(
  18. `mutation updateChat($chat:ChatInput) {
  19. ChatUpsert(chat:$chat) {
  20. _id
  21. title
  22. avatar {
  23. _id
  24. url
  25. }
  26. owner {
  27. _id
  28. login
  29. avatar {
  30. _id
  31. url
  32. }
  33. }
  34. members {
  35. _id
  36. login
  37. nick
  38. avatar {
  39. _id
  40. url
  41. }
  42. }
  43. lastModified
  44. }
  45. }`,
  46. { chat: { _id: chatId, title, members } }
  47. )
  48. )
  49. // MediaUpsert нужен только для добавления данных для загруженного файла
  50. // и дальнейшего отображения его через эти данные (через аватары, сообщения)
  51. const actionUpdateChatAvatar = (mediaId, chatId) =>
  52. actionPromise(
  53. 'uploadFile',
  54. gql(
  55. `mutation uploadFile($media: MediaInput) {
  56. MediaUpsert(media: $media) {
  57. _id
  58. url
  59. }
  60. }`,
  61. { media: { _id: mediaId, chatAvatars: { _id: chatId } } }
  62. )
  63. )
  64. export const actionSetChatInfo =
  65. (name, file, title, members, chatId) => async (dispatch) => {
  66. const chat = await dispatch(actionUpdateChat(title, members, chatId))
  67. if (file && chat._id) {
  68. const fileObj = await dispatch(actionUploadFile(name, file))
  69. const chatAvatar = await dispatch(
  70. actionUpdateChatAvatar(fileObj?._id, chat._id)
  71. )
  72. await dispatch(actionChatOne({ _id: chat._id, avatar: chatAvatar }))
  73. }
  74. }
  75. // поиск по значению в массиве объектов - { 'members._id': userId }
  76. export const actionGetChatsByUser = (userId, skipCount = 0, limitCount = 50) =>
  77. actionPromise(
  78. 'userChats',
  79. gql(
  80. `query userChats($q: String) {
  81. ChatFind (query: $q){
  82. _id
  83. title
  84. avatar {
  85. _id
  86. url
  87. }
  88. owner {
  89. _id
  90. login
  91. avatar {
  92. _id
  93. url
  94. }
  95. }
  96. members {
  97. _id
  98. login
  99. nick
  100. avatar {
  101. _id
  102. url
  103. }
  104. }
  105. lastModified
  106. }
  107. }`,
  108. {
  109. q: JSON.stringify([
  110. {
  111. $or: [{ ___owner: userId }, { 'members._id': userId }],
  112. },
  113. {
  114. sort: [{ lastModified: -1 }],
  115. skip: [skipCount],
  116. limit: [limitCount],
  117. },
  118. ]),
  119. }
  120. )
  121. )
  122. export const actionFullChatList =
  123. (userId, currentCount, limitCount = 50) =>
  124. async (dispatch) => {
  125. const payload = await dispatch(
  126. actionGetChatsByUser(userId, currentCount, limitCount)
  127. )
  128. if (payload) {
  129. await dispatch(actionChatList(payload))
  130. await dispatch(actionGetAllLastMsg(payload))
  131. }
  132. }
  133. export const actionGetChatById = (chatId) =>
  134. actionPromise(
  135. 'chatById',
  136. gql(
  137. `query chatById($q: String) {
  138. ChatFindOne (query: $q){
  139. _id
  140. title
  141. avatar {
  142. _id
  143. url
  144. }
  145. owner {
  146. _id
  147. login
  148. avatar {
  149. _id
  150. url
  151. }
  152. }
  153. members {
  154. _id
  155. login
  156. nick
  157. avatar {
  158. _id
  159. url
  160. }
  161. }
  162. lastModified
  163. }
  164. }`,
  165. {
  166. q: JSON.stringify([{ _id: chatId }]),
  167. }
  168. )
  169. )
  170. export const actionChatsCount = (userId) =>
  171. actionPromise(
  172. 'chatsCount',
  173. gql(
  174. `query chatsCount($q: String) {
  175. ChatCount (query: $q)
  176. }`,
  177. {
  178. q: JSON.stringify([{ ___owner: userId }]),
  179. }
  180. )
  181. )
  182. // происходит когда юзер уходит сам, иначе в чат добавляются юзер, а не наоборот
  183. const actionUpdateUserChats = (userId, newChats) =>
  184. actionPromise(
  185. 'updateUserChats',
  186. gql(
  187. `mutation updateUserChats($user:UserInput) {
  188. UserUpsert(user:$user) {
  189. _id
  190. login
  191. nick
  192. chats {
  193. title
  194. _id
  195. }
  196. }
  197. }`,
  198. { user: { _id: userId, chats: newChats } }
  199. )
  200. )
  201. export const removeUserChat = (chatId) => async (dispatch, getState) => {
  202. const state = getState()
  203. const myId = state.promise.myProfile.payload._id
  204. const oldChats = state.promise.myProfile.payload.chats
  205. const newChats = oldChats.filter((chat) => chat._id !== chatId)
  206. await dispatch(actionUpdateUserChats(myId, newChats))
  207. const ownerId = state.chats[chatId]?.owner?._id
  208. // тут событие ухода из чата не приходит по сокету,
  209. // поэтому нужно делать все то, что и в сокете
  210. if (myId !== ownerId) {
  211. dispatch(actionChatLeft({ _id: chatId }))
  212. const [, , histId] = history.location.pathname.split('/')
  213. if (histId === chatId) {
  214. history.push('/')
  215. }
  216. } else {
  217. const chat = await dispatch(actionGetChatById(chatId))
  218. await dispatch(actionChatOne(chat))
  219. }
  220. await dispatch(actionAboutMe())
  221. }