|
|
|
@ -4,15 +4,17 @@ |
|
|
|
<view class="chat-main-box" :style="{height: chatMainHeight+'px'}"> |
|
|
|
<view class="chat-message" @click="switchChatTabBox('none')"> |
|
|
|
<scroll-view class="scroll-box" scroll-y="true" upper-threshold="200" @scrolltoupper="onScrollToTop" |
|
|
|
:scroll-into-view="'chat-item-' + scrollMsgIdx"> |
|
|
|
<view v-if="chat" v-for="(msgInfo, idx) in chat.messages" :key="idx"> |
|
|
|
<chat-message-item :ref="'message'+msgInfo.id" v-if="idx >= showMinIdx" |
|
|
|
:headImage="headImage(msgInfo)" @call="onRtCall(msgInfo)" :showName="showName(msgInfo)" |
|
|
|
@recall="onRecallMessage" @delete="onDeleteMessage" @copy="onCopyMessage" |
|
|
|
@longPressHead="onLongPressHead(msgInfo)" @download="onDownloadFile" |
|
|
|
@audioStateChange="onAudioStateChange" :id="'chat-item-' + idx" :msgInfo="msgInfo" |
|
|
|
:groupMembers="groupMembers"> |
|
|
|
</chat-message-item> |
|
|
|
@scroll="onScroll" :scroll-into-view="'chat-item-' + scrollMsgIdx" :scroll-top="scrollTop"> |
|
|
|
<view v-if="chat" class="chat-wrap"> |
|
|
|
<view v-for="(msgInfo, idx) in chat.messages" :key="idx"> |
|
|
|
<chat-message-item :ref="'message'+msgInfo.id" v-if="idx >= showMinIdx" |
|
|
|
:headImage="headImage(msgInfo)" @call="onRtCall(msgInfo)" :showName="showName(msgInfo)" |
|
|
|
@recall="onRecallMessage" @delete="onDeleteMessage" @copy="onCopyMessage" |
|
|
|
@longPressHead="onLongPressHead(msgInfo)" @download="onDownloadFile" |
|
|
|
@audioStateChange="onAudioStateChange" :id="'chat-item-' + idx" :msgInfo="msgInfo" |
|
|
|
:groupMembers="groupMembers"> |
|
|
|
</chat-message-item> |
|
|
|
</view> |
|
|
|
</view> |
|
|
|
</scroll-view> |
|
|
|
<view v-if="!isInBottom" class="scroll-to-bottom" @click="onClickToBottom"> |
|
|
|
@ -129,12 +131,11 @@ export default { |
|
|
|
scrollMsgIdx: 0, // 滚动条定位为到哪条消息 |
|
|
|
chatTabBox: 'none', |
|
|
|
showRecord: false, |
|
|
|
chatMainHeight: 0, // 聊天窗口高度 |
|
|
|
chatMainHeight: 800, // 聊天窗口高度 |
|
|
|
keyboardHeight: 290, // 键盘高度 |
|
|
|
windowHeight: 1000, // 窗口高度 |
|
|
|
initHeight: 1000, // h5初始高度 |
|
|
|
atUserIds: [], |
|
|
|
needScrollToBottom: false, // 需要滚动到底部 |
|
|
|
showMinIdx: 0, // 下标小于showMinIdx的消息不显示,否则可能很卡 |
|
|
|
reqQueue: [], // 请求队列 |
|
|
|
isSending: false, // 是否正在发送请求 |
|
|
|
@ -145,7 +146,9 @@ export default { |
|
|
|
isReadOnly: false, // 编辑器是否只读 |
|
|
|
playingAudio: null, // 当前正在播放的录音消息 |
|
|
|
isInBottom: true, // 滚动条是否在底部 |
|
|
|
newMessageSize: 0 // 滚动条不在底部时新的消息数量 |
|
|
|
newMessageSize: 0, // 滚动条不在底部时新的消息数量 |
|
|
|
scrollTop: 0, // 用于ios h5定位滚动条 |
|
|
|
scrollViewHeight: 0 // 滚动条总长度 |
|
|
|
} |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
@ -575,13 +578,20 @@ export default { |
|
|
|
this.newMessageSize = 0; |
|
|
|
}, 100) |
|
|
|
}, |
|
|
|
onScroll(e) { |
|
|
|
// 记录当前滚动条高度 |
|
|
|
this.scrollViewHeight = e.detail.scrollHeight; |
|
|
|
}, |
|
|
|
onScrollToTop() { |
|
|
|
console.log("onScrollToTop") |
|
|
|
if (this.showMinIdx > 0) { |
|
|
|
// #ifndef H5 |
|
|
|
// 防止滚动条定格在顶部,不能一直往上滚 |
|
|
|
// #ifndef H5 |
|
|
|
// 防止滚动条定格在顶部,不能一直往上滚,app和小程序采用scroll-into-view定位 |
|
|
|
this.scrollToMsgIdx(this.showMinIdx); |
|
|
|
// #endif |
|
|
|
// #ifdef H5 |
|
|
|
// 防止滚动条定格在顶部,不能一直往上滚,h5采用scroll-top定位 |
|
|
|
this.holdingScrollBar(this.scrollViewHeight); |
|
|
|
// #endif |
|
|
|
// 多展示20条信息 |
|
|
|
this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0; |
|
|
|
} |
|
|
|
@ -593,6 +603,20 @@ export default { |
|
|
|
this.isInBottom = true; |
|
|
|
this.newMessageSize = 0; |
|
|
|
}, |
|
|
|
holdingScrollBar(scrollViewHeight) { |
|
|
|
// 内容高度 |
|
|
|
const query = uni.createSelectorQuery().in(this); |
|
|
|
setTimeout(() => { |
|
|
|
query.select('.chat-wrap').boundingClientRect(); |
|
|
|
query.exec(data => { |
|
|
|
this.scrollTop = data[0].height - scrollViewHeight; |
|
|
|
if(this.scrollTop < 10){ |
|
|
|
// 未渲染完成,重试一次 |
|
|
|
this.holdingScrollBar(); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, 50) |
|
|
|
}, |
|
|
|
onShowMore() { |
|
|
|
if (this.chat.type == "GROUP") { |
|
|
|
uni.navigateTo({ |
|
|
|
@ -924,14 +948,17 @@ export default { |
|
|
|
}, |
|
|
|
watch: { |
|
|
|
messageSize: function(newSize, oldSize) { |
|
|
|
// 接收到消息时滚动到底部 |
|
|
|
if (newSize > oldSize) { |
|
|
|
if (this.isInBottom) { |
|
|
|
// 收到消息,则滚动至底部 |
|
|
|
this.scrollToBottom(); |
|
|
|
} else { |
|
|
|
// 若滚动条不在底部,说明用户正在翻历史消息,此时滚动条不能动,同时增加新消息提示 |
|
|
|
this.newMessageSize++; |
|
|
|
// 接收到新消息 |
|
|
|
if (newSize > oldSize && oldSize > 0) { |
|
|
|
let lastMessage = this.chat.messages[newSize - 1]; |
|
|
|
if (this.$msgType.isNormal(lastMessage.type)) { |
|
|
|
if (this.isInBottom) { |
|
|
|
// 收到消息,则滚动至底部 |
|
|
|
this.scrollToBottom(); |
|
|
|
} else { |
|
|
|
// 若滚动条不在底部,说明用户正在翻历史消息,此时滚动条不能动,同时增加新消息提示 |
|
|
|
this.newMessageSize++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
@ -963,6 +990,9 @@ export default { |
|
|
|
this.chatStore.activeChat(options.chatIdx); |
|
|
|
// 复位回执消息 |
|
|
|
this.isReceipt = false; |
|
|
|
// 清空底部标志 |
|
|
|
this.isInBottom = true; |
|
|
|
this.newMessageSize = 0; |
|
|
|
// 监听键盘高度 |
|
|
|
this.listenKeyBoard(); |
|
|
|
// 计算聊天窗口高度 |
|
|
|
@ -982,13 +1012,6 @@ export default { |
|
|
|
}, |
|
|
|
onUnload() { |
|
|
|
this.unListenKeyboard(); |
|
|
|
}, |
|
|
|
onShow() { |
|
|
|
if (this.needScrollToBottom) { |
|
|
|
// 页面滚到底部 |
|
|
|
this.scrollToBottom(); |
|
|
|
this.needScrollToBottom = false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
|