msgActions.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import { gql } from '../helpers'
  2. import {
  3. actionPromise,
  4. actionMsgList,
  5. actionMsgOne,
  6. actionChatOne,
  7. store,
  8. } from '../reducers'
  9. import { actionUploadFile } from './mediaActions'
  10. export const actionGetMsgsByChat = (chatId, skipCount = 0, limitCount = 50) =>
  11. actionPromise(
  12. 'chatMsgs',
  13. gql(
  14. `query chatMsgs($q: String) {
  15. MessageFind (query: $q){
  16. _id
  17. createdAt
  18. owner {
  19. _id
  20. login
  21. nick
  22. avatar {
  23. url
  24. }
  25. }
  26. text
  27. chat {
  28. _id
  29. }
  30. media {
  31. _id
  32. url
  33. type
  34. originalFileName
  35. }
  36. forwardWith {
  37. _id
  38. }
  39. replies {
  40. _id
  41. }
  42. replyTo {
  43. _id
  44. }
  45. forwarded {
  46. _id
  47. }
  48. }
  49. }`,
  50. {
  51. q: JSON.stringify([
  52. { 'chat._id': { $in: [chatId] } },
  53. {
  54. sort: [{ _id: -1 }],
  55. skip: [skipCount],
  56. limit: [limitCount],
  57. },
  58. ]),
  59. }
  60. )
  61. )
  62. export const actionFullMsgsByChat =
  63. (chatId, currentCount, limitCount = 50) =>
  64. async (dispatch, getState) => {
  65. const chat = getState().chats[chatId]
  66. if (
  67. !chat ||
  68. !chat.messages ||
  69. (chat.messages[0]?._id !== chat.firstMsgId &&
  70. (chat.messages?.length ?? 0) < currentCount + limitCount)
  71. ) {
  72. const payload = await dispatch(
  73. actionGetMsgsByChat(chatId, currentCount, limitCount)
  74. )
  75. if (payload) {
  76. await dispatch(actionMsgList(payload))
  77. }
  78. }
  79. }
  80. const actionFirstMsgByChat = (chatId) =>
  81. actionPromise(
  82. 'firstMsg',
  83. gql(
  84. `query firstMsg($q: String) {
  85. MessageFind (query: $q){
  86. _id
  87. }
  88. }`,
  89. {
  90. q: JSON.stringify([
  91. { 'chat._id': chatId },
  92. {
  93. sort: [{ _id: 1 }],
  94. skip: [0],
  95. limit: [1],
  96. },
  97. ]),
  98. }
  99. )
  100. )
  101. export const actionGetAllLastMsg = (chats) => async (dispatch, getState) => {
  102. const msgReq = chats.map((chat) =>
  103. Promise.all([
  104. dispatch(actionGetMsgsByChat(chat._id, 0, 1)),
  105. getState().chats[chat._id]?.firstMsgId
  106. ? Promise.resolve([])
  107. : dispatch(actionFirstMsgByChat(chat._id)),
  108. ])
  109. )
  110. for await (const [lastMsgs, firstMsgs] of msgReq) {
  111. lastMsgs.length && dispatch(actionMsgOne(lastMsgs[0]))
  112. firstMsgs.length &&
  113. dispatch(
  114. actionChatOne({
  115. _id: lastMsgs[0].chat._id,
  116. firstMsgId: firstMsgs[0]._id,
  117. })
  118. )
  119. }
  120. }
  121. export const actionMsgsCount = (chatId) =>
  122. actionPromise(
  123. 'msgsCount',
  124. gql(
  125. `query msgsCount($q: String) {
  126. MessageCount (query: $q)
  127. }`,
  128. {
  129. q: JSON.stringify([{ 'chat._id': chatId }]),
  130. }
  131. )
  132. )
  133. export const actionGetMsgById = (msgId) =>
  134. actionPromise(
  135. 'msgById',
  136. gql(
  137. `query msgById($q: String) {
  138. MessageFindOne (query: $q){
  139. _id
  140. createdAt
  141. owner {
  142. _id
  143. login
  144. nick
  145. avatar {
  146. url
  147. }
  148. }
  149. text
  150. chat {
  151. _id
  152. }
  153. media {
  154. _id
  155. url
  156. type
  157. originalFileName
  158. }
  159. forwardWith {
  160. _id
  161. }
  162. replies {
  163. _id
  164. }
  165. replyTo {
  166. _id
  167. }
  168. forwarded {
  169. _id
  170. }
  171. }
  172. }`,
  173. {
  174. q: JSON.stringify([{ _id: msgId }]),
  175. }
  176. )
  177. )
  178. export const actionUpdateMsg = (chatId, text, media, msgId) =>
  179. actionPromise(
  180. 'updateMsg',
  181. gql(
  182. `mutation updateMsg($msg: MessageInput) {
  183. MessageUpsert(message: $msg) {
  184. _id
  185. createdAt
  186. owner {
  187. _id
  188. login
  189. nick
  190. avatar {
  191. url
  192. }
  193. }
  194. text
  195. chat {
  196. _id
  197. }
  198. media {
  199. _id
  200. url
  201. type
  202. originalFileName
  203. }
  204. forwardWith {
  205. _id
  206. }
  207. replies {
  208. _id
  209. }
  210. replyTo {
  211. _id
  212. }
  213. forwarded {
  214. _id
  215. }
  216. }
  217. }`,
  218. {
  219. msg: {
  220. _id: msgId,
  221. text,
  222. chat: { _id: chatId },
  223. media,
  224. // replyTo: {_id: undefined}
  225. },
  226. }
  227. )
  228. )
  229. // медиа - массив объектов с ид медиа
  230. export const actionSendMsg =
  231. (chatId, text, inputName, files, msgId) => async (dispatch) => {
  232. // тут нужно отделить уже залитые файлы от тех которые лежат локально
  233. // локальные залить и получить ид, с залитых просто получить ид
  234. const mediaToUpload = []
  235. const media = []
  236. for (const file of files) {
  237. if (file.url.match(/blob/)) {
  238. mediaToUpload.push(dispatch(actionUploadFile(inputName, file)))
  239. } else {
  240. let fileObj = file
  241. media.push({ _id: fileObj?._id })
  242. }
  243. }
  244. const fileArr = await Promise.all(mediaToUpload)
  245. if (fileArr) {
  246. for (const uploadedFile of fileArr) {
  247. media.push({ _id: uploadedFile?._id })
  248. }
  249. }
  250. const payload = await dispatch(
  251. actionUpdateMsg(chatId, text, media, msgId)
  252. )
  253. }