// [z-paging]聊天记录模式模块
|
import u from '.././z-paging-utils'
|
|
export default {
|
props: {
|
// 使用聊天记录模式,默认为否
|
useChatRecordMode: {
|
type: Boolean,
|
default: u.gc('useChatRecordMode', false)
|
},
|
// 使用聊天记录模式时滚动到顶部后,列表垂直移动偏移距离。默认0rpx。单位px(暂时无效)
|
chatRecordMoreOffset: {
|
type: [Number, String],
|
default: u.gc('chatRecordMoreOffset', '0rpx')
|
},
|
// 使用聊天记录模式时是否自动隐藏键盘:在用户触摸列表时候自动隐藏键盘,默认为是
|
autoHideKeyboardWhenChat: {
|
type: Boolean,
|
default: u.gc('autoHideKeyboardWhenChat', true)
|
},
|
// 使用聊天记录模式中键盘弹出时是否自动调整slot="bottom"高度,默认为是
|
autoAdjustPositionWhenChat: {
|
type: Boolean,
|
default: u.gc('autoAdjustPositionWhenChat', true)
|
},
|
// 使用聊天记录模式中键盘弹出时占位高度偏移距离。默认0rpx。单位px
|
chatAdjustPositionOffset: {
|
type: [Number, String],
|
default: u.gc('chatAdjustPositionOffset', '0rpx')
|
},
|
// 使用聊天记录模式中键盘弹出时是否自动滚动到底部,默认为否
|
autoToBottomWhenChat: {
|
type: Boolean,
|
default: u.gc('autoToBottomWhenChat', false)
|
},
|
// 使用聊天记录模式中reload时是否显示chatLoading,默认为否
|
showChatLoadingWhenReload: {
|
type: Boolean,
|
default: u.gc('showChatLoadingWhenReload', false)
|
},
|
// 在聊天记录模式中滑动到顶部状态为默认状态时,以加载中的状态展示,默认为是。若设置为否,则默认会显示【点击加载更多】,然后才会显示loading
|
chatLoadingMoreDefaultAsLoading: {
|
type: Boolean,
|
default: u.gc('chatLoadingMoreDefaultAsLoading', true)
|
},
|
},
|
data() {
|
return {
|
// 键盘高度
|
keyboardHeight: 0,
|
// 键盘高度是否未改变,此时占位高度变化不需要动画效果
|
isKeyboardHeightChanged: false,
|
}
|
},
|
computed: {
|
finalChatRecordMoreOffset() {
|
return u.convertToPx(this.chatRecordMoreOffset);
|
},
|
finalChatAdjustPositionOffset() {
|
return u.convertToPx(this.chatAdjustPositionOffset);
|
},
|
// 聊天记录模式旋转180度style
|
chatRecordRotateStyle() {
|
let cellStyle;
|
// 在vue中,直接将列表倒置,因此在vue的cell中,也直接写style="transform: scaleY(-1)"转回来即可。
|
// #ifndef APP-NVUE
|
cellStyle = this.useChatRecordMode ? { transform: 'scaleY(-1)' } : {};
|
// #endif
|
|
// 在nvue中,需要考虑数据量不满一页的情况,因为nvue中的list无法通过flex-end修改不满一页的起始位置,会导致不满一页时列表数据从底部开始,因此需要特别判断
|
// 当数据不满一屏的时候,不进行列表倒置
|
// #ifdef APP-NVUE
|
cellStyle = this.useChatRecordMode ? { transform: this.isFirstPageAndNoMore ? 'scaleY(1)' : 'scaleY(-1)' } : {};
|
// #endif
|
|
this.$emit('update:cellStyle', cellStyle);
|
this.$emit('cellStyleChange', cellStyle);
|
|
// 在聊天记录模式中,如果列表没有倒置并且当前是第一页,则需要自动滚动到最底部
|
this.$nextTick(() => {
|
if (this.isFirstPage && this.isChatRecordModeAndNotInversion) {
|
this.$nextTick(() => {
|
// 这里多次触发滚动到底部是为了避免在某些情况下,即使是在nextTick但是cell未渲染完毕导致滚动到底部位置不正确的问题
|
this._scrollToBottom(false);
|
u.delay(() => {
|
this._scrollToBottom(false);
|
u.delay(() => {
|
this._scrollToBottom(false);
|
}, 50)
|
}, 50)
|
})
|
}
|
})
|
return cellStyle;
|
},
|
// 是否是聊天记录列表并且有配置transform
|
isChatRecordModeHasTransform() {
|
return this.useChatRecordMode && this.chatRecordRotateStyle && this.chatRecordRotateStyle.transform;
|
},
|
// 是否是聊天记录列表并且列表未倒置
|
isChatRecordModeAndNotInversion() {
|
return this.isChatRecordModeHasTransform && this.chatRecordRotateStyle.transform === 'scaleY(1)';
|
},
|
// 是否是聊天记录列表并且列表倒置
|
isChatRecordModeAndInversion() {
|
return this.isChatRecordModeHasTransform && this.chatRecordRotateStyle.transform === 'scaleY(-1)';
|
},
|
// 最终的聊天记录模式中底部安全区域的高度,如果开启了底部安全区域并且键盘未弹出,则添加底部区域高度
|
chatRecordModeSafeAreaBottom() {
|
return this.safeAreaInsetBottom && !this.keyboardHeight ? this.safeAreaBottom : 0;
|
}
|
},
|
mounted() {
|
// 监听键盘高度变化(H5、百度小程序、抖音小程序、飞书小程序不支持)
|
// #ifndef H5 || MP-BAIDU || MP-TOUTIAO
|
if (this.useChatRecordMode) {
|
uni.onKeyboardHeightChange(this._handleKeyboardHeightChange);
|
}
|
// #endif
|
},
|
methods: {
|
// 添加聊天记录
|
addChatRecordData(data, toBottom = true, toBottomWithAnimate = true) {
|
if (!this.useChatRecordMode) return;
|
this.isTotalChangeFromAddData = true;
|
this.addDataFromTop(data, toBottom, toBottomWithAnimate);
|
},
|
// 手动触发滚动到顶部加载更多,聊天记录模式时有效
|
doChatRecordLoadMore() {
|
this.useChatRecordMode && this._onLoadingMore('click');
|
},
|
// 处理键盘高度变化
|
_handleKeyboardHeightChange(res) {
|
this.$emit('keyboardHeightChange', res);
|
if (this.autoAdjustPositionWhenChat) {
|
this.isKeyboardHeightChanged = true;
|
this.keyboardHeight = res.height > 0 ? res.height + this.finalChatAdjustPositionOffset : res.height;
|
}
|
if (this.autoToBottomWhenChat && this.keyboardHeight > 0) {
|
u.delay(() => {
|
this.scrollToBottom(false);
|
u.delay(() => {
|
this.scrollToBottom(false);
|
})
|
})
|
}
|
}
|
}
|
}
|