chatStore.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. import {
  2. MESSAGE_TYPE,
  3. MESSAGE_STATUS
  4. } from "../api/enums.js"
  5. import userStore from './userStore';
  6. export default {
  7. state: {
  8. activeChat: null,
  9. privateMsgMaxId: 0,
  10. groupMsgMaxId: 0,
  11. loadingPrivateMsg: false,
  12. loadingGroupMsg: false,
  13. chats: []
  14. },
  15. mutations: {
  16. initChats(state, chatsData) {
  17. state.chats = chatsData.chats || [];
  18. state.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
  19. state.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
  20. // 防止图片一直处在加载中状态
  21. state.chats.forEach((chat) => {
  22. chat.messages.forEach((msg) => {
  23. if (msg.loadStatus == "loading") {
  24. msg.loadStatus = "fail"
  25. }
  26. })
  27. })
  28. },
  29. openChat(state, chatInfo) {
  30. let chat = null;
  31. for (let idx in state.chats) {
  32. if (state.chats[idx].type == chatInfo.type &&
  33. state.chats[idx].targetId === chatInfo.targetId) {
  34. chat = state.chats[idx];
  35. // 放置头部
  36. this.commit("moveTop", idx)
  37. break;
  38. }
  39. }
  40. // 创建会话
  41. if (chat == null) {
  42. chat = {
  43. targetId: chatInfo.targetId,
  44. type: chatInfo.type,
  45. showName: chatInfo.showName,
  46. headImage: chatInfo.headImage,
  47. lastContent: "",
  48. lastSendTime: new Date().getTime(),
  49. unreadCount: 0,
  50. messages: [],
  51. atMe: false,
  52. atAll: false
  53. };
  54. state.chats.unshift(chat);
  55. }
  56. },
  57. activeChat(state, idx) {
  58. state.activeChat = state.chats[idx];
  59. },
  60. resetUnreadCount(state, chatInfo) {
  61. for (let idx in state.chats) {
  62. if (state.chats[idx].type == chatInfo.type &&
  63. state.chats[idx].targetId == chatInfo.targetId) {
  64. state.chats[idx].unreadCount = 0;
  65. state.chats[idx].atMe = false;
  66. state.chats[idx].atAll = false;
  67. }
  68. }
  69. this.commit("saveToStorage");
  70. },
  71. readedMessage(state, pos) {
  72. for (let idx in state.chats) {
  73. if (state.chats[idx].type == 'PRIVATE' &&
  74. state.chats[idx].targetId == pos.friendId) {
  75. state.chats[idx].messages.forEach((m) => {
  76. if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
  77. // pos.maxId为空表示整个会话已读
  78. if (!pos.maxId || m.id <= pos.maxId) {
  79. m.status = MESSAGE_STATUS.READED
  80. }
  81. }
  82. })
  83. }
  84. }
  85. this.commit("saveToStorage");
  86. },
  87. removeChat(state, idx) {
  88. if (state.chats[idx] == state.activeChat) {
  89. state.activeChat = null;
  90. }
  91. state.chats.splice(idx, 1);
  92. this.commit("saveToStorage");
  93. },
  94. moveTop(state, idx) {
  95. // 加载中不移动,很耗性能
  96. if (state.loadingPrivateMsg || state.loadingGroupMsg) {
  97. return;
  98. }
  99. if (idx > 0) {
  100. let chat = state.chats[idx];
  101. state.chats.splice(idx, 1);
  102. state.chats.unshift(chat);
  103. this.commit("saveToStorage");
  104. }
  105. },
  106. removePrivateChat(state, friendId) {
  107. for (let idx in state.chats) {
  108. if (state.chats[idx].type == 'PRIVATE' &&
  109. state.chats[idx].targetId == friendId) {
  110. this.commit("removeChat", idx);
  111. }
  112. }
  113. },
  114. insertMessage(state, msgInfo) {
  115. let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
  116. // 记录消息的最大id
  117. if (msgInfo.id && type == "PRIVATE" && msgInfo.id > state.privateMsgMaxId) {
  118. state.privateMsgMaxId = msgInfo.id;
  119. }
  120. if (msgInfo.id && type == "GROUP" && msgInfo.id > state.groupMsgMaxId) {
  121. state.groupMsgMaxId = msgInfo.id;
  122. }
  123. // 如果是已存在消息,则覆盖旧的消息数据
  124. let chat = this.getters.findChat(msgInfo);
  125. let message = this.getters.findMessage(chat, msgInfo);
  126. if (message) {
  127. Object.assign(message, msgInfo);
  128. // 撤回消息需要显示
  129. if (msgInfo.type == MESSAGE_TYPE.RECALL) {
  130. chat.lastContent = msgInfo.content;
  131. }
  132. this.commit("saveToStorage");
  133. return;
  134. }
  135. // 插入新的数据
  136. if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
  137. chat.lastContent = "[图片]";
  138. } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
  139. chat.lastContent = "[文件]";
  140. } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
  141. chat.lastContent = "[语音]";
  142. } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
  143. chat.lastContent = msgInfo.content;
  144. } else if (msgInfo.type == MESSAGE_TYPE.RT_VOICE) {
  145. chat.lastContent = "[语音通话]";
  146. } else if (msgInfo.type == MESSAGE_TYPE.RT_VIDEO) {
  147. chat.lastContent = "[视频通话]";
  148. }
  149. chat.lastSendTime = msgInfo.sendTime;
  150. chat.sendNickName = msgInfo.sendNickName;
  151. // 未读加1
  152. if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED && msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
  153. chat.unreadCount++;
  154. }
  155. // 是否有人@我
  156. if (!msgInfo.selfSend && chat.type == "GROUP" && msgInfo.atUserIds &&
  157. msgInfo.status != MESSAGE_STATUS.READED) {
  158. let userId = userStore.state.userInfo.id;
  159. if (msgInfo.atUserIds.indexOf(userId) >= 0) {
  160. chat.atMe = true;
  161. }
  162. if (msgInfo.atUserIds.indexOf(-1) >= 0) {
  163. chat.atAll = true;
  164. }
  165. }
  166. // 间隔大于10分钟插入时间显示
  167. if (!chat.lastTimeTip || (chat.lastTimeTip < msgInfo.sendTime - 600 * 1000)) {
  168. chat.messages.push({
  169. sendTime: msgInfo.sendTime,
  170. type: MESSAGE_TYPE.TIP_TIME,
  171. });
  172. chat.lastTimeTip = msgInfo.sendTime;
  173. }
  174. // 根据id顺序插入,防止消息乱序
  175. let insertPos = chat.messages.length;
  176. for (let idx in chat.messages) {
  177. if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) {
  178. insertPos = idx;
  179. console.log(`消息出现乱序,位置:${chat.messages.length},修正至:${insertPos}`);
  180. break;
  181. }
  182. }
  183. chat.messages.splice(insertPos, 0, msgInfo);
  184. this.commit("saveToStorage");
  185. },
  186. updateMessage(state, msgInfo) {
  187. // 获取对方id或群id
  188. let chat = this.getters.findChat(msgInfo);
  189. let message = this.getters.findMessage(chat, msgInfo);
  190. if (message) {
  191. // 属性拷贝
  192. Object.assign(message, msgInfo);
  193. this.commit("saveToStorage");
  194. }
  195. },
  196. deleteMessage(state, msgInfo) {
  197. let chat = this.getters.findChat(msgInfo);
  198. for (let idx in chat.messages) {
  199. // 已经发送成功的,根据id删除
  200. if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
  201. chat.messages.splice(idx, 1);
  202. break;
  203. }
  204. // 正在发送中的消息可能没有id,根据发送时间删除
  205. if (msgInfo.selfSend && chat.messages[idx].selfSend &&
  206. chat.messages[idx].sendTime == msgInfo.sendTime) {
  207. chat.messages.splice(idx, 1);
  208. break;
  209. }
  210. }
  211. this.commit("saveToStorage");
  212. },
  213. updateChatFromFriend(state, friend) {
  214. for (let i in state.chats) {
  215. let chat = state.chats[i];
  216. if (chat.type == 'PRIVATE' && chat.targetId == friend.id) {
  217. chat.headImage = friend.headImageThumb;
  218. chat.showName = friend.nickName;
  219. break;
  220. }
  221. }
  222. this.commit("saveToStorage");
  223. },
  224. updateChatFromGroup(state, group) {
  225. for (let i in state.chats) {
  226. let chat = state.chats[i];
  227. if (chat.type == 'GROUP' && chat.targetId == group.id) {
  228. chat.headImage = group.headImageThumb;
  229. chat.showName = group.remark;
  230. break;
  231. }
  232. }
  233. this.commit("saveToStorage");
  234. },
  235. loadingPrivateMsg(state, loadding) {
  236. state.loadingPrivateMsg = loadding;
  237. if (!state.loadingPrivateMsg && !state.loadingGroupMsg) {
  238. this.commit("sort")
  239. }
  240. },
  241. loadingGroupMsg(state, loadding) {
  242. state.loadingGroupMsg = loadding;
  243. if (!state.loadingPrivateMsg && !state.loadingGroupMsg) {
  244. this.commit("sort")
  245. }
  246. },
  247. sort(state) {
  248. state.chats.sort((c1, c2) => c2.lastSendTime - c1.lastSendTime);
  249. },
  250. saveToStorage(state) {
  251. let userId = userStore.state.userInfo.id;
  252. let key = "chats-" + userId;
  253. let chatsData = {
  254. privateMsgMaxId: state.privateMsgMaxId,
  255. groupMsgMaxId: state.groupMsgMaxId,
  256. chats: state.chats
  257. }
  258. localStorage.setItem(key, JSON.stringify(chatsData));
  259. },
  260. clear(state) {
  261. state.activeChat = null;
  262. state.chats = [];
  263. }
  264. },
  265. actions: {
  266. loadChat(context) {
  267. return new Promise((resolve, reject) => {
  268. let userId = userStore.state.userInfo.id;
  269. let key = "chats-" + userId;
  270. let item = localStorage.getItem(key)
  271. if (item) {
  272. let chatsData = JSON.parse(item);
  273. context.commit("initChats", chatsData);
  274. }
  275. resolve();
  276. })
  277. }
  278. },
  279. getters: {
  280. findChatIdx: (state) => (chat) => {
  281. for (let idx in state.chats) {
  282. if (state.chats[idx].type == chat.type &&
  283. state.chats[idx].targetId === chat.targetId) {
  284. chat = state.chats[idx];
  285. return idx
  286. }
  287. }
  288. },
  289. findChat: (state) => (msgInfo) => {
  290. // 获取对方id或群id
  291. let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
  292. let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId;
  293. let chat = null;
  294. for (let idx in state.chats) {
  295. if (state.chats[idx].type == type &&
  296. state.chats[idx].targetId === targetId) {
  297. chat = state.chats[idx];
  298. break;
  299. }
  300. }
  301. return chat;
  302. },
  303. findMessage: (state) => (chat, msgInfo) => {
  304. if (!chat) {
  305. return null;
  306. }
  307. for (let idx in chat.messages) {
  308. // 通过id判断
  309. if (msgInfo.id && chat.messages[idx].id == msgInfo.id) {
  310. return chat.messages[idx];
  311. }
  312. // 正在发送中的消息可能没有id,通过发送时间判断
  313. if (msgInfo.selfSend && chat.messages[idx].selfSend &&
  314. chat.messages[idx].sendTime == msgInfo.sendTime) {
  315. return chat.messages[idx];
  316. }
  317. }
  318. }
  319. }
  320. }