修复合并消息可能导致滚动卡住的问题

This commit is contained in:
John Smith 2023-10-15 10:57:56 +08:00
parent 9874cf4291
commit bb23e2e5dc
2 changed files with 107 additions and 73 deletions

View File

@ -53,6 +53,7 @@
</template>
<script>
import _ from 'lodash'
import * as chatConfig from '@/api/chatConfig'
import Ticker from './Ticker'
import TextMessage from './TextMessage'
@ -60,12 +61,12 @@ import MembershipItem from './MembershipItem'
import PaidMessage from './PaidMessage'
import * as constants from './constants'
//
const NEED_SMOOTH_MESSAGE_TYPES = [
//
const ADD_MESSAGE_TYPES = [
constants.MESSAGE_TYPE_TEXT,
constants.MESSAGE_TYPE_GIFT,
constants.MESSAGE_TYPE_MEMBER,
constants.MESSAGE_TYPE_SUPER_CHAT
constants.MESSAGE_TYPE_SUPER_CHAT,
]
//
const MESSAGE_MIN_INTERVAL = 80
@ -159,13 +160,14 @@ export default {
addMessages(messages) {
this.enqueueMessages(messages)
},
//
mergeSimilarText(content) {
content = content.trim().toLowerCase()
let res = false
this.forEachRecentMessage(5, message => {
for (let message of this.iterRecentMessages(5)) {
if (message.type !== constants.MESSAGE_TYPE_TEXT) {
return true
continue
}
let messageContent = message.content.trim().toLowerCase()
let longer, shorter
if (messageContent.length > content.length) {
@ -175,52 +177,61 @@ export default {
longer = content
shorter = messageContent
}
if (longer.indexOf(shorter) !== -1 //
&& longer.length - shorter.length < shorter.length //
if (
longer.indexOf(shorter) !== -1 //
&& longer.length - shorter.length < shorter.length //
) {
//
message.repeated++
res = true
return false
this.updateMessage(message.id, { $add: {
repeated: 1
} })
return true
}
return true
})
return res
}
return false
},
mergeSimilarGift(authorName, price, giftName, num) {
let res = false
this.forEachRecentMessage(5, message => {
if (message.type === constants.MESSAGE_TYPE_GIFT
&& message.authorName === authorName
&& message.giftName === giftName
for (let message of this.iterRecentMessages(5)) {
if (
message.type === constants.MESSAGE_TYPE_GIFT
&& message.authorName === authorName
&& message.giftName === giftName
) {
message.price += price
message.num += num
res = true
return false
this.updateMessage(message.id, { $add: {
price: price,
num: num
} })
return true
}
return true
})
return res
}
return false
},
forEachRecentMessage(num, callback) {
// num
for (let i = this.smoothedMessageQueue.length - 1; i >= 0 && num > 0; i--) {
let messageGroup = this.smoothedMessageQueue[i]
for (let j = messageGroup.length - 1; j >= 0 && num-- > 0; j--) {
if (!callback(messageGroup[j])) {
return
// numsmoothedMessageQueuepaidMessages
*iterRecentMessages(num, onlyCountAddMessages = true) {
if (num <= 0) {
return
}
for (let arr of this.iterMessageArrs()) {
for (let i = arr.length - 1; i >= 0 && num > 0; i--) {
let message = arr[i]
yield message
if (!onlyCountAddMessages || this.isAddMessage(message)) {
num--
}
}
}
for (let arr of [this.messagesBuffer, this.messages]) {
for (let i = arr.length - 1; i >= 0 && num-- > 0; i--) {
if (!callback(arr[i])) {
return
}
if (num <= 0) {
break
}
}
},
//
*iterMessageArrs() {
for (let i = this.smoothedMessageQueue.length - 1; i >= 0; i--) {
yield this.smoothedMessageQueue[i]
}
yield this.messagesBuffer
yield this.messages
},
delMessage(id) {
this.delMessages([id])
},
@ -283,7 +294,7 @@ export default {
let messageGroup = []
for (let message of messages) {
messageGroup.push(message)
if (this.messageNeedSmooth(message)) {
if (this.isAddMessage(message)) {
this.smoothedMessageQueue.push(messageGroup)
messageGroup = []
}
@ -306,8 +317,8 @@ export default {
this.emitSmoothedMessageTimerId = window.setTimeout(this.emitSmoothedMessages)
}
},
messageNeedSmooth({ type }) {
return NEED_SMOOTH_MESSAGE_TYPES.indexOf(type) !== -1
isAddMessage({ type }) {
return ADD_MESSAGE_TYPES.indexOf(type) !== -1
},
emitSmoothedMessages() {
this.emitSmoothedMessageTimerId = null
@ -377,6 +388,7 @@ export default {
case constants.MESSAGE_TYPE_GIFT:
case constants.MESSAGE_TYPE_MEMBER:
case constants.MESSAGE_TYPE_SUPER_CHAT:
// ADD_MESSAGE_TYPES
this.handleAddMessage(message)
break
case constants.MESSAGE_TYPE_DEL:
@ -393,53 +405,73 @@ export default {
this.$nextTick(this.maybeScrollToBottom)
},
handleAddMessage(message) {
message = {
...message,
addTime: new Date() // Ticker
}
this.messagesBuffer.push(message)
// Ticker
message.addTime = new Date()
if (message.type !== constants.MESSAGE_TYPE_TEXT) {
this.paidMessages.unshift(message)
this.paidMessages.unshift(_.cloneDeep(message))
const MAX_PAID_MESSAGE_NUM = 100
if (this.paidMessages.length > MAX_PAID_MESSAGE_NUM) {
this.paidMessages.splice(MAX_PAID_MESSAGE_NUM, this.paidMessages.length - MAX_PAID_MESSAGE_NUM)
}
}
// cloneDeepVue
this.messagesBuffer.push(message)
},
handleDelMessage({ id }) {
for (let arr of [this.messages, this.paidMessages, this.messagesBuffer]) {
let arrs = [this.messages, this.paidMessages, this.messagesBuffer]
let needResetSmoothScroll = false
for (let arr of arrs) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].id === id) {
arr.splice(i, 1)
this.resetSmoothScroll()
break
if (arr[i].id !== id) {
continue
}
arr.splice(i, 1)
if (arr === this.messages) {
needResetSmoothScroll = true
}
break
}
}
if (needResetSmoothScroll) {
this.resetSmoothScroll()
}
},
handleUpdateMessage({ id, newValuesObj }) {
//
this.forEachRecentMessage(999999999, message => {
if (message.id !== id) {
return true
let arrs = [this.messages, this.paidMessages, this.messagesBuffer]
let needResetSmoothScroll = false
for (let arr of arrs) {
for (let message of arr) {
if (message.id !== id) {
continue
}
this.doUpdateMessage(message, newValuesObj)
if (arr === this.messages) {
needResetSmoothScroll = true
}
break
}
}
if (needResetSmoothScroll) {
this.resetSmoothScroll()
}
},
doUpdateMessage(message, newValuesObj) {
// +=
let addValuesObj = newValuesObj.$add
if (addValuesObj !== undefined) {
for (let name in addValuesObj) {
message[name] += addValuesObj[name]
}
}
// =
for (let name in newValuesObj) {
if (!name.startsWith('$')) {
message[name] = newValuesObj[name]
}
for (let name in newValuesObj) {
message[name] = newValuesObj[name]
}
return false
})
//
for (let message of this.paidMessages) {
if (message.id !== id) {
continue
}
for (let name in newValuesObj) {
message[name] = newValuesObj[name]
}
break
}
this.resetSmoothScroll()
},
async flushMessagesBuffer() {

View File

@ -490,6 +490,8 @@ export default {
}
// 0
img.onerror = resolve
//
setTimeout(resolve, 5000)
img.src = urlInClosure
}
))