Browse Source

优化: uniapp会话置顶、删除会话、好友状态更新导致卡顿

master
blue 2 years ago
parent
commit
267e790188
  1. 2
      im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java
  2. 2
      im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java
  3. 3
      im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java
  4. 3
      im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java
  5. 5
      im-ui/src/store/chatStore.js
  6. 4
      im-uniapp/App.vue
  7. 18
      im-uniapp/components/chat-item/chat-item.vue
  8. 6
      im-uniapp/components/chat-message-item/chat-message-item.vue
  9. 1
      im-uniapp/components/pop-menu/pop-menu.vue
  10. 2
      im-uniapp/components/user-search/user-search.vue
  11. 3
      im-uniapp/package.json
  12. 15
      im-uniapp/pages/chat/chat-box.vue
  13. 40
      im-uniapp/pages/chat/chat.vue
  14. 5
      im-uniapp/pages/common/user-info.vue
  15. 2
      im-uniapp/pages/friend/friend-add.vue
  16. 5
      im-uniapp/pages/friend/friend-search.vue
  17. 17
      im-uniapp/pages/friend/friend.vue
  18. 3
      im-uniapp/pages/group/group-info.vue
  19. 3
      im-uniapp/pages/group/group-invite.vue
  20. 69
      im-uniapp/store/chatStore.js
  21. 51
      im-uniapp/store/friendStore.js

2
im-platform/src/main/java/com/bx/implatform/controller/GroupMessageController.java

@ -37,7 +37,7 @@ public class GroupMessageController {
@GetMapping("/loadMessage") @GetMapping("/loadMessage")
@ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条") @ApiOperation(value = "拉取消息(已废弃)", notes = "拉取消息,一次最多拉取100条")
public Result<List<GroupMessageVO>> loadMessage(@RequestParam Long minId) { public Result<List<GroupMessageVO>> loadMessage(@RequestParam Long minId) {
return ResultUtils.success(groupMessageService.loadMessage(minId)); return ResultUtils.success(groupMessageService.loadMessage(minId));
} }

2
im-platform/src/main/java/com/bx/implatform/controller/PrivateMessageController.java

@ -38,7 +38,7 @@ public class PrivateMessageController {
@GetMapping("/loadMessage") @GetMapping("/loadMessage")
@ApiOperation(value = "拉取消息", notes = "拉取消息,一次最多拉取100条") @ApiOperation(value = "拉取消息(已废弃)", notes = "拉取消息,一次最多拉取100条")
public Result<List<PrivateMessageVO>> loadMessage(@RequestParam Long minId) { public Result<List<PrivateMessageVO>> loadMessage(@RequestParam Long minId) {
return ResultUtils.success(privateMessageService.loadMessage(minId)); return ResultUtils.success(privateMessageService.loadMessage(minId));
} }

3
im-platform/src/main/java/com/bx/implatform/service/impl/PrivateMessageServiceImpl.java

@ -237,8 +237,7 @@ public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper,
IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>(); IMPrivateMessage<PrivateMessageVO> sendMessage = new IMPrivateMessage<>();
sendMessage.setData(msgInfo); sendMessage.setData(msgInfo);
sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal())); sendMessage.setSender(new IMUserInfo(session.getUserId(), session.getTerminal()));
sendMessage.setRecvId(session.getUserId()); sendMessage.setSendToSelf(true);
sendMessage.setSendToSelf(false);
sendMessage.setSendResult(false); sendMessage.setSendResult(false);
imClient.sendPrivateMessage(sendMessage); imClient.sendPrivateMessage(sendMessage);
// 推送回执消息给对方,更新已读状态 // 推送回执消息给对方,更新已读状态

3
im-platform/src/main/java/com/bx/implatform/util/SensitiveFilterUtil.java

@ -79,11 +79,10 @@ public final class SensitiveFilterUtil {
*/ */
@PostConstruct @PostConstruct
public void init() { public void init() {
try ( try {
// 类加载器 // 类加载器
InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt"); InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is)); BufferedReader reader = new BufferedReader(new InputStreamReader(is));
) {
String keyword; String keyword;
while ((keyword = reader.readLine()) != null) { while ((keyword = reader.readLine()) != null) {
// 添加到前缀树 // 添加到前缀树

5
im-ui/src/store/chatStore.js

@ -186,12 +186,7 @@ export default {
} }
} }
} }
if(insertPos == chat.messages.length){
// 这种赋值效率最高
chat.messages[insertPos]= msgInfo;
}else{
chat.messages.splice(insertPos, 0, msgInfo); chat.messages.splice(insertPos, 0, msgInfo);
}
this.commit("saveToStorage"); this.commit("saveToStorage");
}, },
updateMessage(state, msgInfo) { updateMessage(state, msgInfo) {

4
im-uniapp/App.vue

@ -63,12 +63,14 @@
}) })
}, },
pullPrivateOfflineMessage(minId) { pullPrivateOfflineMessage(minId) {
store.commit("loadingPrivateMsg",true)
http({ http({
url: "/message/private/pullOfflineMessage?minId=" + minId, url: "/message/private/pullOfflineMessage?minId=" + minId,
method: 'get' method: 'get'
}); });
}, },
pullGroupOfflineMessage(minId) { pullGroupOfflineMessage(minId) {
store.commit("loadingGroupMsg",true)
http({ http({
url: "/message/group/pullOfflineMessage?minId=" + minId, url: "/message/group/pullOfflineMessage?minId=" + minId,
method: 'get' method: 'get'
@ -195,7 +197,7 @@
}, },
loadFriendInfo(id) { loadFriendInfo(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let friend = store.state.friendStore.friends.find((f) => f.id == id); let friend = store.getters.findFriend(id);
if (friend) { if (friend) {
resolve(friend); resolve(friend);
} else { } else {

18
im-uniapp/components/chat-item/chat-item.vue

@ -1,5 +1,5 @@
<template> <template>
<view class="chat-item" @click="showChatBox()"> <view class="chat-item" :class="active?'active':''" @click="showChatBox()">
<view class="left"> <view class="left">
<head-image :url="chat.headImage" :name="chat.showName" :size="90"></head-image> <head-image :url="chat.headImage" :name="chat.showName" :size="90"></head-image>
<view v-if="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</view> <view v-if="chat.unreadCount>0" class="unread-text">{{chat.unreadCount}}</view>
@ -30,6 +30,10 @@
}, },
index: { index: {
type: Number type: Number
},
active: {
type: Boolean,
default: false
} }
}, },
methods: { methods: {
@ -68,6 +72,10 @@
background-color: #eeeeee; background-color: #eeeeee;
} }
&.active {
background-color: #eeeeee;
}
.left { .left {
position: relative; position: relative;
display: flex; display: flex;
@ -100,8 +108,8 @@
.chat-name { .chat-name {
display: flex; display: flex;
line-height: 50rpx; line-height: 44rpx;
height: 50rpx; height: 44rpx;
.chat-name-text { .chat-name-text {
flex: 1; flex: 1;
@ -122,7 +130,8 @@
.chat-content { .chat-content {
display: flex; display: flex;
line-height: 44rpx; line-height: 60rpx;
height: 60rpx;
.chat-at-text { .chat-at-text {
color: #c70b0b; color: #c70b0b;
font-size: 24rpx; font-size: 24rpx;
@ -137,7 +146,6 @@
font-size: 28rpx; font-size: 28rpx;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
line-height: 50rpx;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
} }

6
im-uniapp/components/chat-message-item/chat-message-item.vue

@ -17,9 +17,11 @@
</view> </view>
<view class="chat-msg-bottom" @touchmove="onHideMenu()"> <view class="chat-msg-bottom" @touchmove="onHideMenu()">
<rich-text class="chat-msg-text" v-if="msgInfo.type==$enums.MESSAGE_TYPE.TEXT" <view v-if="msgInfo.type==$enums.MESSAGE_TYPE.TEXT" @longpress.native="onShowMenu($event)">
<rich-text class="chat-msg-text"
:nodes="$emo.transform(msgInfo.content)" :nodes="$emo.transform(msgInfo.content)"
@longpress="onShowMenu($event)"></rich-text> ></rich-text>
</view>
<view class="chat-msg-image" v-if="msgInfo.type==$enums.MESSAGE_TYPE.IMAGE"> <view class="chat-msg-image" v-if="msgInfo.type==$enums.MESSAGE_TYPE.IMAGE">
<view class="img-load-box" @longpress="onShowMenu($event)"> <view class="img-load-box" @longpress="onShowMenu($event)">
<image class="send-image" mode="heightFix" :src="JSON.parse(msgInfo.content).thumbUrl" <image class="send-image" mode="heightFix" :src="JSON.parse(msgInfo.content).thumbUrl"

1
im-uniapp/components/pop-menu/pop-menu.vue

@ -28,7 +28,6 @@
this.$emit("select", item); this.$emit("select", item);
}, },
onClose() { onClose() {
console.log("@touchmove")
this.$emit("close"); this.$emit("close");
} }
} }

2
im-uniapp/components/user-search/user-search.vue

@ -68,7 +68,7 @@
isFriend(userId) { isFriend(userId) {
let friends = this.$store.state.friendStore.friends; let friends = this.$store.state.friendStore.friends;
let friend = friends.find((f) => f.id == userId); let friend = friends.find((f) => f.id == userId);
return friend != undefined; return friend&&!friend.delete;
} }
} }
} }

3
im-uniapp/package.json

@ -4,7 +4,6 @@
"scripts": {} "scripts": {}
}, },
"dependencies": { "dependencies": {
"js-audio-recorder": "^1.0.7", "js-audio-recorder": "^1.0.7"
"recorder-core": "^1.3.23122400"
} }
} }

15
im-uniapp/pages/chat/chat-box.vue

@ -10,7 +10,7 @@
upper-threshold="200" @scrolltoupper="onScrollToTop" upper-threshold="200" @scrolltoupper="onScrollToTop"
:scroll-into-view="'chat-item-'+scrollMsgIdx"> :scroll-into-view="'chat-item-'+scrollMsgIdx">
<view v-for="(msgInfo,idx) in chat.messages" :key="idx"> <view v-for="(msgInfo,idx) in chat.messages" :key="idx">
<chat-message-item v-if="idx>=showMinIdx" :headImage="headImage(msgInfo)" @call="onRtCall(msgInfo)" <chat-message-item v-if="idx>=showMinIdx&&!msgInfo.delete" :headImage="headImage(msgInfo)" @call="onRtCall(msgInfo)"
:showName="showName(msgInfo)" @recall="onRecallMessage" @delete="onDeleteMessage" :showName="showName(msgInfo)" @recall="onRecallMessage" @delete="onDeleteMessage"
@longPressHead="onLongPressHead(msgInfo)" @download="onDownloadFile" :id="'chat-item-'+idx" @longPressHead="onLongPressHead(msgInfo)" @download="onDownloadFile" :id="'chat-item-'+idx"
:msgInfo="msgInfo" :groupMembers="groupMembers"> :msgInfo="msgInfo" :groupMembers="groupMembers">
@ -544,8 +544,14 @@
}); });
}, },
readedMessage() { readedMessage() {
if(this.unreadCount == 0){
console.log("0000000000")
return;
}
let url = ""
if (this.chat.type == "GROUP") { if (this.chat.type == "GROUP") {
var url = `/message/group/readed?groupId=${this.chat.targetId}` url = `/message/group/readed?groupId=${this.chat.targetId}`
} else { } else {
url = `/message/private/readed?friendId=${this.chat.targetId}` url = `/message/private/readed?friendId=${this.chat.targetId}`
} }
@ -565,7 +571,6 @@
this.group = group; this.group = group;
this.$store.commit("updateChatFromGroup", group); this.$store.commit("updateChatFromGroup", group);
this.$store.commit("updateGroup", group); this.$store.commit("updateGroup", group);
}); });
this.$http({ this.$http({
@ -660,8 +665,6 @@
// 20 // 20
let size = this.chat.messages.length; let size = this.chat.messages.length;
this.showMinIdx = size > 20 ? size - 20 : 0; this.showMinIdx = size > 20 ? size - 20 : 0;
//
this.$store.commit("activeChat", options.chatIdx);
// //
this.readedMessage() this.readedMessage()
// //
@ -671,6 +674,8 @@
this.loadFriend(this.chat.targetId); this.loadFriend(this.chat.targetId);
this.loadReaded(this.chat.targetId) this.loadReaded(this.chat.targetId)
} }
//
this.$store.commit("activeChat", options.chatIdx);
// //
this.isReceipt = false; this.isReceipt = false;
}, },

40
im-uniapp/pages/chat/chat.vue

@ -10,12 +10,14 @@
温馨提示您现在还没有任何聊天消息快跟您的好友发起聊天吧~ 温馨提示您现在还没有任何聊天消息快跟您的好友发起聊天吧~
</view> </view>
<scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" v-else scroll-with-animation="true" scroll-y="true">
<view v-for="(chat,index) in chatStore.chats" :key="index"> <view v-for="(chatPos,i) in chatsPos" :key="i">
<chat-item :chat="chat" :index="index" @longpress.native="onShowMenu($event,index)"></chat-item> <chat-item v-if="!chatStore.chats[chatPos.idx].delete" :chat="chatStore.chats[chatPos.idx]"
:active="menu.chatIdx==chatPos.idx" :index="chatPos.idx"
@longpress.native="onShowMenu($event,chatPos.idx)"></chat-item>
</view> </view>
</scroll-view> </scroll-view>
<pop-menu v-show="menu.show" :menu-style="menu.style" :items="menu.items" @close="menu.show=false" <pop-menu v-show="menu.show" :menu-style="menu.style" :items="menu.items" @close="onCloseMenu()"
@select="onSelectMenu"></pop-menu> @select="onSelectMenu"></pop-menu>
</view> </view>
</template> </template>
@ -30,12 +32,12 @@
chatIdx: -1, chatIdx: -1,
items: [{ items: [{
key: 'DELETE', key: 'DELETE',
name: '删除', name: '删除该聊天',
icon: 'trash' icon: 'trash'
}, },
{ {
key: 'TOP', key: 'TOP',
name: '置顶', name: '置顶该聊天',
icon: 'arrow-up' icon: 'arrow-up'
} }
] ]
@ -57,6 +59,7 @@
this.menu.show = false; this.menu.show = false;
}, },
onShowMenu(e, chatIdx) { onShowMenu(e, chatIdx) {
this.menu.chatIdx = chatIdx;
uni.getSystemInfo({ uni.getSystemInfo({
success: (res) => { success: (res) => {
let touches = e.touches[0]; let touches = e.touches[0];
@ -81,6 +84,10 @@
} }
}) })
}, },
onCloseMenu() {
this.menu.chatIdx = -1;
this.menu.show = false;
},
removeChat(chatIdx) { removeChat(chatIdx) {
this.$store.commit("removeChat", chatIdx); this.$store.commit("removeChat", chatIdx);
}, },
@ -103,13 +110,30 @@
} }
}, },
computed: { computed: {
chatsPos() {
//
let chatsPos = [];
let chats = this.chatStore.chats;
chats.forEach((chat, idx) => {
chatsPos.push({
idx: idx,
sendTime: chat.lastSendTime
})
})
chatsPos.sort((chatPos1, chatPos2) => {
return chatPos2.sendTime - chatPos1.sendTime;
});
return chatsPos;
},
chatStore() { chatStore() {
return this.$store.state.chatStore; return this.$store.state.chatStore;
}, },
unreadCount() { unreadCount() {
let count = 0; let count = 0;
this.chatStore.chats.forEach(chat => { this.chatStore.chats.forEach(chat => {
if (!chat.delete) {
count += chat.unreadCount; count += chat.unreadCount;
}
}) })
return count; return count;
}, },
@ -147,10 +171,16 @@
.chat-loading { .chat-loading {
display: block; display: block;
width: 100%;
height: 100rpx; height: 100rpx;
background: white; background: white;
position: relative; position: relative;
color: blue; color: blue;
.loading-box {
position: relative;
}
} }
.scroll-bar { .scroll-bar {

5
im-uniapp/pages/common/user-info.vue

@ -55,8 +55,9 @@
headImage: this.userInfo.headImage, headImage: this.userInfo.headImage,
}; };
this.$store.commit("openChat", chat); this.$store.commit("openChat", chat);
let chatIdx = this.$store.getters.findChatIdx(chat);
uni.navigateTo({ uni.navigateTo({
url:"/pages/chat/chat-box?chatIdx=0" url:"/pages/chat/chat-box?chatIdx=" + chatIdx
}) })
}, },
onAddFriend() { onAddFriend() {
@ -130,7 +131,7 @@
}, },
computed: { computed: {
isFriend() { isFriend() {
return this.friendInfo != undefined; return this.friendInfo&&!this.friendInfo.delete;
}, },
friendInfo(){ friendInfo(){
let friends = this.$store.state.friendStore.friends; let friends = this.$store.state.friendStore.friends;

2
im-uniapp/pages/friend/friend-add.vue

@ -70,7 +70,7 @@
isFriend(userId) { isFriend(userId) {
let friends = this.$store.state.friendStore.friends; let friends = this.$store.state.friendStore.friends;
let friend = friends.find((f) => f.id == userId); let friend = friends.find((f) => f.id == userId);
return friend != undefined; return friend&&!friend.delete;
} }
} }
} }

5
im-uniapp/pages/friend/friend-search.vue

@ -5,8 +5,9 @@
</view> </view>
<view class="friend-items"> <view class="friend-items">
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="(friend,index) in $store.state.friendStore.friends" v-show="searchText && friend.nickName.startsWith(searchText)" :key="index"> <view v-for="(friend,index) in $store.state.friendStore.friends" :key="index">
<friend-item :friend="friend" :index="index"></friend-item> <friend-item v-if="searchText&&!friend.delete&&friend.nickName.startsWith(searchText)"
:friend="friend" :index="index"></friend-item>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>

17
im-uniapp/pages/friend/friend.vue

@ -8,13 +8,18 @@
<uni-icons type="personadd" size="30"></uni-icons> <uni-icons type="personadd" size="30"></uni-icons>
</view> </view>
</view> </view>
<view class="friend-tip" v-if="$store.state.friendStore.friends.length==0"> <view class="friend-tip" v-if="friends.length==0">
温馨提示您现在还没有任何好友快点击右上方'+'按钮添加好友吧~ 温馨提示您现在还没有任何好友快点击右上方'+'按钮添加好友吧~
</view> </view>
<view class="friend-items" v-else> <view class="friend-items" v-else>
<scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true"> <scroll-view class="scroll-bar" scroll-with-animation="true" scroll-y="true">
<view v-for="(friend,index) in $store.state.friendStore.friends" :key="index"> <!-- 先展示在线好友-->
<friend-item :friend="friend"></friend-item> <view v-for="(friend,index) in friends" :key="index">
<friend-item v-if="!friend.delete&&friend.online" :friend="friend"></friend-item>
</view>
<!-- 再展示离线好友-->
<view v-for="(friend,index) in friends" :key="index">
<friend-item v-if="!friend.delete&&!friend.online" :friend="friend"></friend-item>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
@ -40,8 +45,12 @@
url: "/pages/friend/friend-add" url: "/pages/friend/friend-add"
}) })
} }
},
computed:{
friends(){
return this.$store.state.friendStore.friends;
}
} }
} }
</script> </script>

3
im-uniapp/pages/group/group-info.vue

@ -86,8 +86,9 @@
headImage: this.group.headImage, headImage: this.group.headImage,
}; };
this.$store.commit("openChat", chat); this.$store.commit("openChat", chat);
let chatIdx = this.$store.getters.findChatIdx(chat);
uni.navigateTo({ uni.navigateTo({
url: "/pages/chat/chat-box?chatIdx=0" url: "/pages/chat/chat-box?chatIdx=" + chatIdx
}) })
}, },
onQuitGroup() { onQuitGroup() {

3
im-uniapp/pages/group/group-invite.vue

@ -84,6 +84,9 @@
this.friendItems = []; this.friendItems = [];
let friends = this.$store.state.friendStore.friends; let friends = this.$store.state.friendStore.friends;
friends.forEach((f => { friends.forEach((f => {
if(f.delete){
return
}
let item = { let item = {
id: f.id, id: f.id,
headImage: f.headImage, headImage: f.headImage,

69
im-uniapp/store/chatStore.js

@ -3,14 +3,20 @@ import {
MESSAGE_STATUS MESSAGE_STATUS
} from '@/common/enums.js'; } from '@/common/enums.js';
import userStore from './userStore'; import userStore from './userStore';
/*
uniapp性能优化
1.由于uniapp渲染消息性能非常拉胯,所以先把离线消息存储到cacheChats,
待所有离线消息拉取完成后再统一进行渲染
2.在vuex中对数组进行unshift,splice特别卡所以删除会话会话置顶
除消息等操作进行优化不通过unshift,splice实现改造方案如下
删除会话 通过delete标志判断是否删除
删除消息通过delete标志判断是否删除
会话置顶通过lastSendTime排序确定会话顺序
*/
/* uniapp线cacheChats,
等待所有离线消息拉取完成后再统一进行渲染 */
let cacheChats = []; let cacheChats = [];
export default { export default {
state: { state: {
activeIndex: -1,
chats: [], chats: [],
privateMsgMaxId: 0, privateMsgMaxId: 0,
groupMsgMaxId: 0, groupMsgMaxId: 0,
@ -20,14 +26,19 @@ export default {
mutations: { mutations: {
initChats(state, chatsData) { initChats(state, chatsData) {
cacheChats = [];
for (let chat of chatsData.chats) {
// 已删除的会话直接丢弃
if (chat.delete) {
continue;
}
// 暂存至缓冲区 // 暂存至缓冲区
cacheChats = JSON.parse(JSON.stringify(chatsData.chats)) cacheChats.push(JSON.parse(JSON.stringify(chat)));
// 只取前10条数据做做样子,一切都为了加快初始化时间 // 加载期间显示只前15个会话做做样子,一切都为了加快初始化时间
let size = Math.min(chatsData.chats.length,10); if (state.chats.length < 15) {
for (let i = 0; i < size; i++) {
let chat = chatsData.chats[i];
chat.messages = []; chat.messages = [];
state.chats[i] = chat; state.chats.push(chat);
}
} }
state.privateMsgMaxId = chatsData.privateMsgMaxId || 0; state.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
state.groupMsgMaxId = chatsData.groupMsgMaxId || 0; state.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
@ -48,6 +59,7 @@ export default {
if (chats[idx].type == chatInfo.type && if (chats[idx].type == chatInfo.type &&
chats[idx].targetId === chatInfo.targetId) { chats[idx].targetId === chatInfo.targetId) {
chat = chats[idx]; chat = chats[idx];
chat.delete = false;
// 放置头部 // 放置头部
this.commit("moveTop", idx) this.commit("moveTop", idx)
break; break;
@ -65,15 +77,15 @@ export default {
unreadCount: 0, unreadCount: 0,
messages: [], messages: [],
atMe: false, atMe: false,
atAll: false atAll: false,
delete: false
}; };
chats.unshift(chat); chats.push(chat);
this.commit("moveTop", chats.length - 1)
} }
this.commit("saveToStorage");
}, },
activeChat(state, idx) { activeChat(state, idx) {
let chats = this.getters.findChats(); let chats = this.getters.findChats();
state.activeIndex = idx;
if (idx >= 0) { if (idx >= 0) {
chats[idx].unreadCount = 0; chats[idx].unreadCount = 0;
} }
@ -109,7 +121,7 @@ export default {
}, },
removeChat(state, idx) { removeChat(state, idx) {
let chats = this.getters.findChats(); let chats = this.getters.findChats();
chats.splice(idx, 1); chats[idx].delete = true;
this.commit("saveToStorage"); this.commit("saveToStorage");
}, },
removePrivateChat(state, userId) { removePrivateChat(state, userId) {
@ -122,17 +134,11 @@ export default {
} }
}, },
moveTop(state, idx) { moveTop(state, idx) {
// 加载中不移动,防止卡顿
if (this.getters.isLoading()) {
return;
}
let chats = this.getters.findChats(); let chats = this.getters.findChats();
if (idx > 0) {
let chat = chats[idx]; let chat = chats[idx];
chats.splice(idx, 1); // 最新的时间会显示在顶部
chats.unshift(chat); chat.lastSendTime = new Date().getTime();
this.commit("saveToStorage"); this.commit("saveToStorage");
}
}, },
insertMessage(state, msgInfo) { insertMessage(state, msgInfo) {
// 获取对方id或群id // 获取对方id或群id
@ -233,13 +239,13 @@ export default {
for (let idx in chat.messages) { for (let idx in chat.messages) {
// 已经发送成功的,根据id删除 // 已经发送成功的,根据id删除
if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) {
chat.messages.splice(idx, 1); chat.messages[idx].delete = true;
break; break;
} }
// 正在发送中的消息可能没有id,根据发送时间删除 // 正在发送中的消息可能没有id,根据发送时间删除
if (msgInfo.selfSend && chat.messages[idx].selfSend && if (msgInfo.selfSend && chat.messages[idx].selfSend &&
chat.messages[idx].sendTime == msgInfo.sendTime) { chat.messages[idx].sendTime == msgInfo.sendTime) {
chat.messages.splice(idx, 1); chat.messages[idx].delete = true;
break; break;
} }
} }
@ -271,24 +277,23 @@ export default {
}, },
loadingPrivateMsg(state, loadding) { loadingPrivateMsg(state, loadding) {
state.loadingPrivateMsg = loadding; state.loadingPrivateMsg = loadding;
if (!state.loadingPrivateMsg && !state.loadingGroupMsg) { if (!this.getters.isLoading()) {
this.commit("refreshChats") this.commit("refreshChats")
} }
}, },
loadingGroupMsg(state, loadding) { loadingGroupMsg(state, loadding) {
state.loadingGroupMsg = loadding; state.loadingGroupMsg = loadding;
if (!state.loadingPrivateMsg && !state.loadingGroupMsg) { if (!this.getters.isLoading()) {
this.commit("refreshChats") this.commit("refreshChats")
} }
}, },
refreshChats(state) { refreshChats(state) {
// 排序 // 排序
cacheChats.sort((chat1, chat2) => { cacheChats.sort((chat1, chat2) => {
return chat2.lastSendTime - chat1.lastSendTime; return chat2.lastSendTime - chat1.lastSendTime;
}); });
// 将消息一次性装载回来,只显示前30个会话,多了卡的不行 // 将消息一次性装载回来
state.chats = JSON.parse(JSON.stringify(cacheChats.slice(0,30))) state.chats = cacheChats;
this.commit("saveToStorage"); this.commit("saveToStorage");
}, },
saveToStorage(state) { saveToStorage(state) {
@ -305,12 +310,12 @@ export default {
} }
uni.setStorage({ uni.setStorage({
key: key, key: key,
data: chatsData data: chatsData ,
}) })
}, },
clear(state) { clear(state) {
cacheChats = [];
state.chats = []; state.chats = [];
state.activeIndex = -1;
state.privateMsgMaxId = 0; state.privateMsgMaxId = 0;
state.groupMsgMaxId = 0; state.groupMsgMaxId = 0;
state.loadingPrivateMsg = false; state.loadingPrivateMsg = false;

51
im-uniapp/store/friendStore.js

@ -13,7 +13,7 @@ export default {
}, },
updateFriend(state, friend) { updateFriend(state, friend) {
state.friends.forEach((f, index) => { state.friends.forEach((f, index) => {
if (f.id == friend.id) { if (!f.delete && f.id == friend.id) {
// 拷贝属性 // 拷贝属性
let online = state.friends[index].online; let online = state.friends[index].online;
Object.assign(state.friends[index], friend); Object.assign(state.friends[index], friend);
@ -22,40 +22,24 @@ export default {
}) })
}, },
removeFriend(state, id) { removeFriend(state, id) {
state.friends.forEach((f, idx) => { let friend = this.getters.findFriend(id);
if (f.id == id) { if(friend){
state.friends.splice(idx, 1) friend.delete = true;
} }
});
}, },
addFriend(state, friend) { addFriend(state, friend) {
let f = this.getters.findFriend(friend.id);
if(f){
Object.assign(f, friend);
f.delete = false;
}else{
state.friends.push(friend); state.friends.push(friend);
}
}, },
setOnlineStatus(state, onlineUsers) {
setOnlineStatus(state, onlineTerminals) {
state.friends.forEach((f) => { state.friends.forEach((f) => {
let userTerminal = onlineTerminals.find((o) => f.id == o.userId); let onlineUser = onlineUsers.find((o) => f.id == o.userId);
if (userTerminal) { f.online = !!onlineUser
f.online = true;
f.onlineTerminals = userTerminal.terminals;
f.onlineWeb = userTerminal.terminals.indexOf(TERMINAL_TYPE.WEB) >= 0
f.onlineApp = userTerminal.terminals.indexOf(TERMINAL_TYPE.APP) >= 0
} else {
f.online = false;
f.onlineTerminals = [];
f.onlineWeb = false;
f.onlineApp = false;
}
});
state.friends.sort((f1, f2) => {
if (f1.online && !f2.online) {
return -1;
}
if (f2.online && !f1.online) {
return 1;
}
return 0;
}); });
}, },
refreshOnlineStatus(state) { refreshOnlineStatus(state) {
@ -67,8 +51,8 @@ export default {
http({ http({
url: '/user/terminal/online?userIds=' + userIds.join(','), url: '/user/terminal/online?userIds=' + userIds.join(','),
method: 'GET' method: 'GET'
}).then((onlineTerminals) => { }).then((onlineUsers) => {
this.commit("setOnlineStatus", onlineTerminals); this.commit("setOnlineStatus", onlineUsers);
}) })
} }
// 30s后重新拉取 // 30s后重新拉取
@ -98,5 +82,10 @@ export default {
}) })
}); });
} }
},
getters:{
findFriend: (state) => (id) => {
return state.friends.find((f)=>f.id==id);
}
} }
} }
Loading…
Cancel
Save