blivechat/frontend/src/views/Room.vue

224 lines
6.3 KiB
Vue
Raw Normal View History

2019-06-17 12:29:25 +08:00
<template>
<chat-renderer ref="renderer" :css="config.css" :maxNumber="config.maxNumber"></chat-renderer>
2019-06-17 12:29:25 +08:00
</template>
<script>
import config from '@/api/config'
import ChatRenderer from '@/components/ChatRenderer'
2019-06-22 16:15:40 +08:00
import * as constants from '@/components/ChatRenderer/constants'
2019-06-17 12:29:25 +08:00
2019-10-06 16:20:48 +08:00
const COMMAND_HEARTBEAT = 0
2019-09-23 22:22:27 +08:00
const COMMAND_JOIN_ROOM = 1
const COMMAND_ADD_TEXT = 2
const COMMAND_ADD_GIFT = 3
const COMMAND_ADD_MEMBER = 4
const COMMAND_ADD_SUPER_CHAT = 5
const COMMAND_DEL_SUPER_CHAT = 6
2019-06-17 12:29:25 +08:00
export default {
name: 'Room',
components: {
ChatRenderer
},
data() {
return {
config: {...config.DEFAULT_CONFIG},
2019-10-06 16:20:48 +08:00
2019-06-17 12:29:25 +08:00
websocket: null,
2019-10-06 16:20:48 +08:00
retryCount: 0,
isDestroying: false,
heartbeatTimerId: null,
2019-06-20 23:53:34 +08:00
nextId: 0,
}
},
computed: {
blockKeywords() {
return this.config.blockKeywords.split('\n').filter(val => val)
},
blockUsers() {
return this.config.blockUsers.split('\n').filter(val => val)
2019-06-17 12:29:25 +08:00
}
},
2019-10-06 16:20:48 +08:00
created() {
this.wsConnect()
2019-06-17 12:29:25 +08:00
if (this.$route.query.config_id) {
2019-10-06 16:20:48 +08:00
this.updateConfig(this.$route.query.config_id)
2019-06-17 12:29:25 +08:00
}
},
beforeDestroy() {
2019-10-06 16:20:48 +08:00
this.isDestroying = true
2019-06-17 12:29:25 +08:00
this.websocket.close()
},
methods: {
2019-10-06 16:20:48 +08:00
async updateConfig(configId) {
try {
this.config = await config.getRemoteConfig(configId)
2019-10-06 16:20:48 +08:00
} catch (e) {
this.$message.error('获取配置失败:' + e)
}
},
wsConnect() {
2019-10-13 17:02:54 +08:00
const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
2019-10-06 16:20:48 +08:00
// 开发时使用localhost:12450
2019-10-13 17:02:54 +08:00
const host = process.env.NODE_ENV === 'development' ? 'localhost:12450' : window.location.host
const url = `${protocol}://${host}/chat`
2019-10-06 16:20:48 +08:00
this.websocket = new WebSocket(url)
this.websocket.onopen = this.onWsOpen
this.websocket.onclose = this.onWsClose
this.websocket.onmessage = this.onWsMessage
this.heartbeatTimerId = window.setInterval(this.sendHeartbeat, 10 * 1000)
},
sendHeartbeat() {
this.websocket.send(JSON.stringify({
cmd: COMMAND_HEARTBEAT
}))
},
2019-06-17 12:29:25 +08:00
onWsOpen() {
2019-10-06 16:20:48 +08:00
this.retryCount = 0
2019-06-17 12:29:25 +08:00
this.websocket.send(JSON.stringify({
cmd: COMMAND_JOIN_ROOM,
data: {
roomId: parseInt(this.$route.params.roomId)
}
}))
},
2019-10-06 16:20:48 +08:00
onWsClose() {
if (this.heartbeatTimerId) {
window.clearInterval(this.heartbeatTimerId)
this.heartbeatTimerId = null
}
if (this.isDestroying) {
return
}
window.console.log(`掉线重连中${++this.retryCount}`)
this.wsConnect()
},
2019-06-17 12:29:25 +08:00
onWsMessage(event) {
let {cmd, data} = JSON.parse(event.data)
let message = null
let time = data.timestamp ? new Date(data.timestamp * 1000) : new Date()
2019-10-06 12:23:47 +08:00
switch (cmd) {
2019-06-17 12:29:25 +08:00
case COMMAND_ADD_TEXT:
if (!this.config.showDanmaku || !this.filterTextMessage(data) || this.mergeSimilarText(data.content)) {
2019-06-17 12:29:25 +08:00
break
}
message = {
2019-10-06 12:23:47 +08:00
id: `text_${this.nextId++}`,
2019-06-22 16:15:40 +08:00
type: constants.MESSAGE_TYPE_TEXT,
2019-06-17 12:29:25 +08:00
avatarUrl: data.avatarUrl,
2019-07-18 08:31:58 +08:00
time: time,
2019-06-17 12:29:25 +08:00
authorName: data.authorName,
authorType: data.authorType,
content: data.content,
2019-06-20 20:03:07 +08:00
privilegeType: data.privilegeType,
2019-06-17 12:29:25 +08:00
repeated: 1
}
break
case COMMAND_ADD_GIFT: {
2019-06-20 23:53:34 +08:00
if (!this.config.showGift) {
break
}
2019-06-17 12:29:25 +08:00
let price = data.totalCoin / 1000
2019-09-23 22:22:27 +08:00
if (price < this.config.minGiftPrice) { // 丢人
2019-06-17 12:29:25 +08:00
break
2019-09-23 22:22:27 +08:00
}
2019-11-29 23:48:43 +08:00
if (this.mergeSimilarGift(data.authorName, price)) {
break
}
2019-06-17 12:29:25 +08:00
message = {
2019-10-06 12:23:47 +08:00
id: `gift_${this.nextId++}`,
2019-09-23 22:22:27 +08:00
type: constants.MESSAGE_TYPE_SUPER_CHAT,
2019-06-17 12:29:25 +08:00
avatarUrl: data.avatarUrl,
authorName: data.authorName,
price: price,
2019-07-18 08:31:58 +08:00
time: time,
2019-09-23 22:22:27 +08:00
content: '' // 有了SC礼物不需要内容了
2019-06-17 12:29:25 +08:00
}
break
}
2019-06-20 20:03:07 +08:00
case COMMAND_ADD_MEMBER:
2019-09-23 22:22:27 +08:00
if (!this.config.showGift || !this.filterSuperChatMessage(data)) {
2019-06-20 23:53:34 +08:00
break
}
2019-06-17 12:29:25 +08:00
message = {
2019-10-06 12:23:47 +08:00
id: `member_${this.nextId++}`,
2019-06-22 16:15:40 +08:00
type: constants.MESSAGE_TYPE_MEMBER,
2019-06-17 12:29:25 +08:00
avatarUrl: data.avatarUrl,
2019-07-18 08:31:58 +08:00
time: time,
2019-06-17 12:29:25 +08:00
authorName: data.authorName,
title: 'NEW MEMBER!',
2019-07-15 21:30:52 +08:00
content: `Welcome ${data.authorName}!`
2019-06-17 12:29:25 +08:00
}
break
2019-09-23 22:22:27 +08:00
case COMMAND_ADD_SUPER_CHAT:
if (!this.config.showGift) {
break
}
if (data.price < this.config.minGiftPrice) { // 丢人
break
}
message = {
2019-10-06 12:23:47 +08:00
id: `sc_${data.id}`,
2019-09-23 22:22:27 +08:00
type: constants.MESSAGE_TYPE_SUPER_CHAT,
avatarUrl: data.avatarUrl,
authorName: data.authorName,
price: data.price,
time: time,
2019-11-29 23:48:43 +08:00
content: data.content.trim()
2019-09-23 22:22:27 +08:00
}
break
case COMMAND_DEL_SUPER_CHAT:
2019-10-06 12:23:47 +08:00
for (let id of data.ids) {
id = `sc_${id}`
this.$refs.renderer.delMessage(id)
2019-10-06 12:23:47 +08:00
}
2019-09-23 22:22:27 +08:00
break
2019-06-17 12:29:25 +08:00
}
if (message) {
this.$refs.renderer.addMessage(message)
2019-06-17 12:29:25 +08:00
}
},
filterTextMessage(data) {
if (this.config.blockGiftDanmaku && data.isGiftDanmaku) {
return false
} else if (this.config.blockLevel > 0 && data.authorLevel < this.config.blockLevel) {
return false
} else if (this.config.blockNewbie && data.isNewbie) {
return false
} else if (this.config.blockNotMobileVerified && !data.isMobileVerified) {
return false
2019-06-21 17:38:22 +08:00
} else if (this.config.blockMedalLevel > 0 && data.medalLevel < this.config.blockMedalLevel) {
return false
2019-06-17 12:29:25 +08:00
}
return this.filterSuperChatMessage(data)
2019-06-17 12:29:25 +08:00
},
2019-09-23 22:22:27 +08:00
filterSuperChatMessage(data) {
for (let keyword of this.blockKeywords) {
2019-09-23 22:22:27 +08:00
if (data.content.indexOf(keyword) !== -1) {
return false
}
}
for (let user of this.blockUsers) {
2019-09-23 22:22:27 +08:00
if (data.authorName === user) {
return false
}
}
return true
},
mergeSimilarText(content) {
2019-06-17 12:29:25 +08:00
if (!this.config.mergeSimilarDanmaku) {
return false
}
return this.$refs.renderer.mergeSimilarText(content)
2019-11-29 23:48:43 +08:00
},
mergeSimilarGift(authorName, price) {
if (!this.config.mergeSimilarDanmaku) {
return false
}
return this.$refs.renderer.mergeSimilarGift(authorName, price)
2019-06-17 12:29:25 +08:00
}
}
}
</script>