mirror of
https://github.com/xfgryujk/blivechat.git
synced 2024-12-26 04:41:40 +08:00
修复合并消息可能导致滚动卡住的问题
This commit is contained in:
parent
9874cf4291
commit
bb23e2e5dc
@ -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
|
||||
// 从新到老迭代num条消息,注意会迭代smoothedMessageQueue,不会迭代paidMessages
|
||||
*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)
|
||||
}
|
||||
}
|
||||
|
||||
// 不知道cloneDeep拷贝Vue的响应式对象会不会有问题,保险起见把这句放在后面
|
||||
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() {
|
||||
|
@ -490,6 +490,8 @@ export default {
|
||||
}
|
||||
// 获取失败了默认为0
|
||||
img.onerror = resolve
|
||||
// 超时保底
|
||||
setTimeout(resolve, 5000)
|
||||
img.src = urlInClosure
|
||||
}
|
||||
))
|
||||
|
Loading…
Reference in New Issue
Block a user