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

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

View File

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