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 1ab6846..f95e34a 100644 --- a/im-uniapp/components/chat-message-item/chat-message-item.vue +++ b/im-uniapp/components/chat-message-item/chat-message-item.vue @@ -118,10 +118,7 @@ export default { }, methods: { onSendFail() { - uni.showToast({ - title: "该消息已发送失败,目前不支持自动重新发送,建议手动重新发送", - icon: "none" - }) + this.$emit("resend", this.msgInfo); }, onPlayAudio() { // 初始化音频播放器 diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue index 0f1e278..be729e1 100644 --- a/im-uniapp/pages/chat/chat-box.vue +++ b/im-uniapp/pages/chat/chat-box.vue @@ -9,10 +9,10 @@ + @resend="onResendMessage" @recall="onRecallMessage" @delete="onDeleteMessage" + @copy="onCopyMessage" @longPressHead="onLongPressHead(msgInfo)" + @download="onDownloadFile" @audioStateChange="onAudioStateChange" + :id="'chat-item-' + idx" :msgInfo="msgInfo" :groupMembers="groupMembers"> @@ -338,10 +338,7 @@ export default { tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; this.chatStore.insertMessage(tmpMessage, chat); - }).finally(() => { - // 滚动到底部 - this.scrollToBottom(); - }); + }) } }) @@ -451,8 +448,6 @@ export default { // 借助file对象保存 file.msgInfo = msgInfo; file.chat = this.chat; - // 滚到最低部 - this.scrollToBottom(); // 更新图片宽高 let chat = this.chat; this.getImageSize(file).then(size => { @@ -511,8 +506,6 @@ export default { // 借助file对象保存 file.msgInfo = msgInfo; file.chat = this.chat; - // 滚到最低部 - this.scrollToBottom(); return true; }, onUploadFileSuccess(file, res) { @@ -536,6 +529,37 @@ export default { msgInfo.status = this.$enums.MESSAGE_STATUS.FAILED; this.chatStore.insertMessage(msgInfo, file.chat); }, + onResendMessage(msgInfo) { + if (msgInfo.type != this.$enums.MESSAGE_TYPE.TEXT) { + uni.showToast({ + title: "该消息不支持自动重新发送,建议手动重新发送", + icon: "none" + }) + return; + } + // 防止发送期间用户切换会话导致串扰 + const chat = this.chat; + // 删除旧消息 + this.chatStore.deleteMessage(msgInfo, chat); + // 重新发送 + msgInfo.temId = this.generateId(); + let tmpMessage = this.buildTmpMessage(msgInfo); + this.chatStore.insertMessage(tmpMessage, chat); + this.moveChatToTop(); + this.sendMessageRequest(msgInfo).then(m => { + // 更新消息 + tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); + tmpMessage.id = m.id; + tmpMessage.status = m.status; + tmpMessage.content = m.content; + this.chatStore.insertMessage(tmpMessage, chat); + }).catch(() => { + // 更新消息 + tmpMessage = JSON.parse(JSON.stringify(tmpMessage)); + tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; + this.chatStore.insertMessage(tmpMessage, chat); + }) + }, onDeleteMessage(msgInfo) { uni.showModal({ title: '删除消息', @@ -996,7 +1020,7 @@ export default { if (newSize > oldSize && oldSize > 0) { let lastMessage = this.chat.messages[newSize - 1]; if (this.$msgType.isNormal(lastMessage.type)) { - if (this.isInBottom) { + if (this.isInBottom || lastMessage.selfSend) { // 收到消息,则滚动至底部 this.scrollToBottom(); } else { diff --git a/im-uniapp/store/chatStore.js b/im-uniapp/store/chatStore.js index 4b0453f..78c0c60 100644 --- a/im-uniapp/store/chatStore.js +++ b/im-uniapp/store/chatStore.js @@ -247,25 +247,33 @@ export default defineStore('chatStore', { } }, deleteMessage(msgInfo, chatInfo) { - // 获取对方id或群id - let chat = this.findChat(chatInfo); let isColdMessage = false; + let chat = this.findChat(chatInfo); + let delIdx = -1; for (let idx in chat.messages) { // 已经发送成功的,根据id删除 if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { - chat.messages.splice(idx, 1); - isColdMessage = idx < chat.hotMinIdx; + delIdx = idx; break; } // 正在发送中的消息可能没有id,只有临时id if (chat.messages[idx].tmpId && chat.messages[idx].tmpId == msgInfo.tmpId) { - chat.messages.splice(idx, 1); - isColdMessage = idx < chat.hotMinIdx; + delIdx = idx; break; } } - chat.stored = false; - this.saveToStorage(isColdMessage); + if (delIdx >= 0) { + chat.messages.splice(delIdx, 1); + if( delIdx < chat.hotMinIdx){ + isColdMessage = true; + chat.hotMinIdx--; + } + if (delIdx < chat.readedMessageIdx) { + chat.readedMessageIdx--; + } + chat.stored = false; + this.saveToStorage(isColdMessage); + } }, recallMessage(msgInfo, chatInfo) { let chat = this.findChat(chatInfo); diff --git a/im-web/src/components/chat/ChatBox.vue b/im-web/src/components/chat/ChatBox.vue index 100e692..62e5490 100644 --- a/im-web/src/components/chat/ChatBox.vue +++ b/im-web/src/components/chat/ChatBox.vue @@ -13,7 +13,8 @@
+ :groupMembers="groupMembers" @resend="onResendMessage" @delete="deleteMessage" + @recall="recallMessage">
@@ -198,8 +199,6 @@ export default { this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); - // 滚动到底部 - this.scrollToBottom(); // 借助file对象保存 file.msgInfo = msgInfo; file.chat = this.chat; @@ -263,8 +262,6 @@ export default { this.chatStore.insertMessage(msgInfo, this.chat); // 会话置顶 this.moveChatToTop(); - // 滚动到底部 - this.scrollToBottom(); // 借助file对象透传 file.msgInfo = msgInfo; file.chat = this.chat; @@ -492,7 +489,6 @@ export default { tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; this.chatStore.insertMessage(tmpMessage, chat); }).finally(() => { - this.scrollToBottom(); this.isReceipt = false; resolve(); }); @@ -506,6 +502,35 @@ export default { } }) }, + onResendMessage(msgInfo) { + if (msgInfo.type != this.$enums.MESSAGE_TYPE.TEXT) { + this.$message.error("该消息不支持自动重新发送,建议手动重新发送") + return; + } + // 防止发送期间用户切换会话导致串扰 + const chat = this.chat; + // 删除旧消息 + this.chatStore.deleteMessage(msgInfo, chat); + // 重新推送 + msgInfo.temId = this.generateId(); + let tmpMessage = this.buildTmpMessage(msgInfo); + this.chatStore.insertMessage(tmpMessage, chat); + this.moveChatToTop(); + // 发送 + this.sendMessageRequest(msgInfo).then(m => { + // 更新消息 + tmpMessage.id = m.id; + tmpMessage.status = m.status; + tmpMessage.content = m.content; + this.chatStore.insertMessage(tmpMessage, chat); + }).catch(() => { + // 更新消息 + tmpMessage.status = this.$enums.MESSAGE_STATUS.FAILED; + this.chatStore.insertMessage(tmpMessage, chat); + }).finally(() => { + this.scrollToBottom(); + }); + }, deleteMessage(msgInfo) { this.$confirm('确认删除消息?', '删除消息', { confirmButtonText: '确定', @@ -797,12 +822,14 @@ export default { messageSize: { handler(newSize, oldSize) { if (newSize > oldSize) { - if (this.isInBottom) { - // 拉至底部 - this.scrollToBottom(); - } else { - // 增加新消息提醒 - this.newMessageSize++; + // 收到普通消息,则滚动至底部 + let lastMessage = this.chat.messages[newSize - 1]; + if (lastMessage && this.$msgType.isNormal(lastMessage.type)) { + if (this.isInBottom || lastMessage.selfSend) { + this.scrollToBottom(); + } else { + this.newMessageSize++; + } } } } diff --git a/im-web/src/components/chat/ChatMessageItem.vue b/im-web/src/components/chat/ChatMessageItem.vue index 068a003..19be0aa 100644 --- a/im-web/src/components/chat/ChatMessageItem.vue +++ b/im-web/src/components/chat/ChatMessageItem.vue @@ -119,7 +119,7 @@ export default { }, methods: { onSendFail() { - this.$message.error("该消息已发送失败,目前不支持自动重新发送,建议手动重新发送") + this.$emit("resend",this.msgInfo); }, showFullImageBox() { let imageUrl = JSON.parse(this.msgInfo.content).originUrl; diff --git a/im-web/src/store/chatStore.js b/im-web/src/store/chatStore.js index 8f4c09d..e672517 100644 --- a/im-web/src/store/chatStore.js +++ b/im-web/src/store/chatStore.js @@ -242,24 +242,33 @@ export default defineStore('chatStore', { } }, deleteMessage(msgInfo, chatInfo) { - let chat = this.findChat(chatInfo); let isColdMessage = false; + let chat = this.findChat(chatInfo); + let delIdx = -1; for (let idx in chat.messages) { // 已经发送成功的,根据id删除 if (chat.messages[idx].id && chat.messages[idx].id == msgInfo.id) { - chat.messages.splice(idx, 1); - isColdMessage = idx < chat.hotMinIdx; + delIdx = idx; break; } // 正在发送中的消息可能没有id,只有临时id if (chat.messages[idx].tmpId && chat.messages[idx].tmpId == msgInfo.tmpId) { - chat.messages.splice(idx, 1); - isColdMessage = idx < chat.hotMinIdx; + delIdx = idx; break; } } - chat.stored = false; - this.saveToStorage(isColdMessage); + if (delIdx >= 0) { + chat.messages.splice(delIdx, 1); + if (delIdx < chat.hotMinIdx) { + isColdMessage = true; + chat.hotMinIdx--; + } + if (delIdx < chat.readedMessageIdx) { + chat.readedMessageIdx--; + } + chat.stored = false; + this.saveToStorage(isColdMessage); + } }, recallMessage(msgInfo, chatInfo) { let chat = this.findChat(chatInfo);