mirror of
https://github.com/kuaifan/dootask.git
synced 2026-01-25 03:48:17 +00:00
pref: 优化消息列表
This commit is contained in:
parent
36735ace50
commit
976b9690d2
@ -68,7 +68,7 @@
|
|||||||
"vue-resize-observer": "^2.0.16",
|
"vue-resize-observer": "^2.0.16",
|
||||||
"vue-router": "^3.6.5",
|
"vue-router": "^3.6.5",
|
||||||
"vue-template-compiler": "~2.6.14",
|
"vue-template-compiler": "~2.6.14",
|
||||||
"vue-virtual-scroll-list-hi": "^2.3.5-7",
|
"vue-virtual-scroll-list-hi": "^2.3.5-8",
|
||||||
"vuedraggable": "^2.24.3",
|
"vuedraggable": "^2.24.3",
|
||||||
"vuex": "^3.6.2"
|
"vuex": "^3.6.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -153,7 +153,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-top-message-btn">
|
<div class="dialog-top-message-btn">
|
||||||
<Loading v-if="topPosLoad" type="pure"/>
|
<Loading v-if="topPosLoad > 0" type="pure"/>
|
||||||
<i v-else class="taskfont"></i>
|
<i v-else class="taskfont"></i>
|
||||||
<i class="taskfont" @click.stop="onCancelTop(topMsg)"></i>
|
<i class="taskfont" @click.stop="onCancelTop(topMsg)"></i>
|
||||||
</div>
|
</div>
|
||||||
@ -188,7 +188,6 @@
|
|||||||
@scroll="onScroll"
|
@scroll="onScroll"
|
||||||
@range="onRange"
|
@range="onRange"
|
||||||
@totop="onPrevPage"
|
@totop="onPrevPage"
|
||||||
@resized="onItemRendered"
|
|
||||||
|
|
||||||
@on-mention="onMention"
|
@on-mention="onMention"
|
||||||
@on-longpress="onLongpress"
|
@on-longpress="onLongpress"
|
||||||
@ -623,7 +622,6 @@ import UserAvatarTip from "../../../components/UserAvatar/tip.vue";
|
|||||||
import DialogGroupWordChain from "./DialogGroupWordChain";
|
import DialogGroupWordChain from "./DialogGroupWordChain";
|
||||||
import DialogGroupVote from "./DialogGroupVote";
|
import DialogGroupVote from "./DialogGroupVote";
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "DialogWrapper",
|
name: "DialogWrapper",
|
||||||
components: {
|
components: {
|
||||||
@ -665,11 +663,15 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
keeps: 25,
|
keeps: 25,
|
||||||
|
loadIng: 0,
|
||||||
|
|
||||||
msgItem: DialogItem,
|
msgItem: DialogItem,
|
||||||
msgText: '',
|
msgText: '',
|
||||||
msgNew: 0,
|
msgNew: 0, // 新消息数
|
||||||
msgType: '',
|
msgType: '', // 消息类型
|
||||||
loadIng: 0,
|
msgActivity: false, // 消息活动中
|
||||||
|
msgPrepared: false, // 消息已准备
|
||||||
|
|
||||||
|
|
||||||
focusLazy: false,
|
focusLazy: false,
|
||||||
focusTimer: null,
|
focusTimer: null,
|
||||||
@ -725,11 +727,8 @@ export default {
|
|||||||
recordState: '',
|
recordState: '',
|
||||||
wrapperStart: null,
|
wrapperStart: null,
|
||||||
|
|
||||||
scrollOffset: 0,
|
|
||||||
scrollTail: 0,
|
scrollTail: 0,
|
||||||
|
scrollOffset: 0,
|
||||||
preventMoreLoad: false,
|
|
||||||
preventToBottom: false,
|
|
||||||
|
|
||||||
replyListShow: false,
|
replyListShow: false,
|
||||||
replyListId: 0,
|
replyListId: 0,
|
||||||
@ -757,6 +756,7 @@ export default {
|
|||||||
scrollAction: 0,
|
scrollAction: 0,
|
||||||
scrollTmp: 0,
|
scrollTmp: 0,
|
||||||
scrollIng: 0,
|
scrollIng: 0,
|
||||||
|
scrollGroup: null,
|
||||||
|
|
||||||
approveDetails: {id: 0},
|
approveDetails: {id: 0},
|
||||||
approveDetailsShow: false,
|
approveDetailsShow: false,
|
||||||
@ -765,15 +765,12 @@ export default {
|
|||||||
observers: [],
|
observers: [],
|
||||||
|
|
||||||
unreadOne: 0, // 最早未读消息id
|
unreadOne: 0, // 最早未读消息id
|
||||||
topPosLoad: false, // 置顶跳转加载中
|
topPosLoad: 0, // 置顶跳转加载中
|
||||||
positionLoad: 0, // 定位跳转加载中
|
positionLoad: 0, // 定位跳转加载中
|
||||||
positionShow: false, // 定位跳转显示
|
positionShow: false, // 定位跳转显示
|
||||||
renderMsgNum: 0, // 渲染消息数量
|
preventMoreLoad: false, // 阻止加载更多
|
||||||
renderMsgSizes: new Map(), // 渲染消息尺寸
|
|
||||||
msgActivityStatus: false, // 消息准备完成
|
|
||||||
listPreparedStatus: false, // 列表准备完成
|
|
||||||
selectedTextStatus: false, // 是否选择文本
|
selectedTextStatus: false, // 是否选择文本
|
||||||
scrollToBottomAndRefresh: false, // 滚动到底部重新获取消息
|
scrollToBottomRefresh: false, // 滚动到底部重新获取消息
|
||||||
androidKeyboardVisible: false, // Android键盘是否可见
|
androidKeyboardVisible: false, // Android键盘是否可见
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1132,9 +1129,13 @@ export default {
|
|||||||
return 1024000
|
return 1024000
|
||||||
},
|
},
|
||||||
|
|
||||||
readEnabled({msgActivityStatus, listPreparedStatus}) {
|
readEnabled({msgActivity, msgPrepared}) {
|
||||||
return msgActivityStatus === 0 && listPreparedStatus
|
return msgActivity === 0 && msgPrepared
|
||||||
},
|
},
|
||||||
|
|
||||||
|
stickToBottom({windowActive, scrollTail}) {
|
||||||
|
return windowActive && scrollTail <= 0
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
@ -1156,39 +1157,28 @@ export default {
|
|||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
|
|
||||||
dialogId: {
|
dialogId: {
|
||||||
handler(dialog_id, old_id) {
|
handler(dialog_id, old_id) {
|
||||||
this.scrollInit()
|
|
||||||
if (dialog_id) {
|
if (dialog_id) {
|
||||||
this.msgNew = 0
|
this.msgNew = 0
|
||||||
this.msgType = ''
|
this.msgType = ''
|
||||||
this.unreadOne = 0
|
this.unreadOne = 0
|
||||||
|
this.scrollTail = 0
|
||||||
|
this.scrollOffset = 0
|
||||||
this.searchShow = false
|
this.searchShow = false
|
||||||
this.positionShow = false
|
this.positionShow = false
|
||||||
this.listPreparedStatus = false
|
this.msgPrepared = false
|
||||||
this.scrollToBottomAndRefresh = false
|
this.scrollToBottomRefresh = false
|
||||||
this.renderMsgNum = Math.min(this.keeps, Math.max(this.allMsgList.length, 1))
|
|
||||||
this.renderMsgSizes.clear()
|
|
||||||
this.allMsgs = this.allMsgList
|
this.allMsgs = this.allMsgList
|
||||||
//
|
//
|
||||||
const tmpMsgA = this.allMsgList.map(({id, msg, emoji}) => {
|
|
||||||
return {id, msg, emoji}
|
|
||||||
})
|
|
||||||
this.getMsgs({
|
this.getMsgs({
|
||||||
dialog_id,
|
dialog_id,
|
||||||
msg_id: this.msgId,
|
msg_id: this.msgId,
|
||||||
msg_type: this.msgType,
|
msg_type: this.msgType,
|
||||||
save_before: _ => this.onMarkOffset(false)
|
|
||||||
}).then(_ => {
|
}).then(_ => {
|
||||||
this.openId = dialog_id
|
this.openId = dialog_id
|
||||||
this.listPreparedStatus = true
|
this.msgPrepared = true
|
||||||
//
|
|
||||||
const tmpMsgB = this.allMsgList.map(({id, msg, emoji}) => {
|
|
||||||
return {id, msg, emoji}
|
|
||||||
})
|
|
||||||
if (JSON.stringify(tmpMsgA) != JSON.stringify(tmpMsgB)) {
|
|
||||||
this.renderMsgNum = Math.min(this.keeps, Math.max(this.allMsgList.length, 1))
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
setTimeout(_ => {
|
setTimeout(_ => {
|
||||||
this.onSearchMsgId()
|
this.onSearchMsgId()
|
||||||
@ -1238,6 +1228,16 @@ export default {
|
|||||||
this.observers.push({key: 'scroller', observer: scrollerObserver})
|
this.observers.push({key: 'scroller', observer: scrollerObserver})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.$refs.scroller) {
|
||||||
|
this.scrollGroup = this.$refs.scroller.$el.querySelector('[role="group"]')
|
||||||
|
if (this.scrollGroup) {
|
||||||
|
if (!this.observers.find(({key}) => key === 'scrollGroup')) {
|
||||||
|
const groupObserver = new ResizeObserver(this.onResizeEvent)
|
||||||
|
groupObserver.observe(this.scrollGroup);
|
||||||
|
this.observers.push({key: 'scrollGroup', observer: groupObserver})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
@ -1322,7 +1322,7 @@ export default {
|
|||||||
const lastMsg = this.allMsgs[this.allMsgs.length - 1]
|
const lastMsg = this.allMsgs[this.allMsgs.length - 1]
|
||||||
const lastEl = $A(this.$refs.scroller.$el).find(`[data-id="${lastMsg.id}"]`)
|
const lastEl = $A(this.$refs.scroller.$el).find(`[data-id="${lastMsg.id}"]`)
|
||||||
if (lastEl.length === 0) {
|
if (lastEl.length === 0) {
|
||||||
this.scrollToBottomAndRefresh = true
|
this.scrollToBottomRefresh = true
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 开始请求重新获取消息
|
// 开始请求重新获取消息
|
||||||
@ -1333,7 +1333,6 @@ export default {
|
|||||||
if (JSON.stringify(newList) == JSON.stringify(oldList)) {
|
if (JSON.stringify(newList) == JSON.stringify(oldList)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const {tail} = this.scrollInfo();
|
|
||||||
if ($A.isIos() && newList.length !== oldList.length) {
|
if ($A.isIos() && newList.length !== oldList.length) {
|
||||||
// 隐藏区域,让iOS断触
|
// 隐藏区域,让iOS断触
|
||||||
const scrollEl = this.$refs.scroller.$el
|
const scrollEl = this.$refs.scroller.$el
|
||||||
@ -1346,12 +1345,16 @@ export default {
|
|||||||
this.allMsgs = newList;
|
this.allMsgs = newList;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (!this.windowActive || (tail > 55 && oldList.length > 0)) {
|
if (!this.stickToBottom) {
|
||||||
const lastId = oldList[oldList.length - 1]?.id || 0
|
const oldId = oldList.length > 0 ? oldList[oldList.length - 1].id : 0
|
||||||
const tmpList = newList.filter(item => item.id && item.id > lastId && item.userid != this.userId && !item.read_at)
|
this.msgNew += newList.filter(item => item.id && item.id > oldId && item.userid != this.userId && !item.read_at).length
|
||||||
this.msgNew += tmpList.length
|
}
|
||||||
} else {
|
},
|
||||||
!this.preventToBottom && this.onToBottom()
|
|
||||||
|
|
||||||
|
'allMsgs.length' () {
|
||||||
|
if (this.stickToBottom) {
|
||||||
|
this.onToBottom()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1597,8 +1600,7 @@ export default {
|
|||||||
item.msg.text = data.text
|
item.msg.text = data.text
|
||||||
}
|
}
|
||||||
this.$nextTick(_ => {
|
this.$nextTick(_ => {
|
||||||
const {tail: newTail} = this.scrollInfo()
|
if (tail <= 10 && tail != this.scrollInfo().tail) {
|
||||||
if (tail <= 10 && newTail != tail) {
|
|
||||||
this.operatePreventScroll++
|
this.operatePreventScroll++
|
||||||
this.$refs.scroller.scrollToBottom()
|
this.$refs.scroller.scrollToBottom()
|
||||||
setTimeout(_ => this.operatePreventScroll--, 50)
|
setTimeout(_ => this.operatePreventScroll--, 50)
|
||||||
@ -1703,7 +1705,6 @@ export default {
|
|||||||
delay: 600
|
delay: 600
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
this.preventToBottom = true;
|
|
||||||
this.getMsgs({
|
this.getMsgs({
|
||||||
dialog_id: this.dialogId,
|
dialog_id: this.dialogId,
|
||||||
msg_id: this.msgId,
|
msg_id: this.msgId,
|
||||||
@ -1719,7 +1720,6 @@ export default {
|
|||||||
if (msg_id > 0) {
|
if (msg_id > 0) {
|
||||||
this.$store.dispatch("cancelLoad", `msg-${msg_id}`)
|
this.$store.dispatch("cancelLoad", `msg-${msg_id}`)
|
||||||
}
|
}
|
||||||
this.preventToBottom = false;
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2072,6 +2072,8 @@ export default {
|
|||||||
entries.some(({target, contentRect}) => {
|
entries.some(({target, contentRect}) => {
|
||||||
if (target === this.$refs.msgs) {
|
if (target === this.$refs.msgs) {
|
||||||
this.onMsgsResize(contentRect)
|
this.onMsgsResize(contentRect)
|
||||||
|
} else if (target === this.scrollGroup) {
|
||||||
|
this.onScrollGroupResize(contentRect)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -2091,6 +2093,18 @@ export default {
|
|||||||
this.__msgs_height = height;
|
this.__msgs_height = height;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onScrollGroupResize({height}) {
|
||||||
|
const {offset, tail} = this.scrollInfo()
|
||||||
|
if (this.stickToBottom) {
|
||||||
|
this.onToBottom()
|
||||||
|
} else if (tail > 0
|
||||||
|
&& typeof this.__scroll_group_data !== "undefined"
|
||||||
|
&& offset - this.__scroll_group_data.offset + tail === height - this.__scroll_group_data.height) {
|
||||||
|
this.onToBottom()
|
||||||
|
}
|
||||||
|
this.__scroll_group_data = {height, offset, tail}
|
||||||
|
},
|
||||||
|
|
||||||
onActive() {
|
onActive() {
|
||||||
this.$emit("on-active");
|
this.$emit("on-active");
|
||||||
},
|
},
|
||||||
@ -2131,33 +2145,6 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onMarkOffset(recovery = false) {
|
|
||||||
const scroller = this.$refs.scroller
|
|
||||||
if (!scroller) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (recovery) {
|
|
||||||
if (this.__mark_offset === undefined) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
this.onToOffset(scroller.getScrollSize() - scroller.getClientSize() - this.__mark_offset)
|
|
||||||
this.__mark_offset = undefined
|
|
||||||
} else {
|
|
||||||
this.__mark_offset = scroller.getScrollSize() - scroller.getClientSize() - scroller.getOffset()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
|
|
||||||
scrollInit() {
|
|
||||||
const scroller = this.$refs.scroller;
|
|
||||||
if (scroller && this.allMsgs.length > 0) {
|
|
||||||
scroller.virtual.destroy()
|
|
||||||
this.allMsgs = []
|
|
||||||
scroller.scrollToOffset(0)
|
|
||||||
scroller.installVirtual()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
scrollInfo() {
|
scrollInfo() {
|
||||||
const scroller = this.$refs.scroller;
|
const scroller = this.$refs.scroller;
|
||||||
if (scroller) {
|
if (scroller) {
|
||||||
@ -2204,7 +2191,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onReGetMsg() {
|
onReGetMsg() {
|
||||||
this.scrollToBottomAndRefresh = false
|
this.scrollToBottomRefresh = false
|
||||||
this.getMsgs({
|
this.getMsgs({
|
||||||
dialog_id: this.dialogId,
|
dialog_id: this.dialogId,
|
||||||
msg_id: this.msgId,
|
msg_id: this.msgId,
|
||||||
@ -2240,22 +2227,6 @@ export default {
|
|||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
},
|
},
|
||||||
|
|
||||||
onItemRendered(id, size) {
|
|
||||||
const scroller = this.$refs.scroller
|
|
||||||
if (!scroller) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.renderMsgNum > 0 && scroller.getSizes() >= this.renderMsgNum) {
|
|
||||||
this.renderMsgNum = 0
|
|
||||||
!this.onMarkOffset(true) && this.onToBottom()
|
|
||||||
} else if (this.renderMsgSizes.has(id)
|
|
||||||
&& size > this.renderMsgSizes.get(id)
|
|
||||||
&& size - this.renderMsgSizes.get(id) === this.scrollInfo().tail) {
|
|
||||||
this.onToBottom()
|
|
||||||
}
|
|
||||||
this.renderMsgSizes.set(id, size)
|
|
||||||
},
|
|
||||||
|
|
||||||
onDialogMenu(cmd) {
|
onDialogMenu(cmd) {
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case "searchMsg":
|
case "searchMsg":
|
||||||
@ -2527,16 +2498,16 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onActivity(activity) {
|
onActivity(activity) {
|
||||||
if (this.msgActivityStatus === false) {
|
if (this.msgActivity === false) {
|
||||||
if (activity) {
|
if (activity) {
|
||||||
this.msgActivityStatus = 1
|
this.msgActivity = 1
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (activity) {
|
if (activity) {
|
||||||
this.msgActivityStatus++
|
this.msgActivity++
|
||||||
} else {
|
} else {
|
||||||
this.msgActivityStatus--
|
this.msgActivity--
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -2548,9 +2519,9 @@ export default {
|
|||||||
const {offset, tail} = this.scrollInfo();
|
const {offset, tail} = this.scrollInfo();
|
||||||
this.scrollOffset = offset;
|
this.scrollOffset = offset;
|
||||||
this.scrollTail = tail;
|
this.scrollTail = tail;
|
||||||
if (this.scrollTail <= 55) {
|
if (tail <= 10) {
|
||||||
this.msgNew = 0;
|
this.msgNew = 0;
|
||||||
this.scrollToBottomAndRefresh && this.onReGetMsg()
|
this.scrollToBottomRefresh && this.onReGetMsg()
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
this.scrollAction = event.target.scrollTop;
|
this.scrollAction = event.target.scrollTop;
|
||||||
@ -3433,9 +3404,9 @@ export default {
|
|||||||
if (!this.topMsg) {
|
if (!this.topMsg) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.topPosLoad = true
|
this.topPosLoad++
|
||||||
this.onPositionId(this.topMsg.id).finally(_ => {
|
this.onPositionId(this.topMsg.id).finally(_ => {
|
||||||
this.topPosLoad = false
|
this.topPosLoad--
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -521,6 +521,7 @@
|
|||||||
.dialog-msgs {
|
.dialog-msgs {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-position {
|
.dialog-position {
|
||||||
@ -557,8 +558,8 @@
|
|||||||
|
|
||||||
.dialog-scroller {
|
.dialog-scroller {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 16px 32px 0;
|
padding: 16px 32px 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user