mirror of
https://github.com/kuaifan/dootask.git
synced 2026-10-30 06:20:44 +00:00
fix(dialog): iOS 加载历史消息改为等手势空闲后再插入,不再断触
- 记录手指触摸与原生滚动状态,iOS 上等手指离开、惯性滚动停止后再插入历史消息并补偿位置 - 加载期间阻止重复触发加载,切换对话后跳过位置补偿 - getDialogMsgs 的 save_before 支持返回 Promise
This commit is contained in:
parent
a1e79204f8
commit
8aac85a40a
@ -7,6 +7,9 @@
|
||||
@dragover.prevent="chatDragOver(true, $event)"
|
||||
@dragleave.prevent="chatDragOver(false, $event)"
|
||||
@touchstart="onTouchStart"
|
||||
@touchstart.capture="onTouchState"
|
||||
@touchend.capture="onTouchState"
|
||||
@touchcancel.capture="onTouchState"
|
||||
@pointerover="onPointerover">
|
||||
<!--顶部导航-->
|
||||
<div ref="nav" class="dialog-nav">
|
||||
@ -210,6 +213,7 @@
|
||||
@totop="onPrevPage"
|
||||
@range="onRange"
|
||||
@visible="onVisible"
|
||||
@scroll.native.passive="onNativeScroll"
|
||||
|
||||
@on-view-reply="onViewReply"
|
||||
@on-view-text="onViewText"
|
||||
@ -2531,6 +2535,35 @@ export default {
|
||||
target.src = imageFailedSrc
|
||||
},
|
||||
|
||||
// 捕获阶段记录是否有手指在屏幕上(子元素如 v-longpress 会阻止 touchend 冒泡)
|
||||
onTouchState({touches}) {
|
||||
this.__touching = !!touches && touches.length > 0
|
||||
},
|
||||
|
||||
onNativeScroll() {
|
||||
this.__scroll_at = Date.now()
|
||||
},
|
||||
|
||||
// iOS 手指按住或惯性滚动(含顶部回弹)时写入 scrollTop 不生效,需等手势结束、滚动停止后再插入历史消息并补偿位置
|
||||
waitScrollIdle() {
|
||||
if (!$A.isIos()) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
const start = Date.now()
|
||||
const check = () => {
|
||||
const el = this.$refs.scroller?.$el
|
||||
const idle = !this.__touching && Date.now() - (this.__scroll_at || 0) >= 150 && (!el || el.scrollTop >= 0)
|
||||
if (idle || this._isDestroyed || Date.now() - start > 10000) {
|
||||
resolve()
|
||||
} else {
|
||||
setTimeout(check, 50)
|
||||
}
|
||||
}
|
||||
check()
|
||||
})
|
||||
},
|
||||
|
||||
onPointerover({pointerType}) {
|
||||
this.pointerMouse = pointerType === 'mouse';
|
||||
},
|
||||
@ -2919,14 +2952,22 @@ export default {
|
||||
if (this.prevId === 0 || this.preventPrevLoad > 0) {
|
||||
return
|
||||
}
|
||||
// 等待手势空闲期间请求已结束,需自行阻止重复加载
|
||||
const dialogId = this.dialogId
|
||||
this.preventPrevLoad++
|
||||
this.getMsgs({
|
||||
dialog_id: this.dialogId,
|
||||
msg_id: this.msgId,
|
||||
msg_type: this.msgType,
|
||||
prev_id: this.prevId,
|
||||
save_before: _ => this.scrollDisabled = true,
|
||||
save_before: _ => this.waitScrollIdle().then(_ => {
|
||||
this.scrollDisabled = true
|
||||
}),
|
||||
save_after: _ => this.scrollDisabled = false
|
||||
}).then(({data}) => {
|
||||
if (dialogId !== this.dialogId) {
|
||||
return
|
||||
}
|
||||
const ids = data.list.map(item => item.id)
|
||||
this.$nextTick(() => {
|
||||
const scroller = this.$refs.scroller
|
||||
@ -2936,7 +2977,9 @@ export default {
|
||||
})
|
||||
this.onToOffset(scroller.getOffset() + reducer.size, true)
|
||||
});
|
||||
}).catch(() => {})
|
||||
}).catch(() => {}).finally(_ => {
|
||||
this.preventPrevLoad--
|
||||
})
|
||||
},
|
||||
|
||||
onDialogMenu(cmd) {
|
||||
|
||||
5
resources/assets/js/store/actions.js
vendored
5
resources/assets/js/store/actions.js
vendored
@ -4267,6 +4267,7 @@ export default {
|
||||
* @param dispatch
|
||||
* @param getters
|
||||
* @param data {dialog_id, msg_id, ?msg_type, ?position_id, ?prev_id, ?next_id, ?save_before, ?save_after, ?clear_before, ?spinner}
|
||||
* save_before 可返回 Promise,等其完成后再写入消息
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
getDialogMsgs({commit, state, dispatch, getters}, data) {
|
||||
@ -4310,8 +4311,8 @@ export default {
|
||||
data,
|
||||
spinner,
|
||||
complete: _ => dispatch("cancelLoad", loadKey)
|
||||
}).then(result => {
|
||||
saveBefore()
|
||||
}).then(async result => {
|
||||
await saveBefore()
|
||||
const resData = result.data;
|
||||
if ($A.isJson(resData.dialog)) {
|
||||
const ids = resData.list.map(({id}) => id)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user