From aac6eb0d1cd48b76544cc13593d55aee458ddab5 Mon Sep 17 00:00:00 2001
From: xsx <825657193@qq.com>
Date: Mon, 15 Apr 2024 23:48:05 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96:=20uniapp=E6=8B=89=E5=8F=96?=
=?UTF-8?q?=E8=BF=87=E5=A4=9A=E7=A6=BB=E7=BA=BF=E6=B6=88=E6=81=AF=E5=AF=BC?=
=?UTF-8?q?=E8=87=B4=E5=8D=A1=E9=A1=BF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
im-ui/src/store/chatStore.js | 7 +-
.../chat-message-item/chat-message-item.vue | 21 +-
im-uniapp/components/pop-menu/pop-menu.vue | 4 +-
im-uniapp/pages/chat/chat-box.vue | 24 +-
im-uniapp/store/chatStore.js | 205 +++++++++---------
5 files changed, 144 insertions(+), 117 deletions(-)
diff --git a/im-ui/src/store/chatStore.js b/im-ui/src/store/chatStore.js
index 9a240be..90e62e6 100644
--- a/im-ui/src/store/chatStore.js
+++ b/im-ui/src/store/chatStore.js
@@ -186,7 +186,12 @@ export default {
}
}
}
- chat.messages.splice(insertPos, 0, msgInfo);
+ if(insertPos == chat.messages.length){
+ // 这种赋值效率最高
+ chat.messages[insertPos]= msgInfo;
+ }else{
+ chat.messages.splice(insertPos, 0, msgInfo);
+ }
this.commit("saveToStorage");
},
updateMessage(state, msgInfo) {
diff --git a/im-uniapp/components/chat-message-item/chat-message-item.vue b/im-uniapp/components/chat-message-item/chat-message-item.vue
index 43dc856..a77b5ab 100644
--- a/im-uniapp/components/chat-message-item/chat-message-item.vue
+++ b/im-uniapp/components/chat-message-item/chat-message-item.vue
@@ -11,16 +11,17 @@
:class="{'chat-msg-mine':msgInfo.selfSend}">
-
+
{{showName}}
-
+
+ :nodes="$emo.transform(msgInfo.content)"
+ @longpress="onShowMenu($event)">
-
+
@@ -30,7 +31,7 @@
class="send-fail iconfont icon-warning-circle-fill">
-
+
@@ -43,13 +44,14 @@
class="send-fail iconfont icon-warning-circle-fill">
+ @click="onPlayAudio()" @longpress="onShowMenu($event)">
{{JSON.parse(msgInfo.content).duration+'"'}}
-
+
{{msgInfo.content}}
@@ -68,7 +70,7 @@
-
@@ -129,6 +131,9 @@
}
})
},
+ onHideMenu(){
+ this.menu.show = false;
+ },
onSendFail() {
uni.showToast({
title: "该文件已发送失败,目前不支持自动重新发送,建议手动重新发送",
diff --git a/im-uniapp/components/pop-menu/pop-menu.vue b/im-uniapp/components/pop-menu/pop-menu.vue
index 8f08c1e..6c18861 100644
--- a/im-uniapp/components/pop-menu/pop-menu.vue
+++ b/im-uniapp/components/pop-menu/pop-menu.vue
@@ -1,11 +1,10 @@
-
@@ -29,6 +28,7 @@
this.$emit("select", item);
},
onClose() {
+ console.log("@touchmove")
this.$emit("close");
}
}
diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue
index ffd421b..a7a2bd5 100644
--- a/im-uniapp/pages/chat/chat-box.vue
+++ b/im-uniapp/pages/chat/chat-box.vue
@@ -6,8 +6,9 @@
-
+
10 ? this.showMinIdx - 10 : 0;
+ // 多展示0条信息
+ this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0;
},
onShowMore() {
if (this.chat.type == "GROUP") {
@@ -649,9 +657,9 @@
onLoad(options) {
// 聊天数据
this.chat = this.$store.state.chatStore.chats[options.chatIdx];
- // 初始状态只显示30条消息
+ // 初始状态只显示20条消息
let size = this.chat.messages.length;
- this.showMinIdx = size > 30 ? size - 30 : 0;
+ this.showMinIdx = size > 20 ? size - 20 : 0;
// 激活当前会话
this.$store.commit("activeChat", options.chatIdx);
// 消息已读
diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js
index 0d9ba68..b8f610f 100644
--- a/im-uniapp/store/chatStore.js
+++ b/im-uniapp/store/chatStore.js
@@ -1,10 +1,14 @@
-import { MESSAGE_TYPE, MESSAGE_STATUS } from '@/common/enums.js';
+import {
+ MESSAGE_TYPE,
+ MESSAGE_STATUS
+} from '@/common/enums.js';
import userStore from './userStore';
export default {
state: {
activeIndex: -1,
chats: [],
+ copyChats: [],
privateMsgMaxId: 0,
groupMsgMaxId: 0,
loadingPrivateMsg: false,
@@ -13,9 +17,9 @@ export default {
mutations: {
initChats(state, chatsData) {
- state.chats = chatsData.chats ||[];
- state.privateMsgMaxId = chatsData.privateMsgMaxId||0;
- state.groupMsgMaxId = chatsData.groupMsgMaxId||0;
+ state.chats = chatsData.chats || [];
+ state.privateMsgMaxId = chatsData.privateMsgMaxId || 0;
+ state.groupMsgMaxId = chatsData.groupMsgMaxId || 0;
// 防止图片一直处在加载中状态
state.chats.forEach((chat) => {
chat.messages.forEach((msg) => {
@@ -24,15 +28,18 @@ export default {
}
})
})
+ // 拷贝一份,用于缓存离线消息
+ state.copyChats = JSON.parse(JSON.stringify(state.chats))
},
openChat(state, chatInfo) {
+ let chats = this.getters.findChats();
let chat = null;
- for (let idx in state.chats) {
- if (state.chats[idx].type == chatInfo.type &&
- state.chats[idx].targetId === chatInfo.targetId) {
- chat = state.chats[idx];
+ for (let idx in chats) {
+ if (chats[idx].type == chatInfo.type &&
+ chats[idx].targetId === chatInfo.targetId) {
+ chat = chats[idx];
// 放置头部
- this.commit("moveTop",idx)
+ this.commit("moveTop", idx)
break;
}
}
@@ -50,38 +57,40 @@ export default {
atMe: false,
atAll: false
};
- state.chats.unshift(chat);
+ chats.unshift(chat);
}
this.commit("saveToStorage");
},
activeChat(state, idx) {
+ let chats = this.getters.findChats();
state.activeIndex = idx;
if (idx >= 0) {
- state.chats[idx].unreadCount = 0;
+ chats[idx].unreadCount = 0;
}
},
resetUnreadCount(state, chatInfo) {
- for (let idx in state.chats) {
- if (state.chats[idx].type == chatInfo.type &&
- state.chats[idx].targetId == chatInfo.targetId) {
- state.chats[idx].unreadCount = 0;
- state.chats[idx].atMe = false;
- state.chats[idx].atAll = false;
+ let chats = this.getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == chatInfo.type &&
+ chats[idx].targetId == chatInfo.targetId) {
+ chats[idx].unreadCount = 0;
+ chats[idx].atMe = false;
+ chats[idx].atAll = false;
}
}
this.commit("saveToStorage");
},
readedMessage(state, pos) {
- for (let idx in state.chats) {
- if (state.chats[idx].type == 'PRIVATE' &&
- state.chats[idx].targetId == pos.friendId) {
- state.chats[idx].messages.forEach((m) => {
+ let chats = this.getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == 'PRIVATE' &&
+ chats[idx].targetId == pos.friendId) {
+ chats[idx].messages.forEach((m) => {
if (m.selfSend && m.status != MESSAGE_STATUS.RECALL) {
// pos.maxId为空表示整个会话已读
- if(!pos.maxId || m.id <= pos.maxId){
+ if (!pos.maxId || m.id <= pos.maxId) {
m.status = MESSAGE_STATUS.READED
}
-
}
})
}
@@ -89,26 +98,25 @@ export default {
this.commit("saveToStorage");
},
removeChat(state, idx) {
- state.chats.splice(idx, 1);
+ let chats = this.getters.findChats();
+ chats.splice(idx, 1);
this.commit("saveToStorage");
},
removePrivateChat(state, userId) {
- for (let idx in state.chats) {
- if (state.chats[idx].type == 'PRIVATE' &&
- state.chats[idx].targetId == userId) {
+ let chats = this.getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == 'PRIVATE' &&
+ chats[idx].targetId == userId) {
this.commit("removeChat", idx);
}
}
},
moveTop(state, idx) {
- // 加载中不移动,很耗性能
- if(state.loadingPrivateMsg || state.loadingGroupMsg){
- return ;
- }
+ let chats = this.getters.findChats();
if (idx > 0) {
- let chat = state.chats[idx];
- state.chats.splice(idx, 1);
- state.chats.unshift(chat);
+ let chat = chats[idx];
+ chats.splice(idx, 1);
+ chats.unshift(chat);
this.commit("saveToStorage");
}
},
@@ -125,46 +133,45 @@ export default {
// 如果是已存在消息,则覆盖旧的消息数据
let chat = this.getters.findChat(msgInfo);
let message = this.getters.findMessage(chat, msgInfo);
- if(message){
+ if (message) {
Object.assign(message, msgInfo);
// 撤回消息需要显示
- if(msgInfo.type == MESSAGE_TYPE.RECALL){
+ if (msgInfo.type == MESSAGE_TYPE.RECALL) {
chat.lastContent = msgInfo.content;
}
this.commit("saveToStorage");
return;
}
// 会话列表内容
- if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
- if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
- chat.lastContent = "[图片]";
- } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
- chat.lastContent = "[文件]";
- } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
- chat.lastContent = "[语音]";
- } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
- chat.lastContent = msgInfo.content;
- } else if (msgInfo.type == MESSAGE_TYPE.RT_VOICE) {
- chat.lastContent = "[语音通话]";
- } else if (msgInfo.type == MESSAGE_TYPE.RT_VIDEO) {
- chat.lastContent = "[视频通话]";
- }
- chat.lastSendTime = msgInfo.sendTime;
- chat.sendNickName = msgInfo.sendNickName;
+ if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
+ chat.lastContent = "[图片]";
+ } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
+ chat.lastContent = "[文件]";
+ } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
+ chat.lastContent = "[语音]";
+ } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
+ chat.lastContent = msgInfo.content;
+ } else if (msgInfo.type == MESSAGE_TYPE.RT_VOICE) {
+ chat.lastContent = "[语音通话]";
+ } else if (msgInfo.type == MESSAGE_TYPE.RT_VIDEO) {
+ chat.lastContent = "[视频通话]";
}
+ chat.lastSendTime = msgInfo.sendTime;
+ chat.sendNickName = msgInfo.sendNickName;
+
// 未读加1
- if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED
- && msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
+ if (!msgInfo.selfSend && msgInfo.status != MESSAGE_STATUS.READED &&
+ msgInfo.type != MESSAGE_TYPE.TIP_TEXT) {
chat.unreadCount++;
}
// 是否有人@我
- if(!msgInfo.selfSend && chat.type=="GROUP" && msgInfo.atUserIds
- && msgInfo.status != MESSAGE_STATUS.READED){
+ if (!msgInfo.selfSend && chat.type == "GROUP" && msgInfo.atUserIds &&
+ msgInfo.status != MESSAGE_STATUS.READED) {
let userId = userStore.state.userInfo.id;
- if(msgInfo.atUserIds.indexOf(userId)>=0){
+ if (msgInfo.atUserIds.indexOf(userId) >= 0) {
chat.atMe = true;
}
- if(msgInfo.atUserIds.indexOf(-1)>=0){
+ if (msgInfo.atUserIds.indexOf(-1) >= 0) {
chat.atAll = true;
}
}
@@ -179,7 +186,7 @@ export default {
// 根据id顺序插入,防止消息乱序
let insertPos = chat.messages.length;
// 防止 图片、文件 在发送方 显示 在顶端 因为还没存库,id=0
- if(msgInfo.id && msgInfo.id > 0){
+ if (msgInfo.id && msgInfo.id > 0 ) {
for (let idx in chat.messages) {
if (chat.messages[idx].id && msgInfo.id < chat.messages[idx].id) {
insertPos = idx;
@@ -188,14 +195,19 @@ export default {
}
}
}
- chat.messages.splice(insertPos, 0, msgInfo);
+ if(insertPos == chat.messages.length){
+ // 这种赋值效率最高
+ chat.messages[insertPos]= msgInfo;
+ }else{
+ chat.messages.splice(insertPos, 0, msgInfo);
+ }
this.commit("saveToStorage");
},
updateMessage(state, msgInfo) {
// 获取对方id或群id
let chat = this.getters.findChat(msgInfo);
let message = this.getters.findMessage(chat, msgInfo);
- if(message){
+ if (message) {
// 属性拷贝
Object.assign(message, msgInfo);
this.commit("saveToStorage");
@@ -220,8 +232,9 @@ export default {
this.commit("saveToStorage");
},
updateChatFromFriend(state, friend) {
- for (let i in state.chats) {
- let chat = state.chats[i];
+ let chats = this.getters.findChats();
+ for (let i in chats) {
+ let chat = chats[i];
if (chat.type == 'PRIVATE' && chat.targetId == friend.id) {
chat.headImage = friend.headImageThumb;
chat.showName = friend.nickName;
@@ -231,8 +244,9 @@ export default {
this.commit("saveToStorage");
},
updateChatFromGroup(state, group) {
- for (let i in state.chats) {
- let chat = state.chats[i];
+ let chats = this.getters.findChats();
+ for (let i in chats) {
+ let chat = chats[i];
if (chat.type == 'GROUP' && chat.targetId == group.id) {
chat.headImage = group.headImageThumb;
chat.showName = group.remark;
@@ -243,40 +257,26 @@ export default {
},
loadingPrivateMsg(state, loadding) {
state.loadingPrivateMsg = loadding;
- if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
+ if (!state.loadingPrivateMsg && !state.loadingGroupMsg) {
this.commit("refreshChats")
}
},
loadingGroupMsg(state, loadding) {
state.loadingGroupMsg = loadding;
- if(!state.loadingPrivateMsg && !state.loadingGroupMsg){
+ if (!state.loadingPrivateMsg && !state.loadingGroupMsg) {
this.commit("refreshChats")
}
},
- refreshChats(state){
- state.chats.forEach((chat)=>{
- if(chat.messages.length>0){
- let msgInfo = chat.messages[chat.messages.length-1];
- if (msgInfo.type == MESSAGE_TYPE.IMAGE) {
- chat.lastContent = "[图片]";
- } else if (msgInfo.type == MESSAGE_TYPE.FILE) {
- chat.lastContent = "[文件]";
- } else if (msgInfo.type == MESSAGE_TYPE.AUDIO) {
- chat.lastContent = "[语音]";
- } else if (msgInfo.type == MESSAGE_TYPE.TEXT || msgInfo.type == MESSAGE_TYPE.RECALL) {
- chat.lastContent = msgInfo.content;
- }
- chat.lastSendTime = msgInfo.sendTime;
- }else{
- chat.lastContent = "";
- chat.lastSendTime = new Date().getTime()
- }
- })
- state.chats.sort((chat1, chat2) => {
- return chat2.lastSendTime-chat1.lastSendTime;
- });
+ refreshChats(state) {
+ // 将离线消息一次性装载回来
+ state.chats = JSON.parse(JSON.stringify(state.copyChats))
+ this.commit("saveToStorage");
},
saveToStorage(state) {
+ // 加载中不保存,防止卡顿
+ if(state.loadingPrivateMsg || state.loadingGroupMsg){
+ return;
+ }
let userId = userStore.state.userInfo.id;
let key = "chats-" + userId;
let chatsData = {
@@ -291,6 +291,7 @@ export default {
},
clear(state) {
state.chats = [];
+ state.copyChats = [];
state.activeIndex = -1;
state.privateMsgMaxId = 0;
state.groupMsgMaxId = 0;
@@ -316,24 +317,32 @@ export default {
}
},
getters: {
- findChatIdx: (state) => (chat) => {
- for (let idx in state.chats) {
- if (state.chats[idx].type == chat.type &&
- state.chats[idx].targetId === chat.targetId) {
+ findChats: (state) => () => {
+ /* uniapp渲染消息性能非常拉胯,所以这里先把离线消息存储到state.copyChats,
+ 等待所有离线消息拉取完成后,再统一进行渲染 */
+ let isLoading = state.loadingPrivateMsg || state.loadingGroupMsg;
+ return isLoading ? state.copyChats : state.chats;
+ },
+ findChatIdx: (state, getters) => (chat) => {
+ let chats = getters.findChats();
+ for (let idx in chats) {
+ if (chats[idx].type == chat.type &&
+ chats[idx].targetId === chat.targetId) {
chat = state.chats[idx];
return idx;
}
}
},
- findChat: (state) => (msgInfo) => {
+ findChat: (state, getters) => (msgInfo) => {
+ let chats = getters.findChats();
// 获取对方id或群id
let type = msgInfo.groupId ? 'GROUP' : 'PRIVATE';
let targetId = msgInfo.groupId ? msgInfo.groupId : msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId;
let chat = null;
- for (let idx in state.chats) {
- if (state.chats[idx].type == type &&
- state.chats[idx].targetId === targetId) {
- chat = state.chats[idx];
+ for (let idx in chats) {
+ if (chats[idx].type == type &&
+ chats[idx].targetId === targetId) {
+ chat = chats[idx];
break;
}
}