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