From ab9763fd94f72053034e16ee7e7ef32ed7908815 Mon Sep 17 00:00:00 2001 From: xsx <825657193@qq.com> Date: Fri, 30 May 2025 17:30:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=9E=E5=88=B0=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=BA=95=E9=83=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- im-uniapp/pages/chat/chat-box.vue | 65 ++++++++--- im-web/src/components/chat/ChatBox.vue | 146 +++++++++++++++---------- 2 files changed, 140 insertions(+), 71 deletions(-) diff --git a/im-uniapp/pages/chat/chat-box.vue b/im-uniapp/pages/chat/chat-box.vue index 9ca2d61..8875d3d 100644 --- a/im-uniapp/pages/chat/chat-box.vue +++ b/im-uniapp/pages/chat/chat-box.vue @@ -15,6 +15,9 @@ + + {{ newMessageSize > 0 ? newMessageSize+'条新消息' :'回到底部'}} +   @@ -140,7 +143,9 @@ export default { isEmpty: true, // 编辑器是否为空 isFocus: false, // 编辑器是否焦点 isReadOnly: false, // 编辑器是否只读 - playingAudio: null // 当前正在播放的录音消息 + playingAudio: null, // 当前正在播放的录音消息 + isInBottom: true, // 滚动条是否在底部 + newMessageSize: 0 // 滚动条不在底部时新的消息数量 } }, methods: { @@ -561,17 +566,32 @@ export default { } }); }, + onClickToBottom() { + this.scrollToBottom(); + // 有些设备滚到底部时会莫名触发滚动到顶部的事件 + // 所以这里延迟100s保证能准确设置底部标志 + setTimeout(() => { + this.isInBottom = true; + this.newMessageSize = 0; + }, 100) + }, onScrollToTop() { - if (this.showMinIdx == 0) { - console.log("消息已滚动到顶部") - return; + console.log("onScrollToTop") + if (this.showMinIdx > 0) { + // #ifndef H5 + // 防止滚动条定格在顶部,不能一直往上滚 + this.scrollToMsgIdx(this.showMinIdx); + // #endif + // 多展示20条信息 + this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0; } - // #ifndef H5 - // 防止滚动条定格在顶部,不能一直往上滚 - this.scrollToMsgIdx(this.showMinIdx); - // #endif - // 多展示20条信息 - this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0; + // 清除底部标识 + this.isInBottom = false; + }, + onScrollToBottom(e) { + // 设置底部标识 + this.isInBottom = true; + this.newMessageSize = 0; }, onShowMore() { if (this.chat.type == "GROUP") { @@ -639,7 +659,6 @@ export default { method: 'PUT' }).then(() => { this.chatStore.resetUnreadCount(this.chat) - this.scrollToBottom(); }) }, loadGroup(groupId) { @@ -907,12 +926,12 @@ export default { messageSize: function(newSize, oldSize) { // 接收到消息时滚动到底部 if (newSize > oldSize) { - let pages = getCurrentPages(); - let curPage = pages[pages.length - 1].route; - if (curPage == "pages/chat/chat-box") { + if (this.isInBottom) { + // 收到消息,则滚动至底部 this.scrollToBottom(); } else { - this.needScrollToBottom = true; + // 若滚动条不在底部,说明用户正在翻历史消息,此时滚动条不能动,同时增加新消息提示 + this.newMessageSize++; } } }, @@ -949,7 +968,8 @@ export default { // 计算聊天窗口高度 this.$nextTick(() => { this.windowHeight = uni.getSystemInfoSync().windowHeight; - this.reCalChatMainHeight() + this.reCalChatMainHeight(); + this.scrollToBottom(); // #ifdef H5 this.initHeight = window.innerHeight; // 兼容ios的h5:禁止页面滚动 @@ -1025,6 +1045,19 @@ export default { .scroll-box { height: 100%; } + + .scroll-to-bottom { + position: absolute; + right: 30rpx; + bottom: 30rpx; + font-size: $im-font-size; + color: $im-color-primary; + font-weight: 600; + background: white; + padding: 10rpx 30rpx; + border-radius: 25rpx; + box-shadow: $im-box-shadow-dark; + } } .chat-at-bar { diff --git a/im-web/src/components/chat/ChatBox.vue b/im-web/src/components/chat/ChatBox.vue index b5b2cd9..55788db 100644 --- a/im-web/src/components/chat/ChatBox.vue +++ b/im-web/src/components/chat/ChatBox.vue @@ -22,6 +22,9 @@ +
+ {{ newMessageSize > 0 ? newMessageSize + '条新消息' : '回到底部' }} +
20 ? this.showMinIdx - 20 : 0; + this.isInBottom = false; + } + // 滚到底部 + if (scrollTop + scrollElement.clientHeight >= scrollElement.scrollHeight - 30) { + this.isInBottom = true; + this.newMessageSize = 0; } }, showEmotionBox() { @@ -729,8 +740,13 @@ export default { messageSize: { handler(newSize, oldSize) { if (newSize > oldSize) { - // 拉至底部 - this.scrollToBottom(); + if (this.isInBottom) { + // 拉至底部 + this.scrollToBottom(); + } else { + // 增加新消息提醒 + this.newMessageSize++; + } } } } @@ -767,72 +783,92 @@ export default { } } - .im-chat-main { - padding: 0; - background-color: #fff; + .content-box { + position: relative; + + .im-chat-main { + padding: 0; + background-color: #fff; - .im-chat-box { - >ul { - padding: 0 20px; + .im-chat-box { + >ul { + padding: 0 20px; - li { - list-style-type: none; + li { + list-style-type: none; + } } } } - } - .im-chat-footer { - display: flex; - flex-direction: column; - padding: 0; + .scroll-to-bottom { + text-align: right; + position: absolute; + right: 20px; + bottom: 230px; + color: var(--im-color-primary); + font-size: var(--im-font-size); + font-weight: 600; + background: #eee; + padding: 5px 15px; + border-radius: 15px; + cursor: pointer; + z-index: 99; + box-shadow: var(--im-box-shadow-light); + } - .chat-tool-bar { + .im-chat-footer { display: flex; - position: relative; - width: 100%; - height: 36px; - text-align: left; - box-sizing: border-box; - border-top: var(--im-border); - padding: 4px 2px 2px 8px; + flex-direction: column; + padding: 0; + + .chat-tool-bar { + display: flex; + position: relative; + width: 100%; + height: 36px; + text-align: left; + box-sizing: border-box; + border-top: var(--im-border); + padding: 4px 2px 2px 8px; - >div { - font-size: 22px; - cursor: pointer; - line-height: 30px; - width: 30px; - height: 30px; - text-align: center; - border-radius: 2px; - margin-right: 8px; - color: #999; - transition: 0.3s; + >div { + font-size: 22px; + cursor: pointer; + line-height: 30px; + width: 30px; + height: 30px; + text-align: center; + border-radius: 2px; + margin-right: 8px; + color: #999; + transition: 0.3s; - &.chat-tool-active { - font-weight: 600; - color: var(--im-color-primary); - background-color: #ddd; + &.chat-tool-active { + font-weight: 600; + color: var(--im-color-primary); + background-color: #ddd; + } } - } - >div:hover { - color: #333; + >div:hover { + color: #333; + } } - } - .send-content-area { - position: relative; - display: flex; - flex-direction: column; - height: 100%; - background-color: white !important; + .send-content-area { + position: relative; + display: flex; + flex-direction: column; + height: 100%; + background-color: white !important; - .send-btn-area { - padding: 10px; - position: absolute; - bottom: 4px; - right: 6px; + .send-btn-area { + padding: 10px; + position: absolute; + bottom: 4px; + right: 6px; + } } } }