Compare commits

..

4 Commits

Author SHA1 Message Date
John Smith
b73a4e3748 更新版本号v1.4.1 2020-03-01 14:22:12 +08:00
John Smith
102746d0b0 添加显示礼物名、只合并同类礼物 2020-03-01 14:14:19 +08:00
John Smith
2d237af6fd 提示用户已加载页面 2020-02-29 19:20:29 +08:00
John Smith
4030ff43cd 减小编译后文件尺寸 2020-02-22 17:21:47 +08:00
17 changed files with 4717 additions and 11405 deletions

View File

@@ -63,7 +63,7 @@ class Room(blivedm.BLiveClient):
def __parse_gift(self, command):
data = command['data']
return self._on_receive_gift(blivedm.GiftMessage(
None, None, data['uname'], data['face'], None,
data['giftName'], data['num'], data['uname'], data['face'], None,
data['uid'], data['timestamp'], None, None,
None, None, None, data['coin_type'], data['total_coin']
))
@@ -192,7 +192,9 @@ class Room(blivedm.BLiveClient):
'avatarUrl': avatar_url,
'timestamp': gift.timestamp,
'authorName': gift.uname,
'totalCoin': gift.total_coin
'totalCoin': gift.total_coin,
'giftName': gift.gift_name,
'num': gift.num
})
async def _on_buy_guard(self, message: blivedm.GuardBuyMessage):
@@ -419,7 +421,9 @@ class ChatHandler(tornado.websocket.WebSocketHandler):
gift_data = {
**base_data,
'id': uuid.uuid4().hex,
'totalCoin': 450000
'totalCoin': 450000,
'giftName': '摩天大楼',
'num': 1
}
sc_data = {
**base_data,
@@ -444,6 +448,7 @@ class ChatHandler(tornado.websocket.WebSocketHandler):
self.send_message(Command.ADD_GIFT, gift_data)
gift_data['id'] = uuid.uuid4().hex
gift_data['totalCoin'] = 1245000
gift_data['giftName'] = '小电视飞船'
self.send_message(Command.ADD_GIFT, gift_data)
@property

View File

@@ -1,5 +1,13 @@
module.exports = {
presets: [
'@vue/app'
],
plugins: [
[
'component', {
'libraryName': 'element-ui',
'styleLibraryName': 'theme-chalk'
}
]
]
}

15938
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,8 +20,9 @@
"devDependencies": {
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.7.0",
"@vue/cli-service": "^3.7.0",
"@vue/cli-service": "^4.2.2",
"babel-eslint": "^10.0.1",
"babel-plugin-component": "^1.1.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.5.21"

View File

@@ -2,9 +2,11 @@ import {mergeConfig} from '@/utils'
export const DEFAULT_CONFIG = {
minGiftPrice: 7, // $1
mergeSimilarDanmaku: true,
showDanmaku: true,
showGift: true,
showGiftName: false,
mergeSimilarDanmaku: true,
mergeGift: true,
maxNumber: 60,
blockGiftDanmaku: true,

View File

@@ -34,18 +34,19 @@
<paid-message :key="pinnedMessage.id" v-else
class="style-scope yt-live-chat-ticker-renderer"
:price="pinnedMessage.price" :avatarUrl="pinnedMessage.avatarUrl" :authorName="pinnedMessage.authorName"
:time="pinnedMessage.time" :content="pinnedMessage.content"
:time="pinnedMessage.time" :content="showContent"
></paid-message>
</template>
</yt-live-chat-ticker-renderer>
</template>
<script>
import * as config from '@/api/config'
import {formatCurrency} from '@/utils'
import ImgShadow from './ImgShadow.vue'
import LegacyPaidMessage from './LegacyPaidMessage.vue'
import PaidMessage from './PaidMessage.vue'
import * as constants from './constants'
import {formatCurrency} from '@/utils'
export default {
name: 'Ticker',
@@ -55,7 +56,11 @@ export default {
PaidMessage
},
props: {
messages: Array
messages: Array,
showGiftName: {
type: Boolean,
default: config.DEFAULT_CONFIG.showGiftName
}
},
data() {
return {
@@ -65,6 +70,18 @@ export default {
pinnedMessage: null
}
},
computed: {
showContent() {
if (!this.pinnedMessage) {
return ''
}
if (this.pinnedMessage.type === constants.MESSAGE_TYPE_GIFT) {
return constants.getGiftShowContent(this.pinnedMessage, this.showGiftName)
} else {
return constants.getShowContent(this.pinnedMessage)
}
}
},
beforeDestroy() {
window.clearInterval(this.updateTimerId)
},

View File

@@ -18,10 +18,11 @@ export const GUARD_LEVEL_TO_TEXT = [
]
export const MESSAGE_TYPE_TEXT = 0
export const MESSAGE_TYPE_MEMBER = 1
export const MESSAGE_TYPE_SUPER_CHAT = 2
export const MESSAGE_TYPE_DEL = 3
export const MESSAGE_TYPE_UPDATE = 4
export const MESSAGE_TYPE_GIFT = 1
export const MESSAGE_TYPE_MEMBER = 2
export const MESSAGE_TYPE_SUPER_CHAT = 3
export const MESSAGE_TYPE_DEL = 4
export const MESSAGE_TYPE_UPDATE = 5
// 美元 -> 人民币 汇率
const EXCHANGE_RATE = 7
@@ -120,3 +121,17 @@ export function getPriceConfig (price) {
}
return PRICE_CONFIGS[PRICE_CONFIGS.length - 1]
}
export function getShowContent(message) {
if (message.translation) {
return `${message.content}${message.translation}`
}
return message.content
}
export function getGiftShowContent(message, showGiftName) {
if (!showGiftName) {
return ''
}
return `Sent ${message.giftName}x${message.num}`
}

View File

@@ -2,7 +2,9 @@
<yt-live-chat-renderer class="style-scope yt-live-chat-app" style="--scrollbar-width:11px;" hide-timestamps
@mousemove="refreshCantScrollStartTime"
>
<ticker class="style-scope yt-live-chat-renderer" :messages="paidMessages" :hidden="paidMessages.length === 0"></ticker>
<ticker class="style-scope yt-live-chat-renderer" :messages="paidMessages" :showGiftName="showGiftName"
:hidden="paidMessages.length === 0"
></ticker>
<yt-live-chat-item-list-renderer class="style-scope yt-live-chat-renderer" allow-scroll>
<div ref="scroller" id="item-scroller" class="style-scope yt-live-chat-item-list-renderer animated" @scroll="onScroll">
<div ref="itemOffset" id="item-offset" class="style-scope yt-live-chat-item-list-renderer" style="height: 0px;">
@@ -16,6 +18,11 @@
:authorType="message.authorType" :content="getShowContent(message)" :privilegeType="message.privilegeType"
:repeated="message.repeated"
></text-message>
<paid-message :key="message.id" v-else-if="message.type === MESSAGE_TYPE_GIFT"
class="style-scope yt-live-chat-item-list-renderer"
:price="message.price" :avatarUrl="message.avatarUrl" :authorName="message.authorName"
:time="message.time" :content="getGiftShowContent(message)"
></paid-message>
<legacy-paid-message :key="message.id" v-else-if="message.type === MESSAGE_TYPE_MEMBER"
class="style-scope yt-live-chat-item-list-renderer"
:avatarUrl="message.avatarUrl" :title="message.title" :content="message.content"
@@ -58,6 +65,10 @@ export default {
maxNumber: {
type: Number,
default: config.DEFAULT_CONFIG.maxNumber
},
showGiftName: {
type: Boolean,
default: config.DEFAULT_CONFIG.showGiftName
}
},
data() {
@@ -65,6 +76,7 @@ export default {
document.head.appendChild(styleElement)
return {
MESSAGE_TYPE_TEXT: constants.MESSAGE_TYPE_TEXT,
MESSAGE_TYPE_GIFT: constants.MESSAGE_TYPE_GIFT,
MESSAGE_TYPE_MEMBER: constants.MESSAGE_TYPE_MEMBER,
MESSAGE_TYPE_SUPER_CHAT: constants.MESSAGE_TYPE_SUPER_CHAT,
@@ -118,12 +130,10 @@ export default {
this.clearMessages()
},
methods: {
getShowContent(message) {
if (message.translation) {
return `${message.content}${message.translation}`
}
return message.content
getGiftShowContent(message) {
return constants.getGiftShowContent(message, this.showGiftName)
},
getShowContent: constants.getShowContent,
addMessage(message) {
this.addMessages([message])
@@ -159,14 +169,15 @@ export default {
})
return res
},
mergeSimilarGift(authorName, price) {
mergeSimilarGift(authorName, price, giftName, num) {
let res = false
this.forEachRecentMessage(5, message => {
if (message.type === constants.MESSAGE_TYPE_SUPER_CHAT
&& message.content === ''
if (message.type === constants.MESSAGE_TYPE_GIFT
&& message.authorName === authorName
&& message.giftName === giftName
) {
message.price += price
message.num += num
res = true
return false
}
@@ -317,6 +328,7 @@ export default {
for (let message of messageGroup) {
switch (message.type) {
case constants.MESSAGE_TYPE_TEXT:
case constants.MESSAGE_TYPE_GIFT:
case constants.MESSAGE_TYPE_MEMBER:
case constants.MESSAGE_TYPE_SUPER_CHAT:
this.handleAddMessage(message)

View File

@@ -14,7 +14,9 @@ export default {
roomId: 'Room ID',
showDanmaku: 'Show messages',
showGift: 'Show Super Chats',
showGiftName: 'Show gift name',
mergeSimilarDanmaku: 'Merge similar messages',
mergeGift: 'Merge gifts',
minGiftPrice: 'Min price of Super Chats to show (CNY)',
maxNumber: 'Max number of messages',

View File

@@ -14,7 +14,9 @@ export default {
roomId: 'ルームID',
showDanmaku: 'コメントを表示する',
showGift: 'スーパーチャットと新メンバーを表示する',
showGiftName: 'ギフト名を表示する',
mergeSimilarDanmaku: '同じコメントを合併する',
mergeGift: 'ギフトを合併する',
minGiftPrice: '最低表示スーパーチャット価格CNY',
maxNumber: '最大コメント数',
@@ -28,7 +30,7 @@ export default {
blockUsers: 'ブロックユーザー',
blockMedalLevel: 'ブロック勲章等級がx未満',
advanced: 'アドバンス',
advanced: 'アドバンス',
autoTranslate: '自動翻訳コメントから日本語へ',
roomUrl: 'ルームのURL',

View File

@@ -14,7 +14,9 @@ export default {
roomId: '房间ID',
showDanmaku: '显示弹幕',
showGift: '显示打赏和新舰长',
showGiftName: '显示礼物名',
mergeSimilarDanmaku: '合并相似弹幕',
mergeGift: '合并礼物',
minGiftPrice: '最低显示打赏价格(元)',
maxNumber: '最大弹幕数',

View File

@@ -9,7 +9,7 @@
</router-link>
</div>
<div class="version">
v1.4.0
v1.4.1
</div>
<sidebar></sidebar>
</el-aside>

View File

@@ -1,8 +1,10 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import VueI18n from 'vue-i18n'
import {
Aside, Autocomplete, Badge, Button, Col, ColorPicker, Container, Divider, Form, FormItem, Image,
Input, Main, Menu, MenuItem, Message, Row, Scrollbar, Slider, Submenu, Switch, TabPane, Tabs, Tooltip
} from 'element-ui'
import axios from 'axios'
import App from './App.vue'
@@ -23,8 +25,32 @@ if (process.env.NODE_ENV === 'development') {
}
Vue.use(VueRouter)
Vue.use(ElementUI)
Vue.use(VueI18n)
// 初始化element
Vue.use(Aside)
Vue.use(Autocomplete)
Vue.use(Badge)
Vue.use(Button)
Vue.use(Col)
Vue.use(ColorPicker)
Vue.use(Container)
Vue.use(Divider)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Image)
Vue.use(Input)
Vue.use(Main)
Vue.use(Menu)
Vue.use(MenuItem)
Vue.use(Row)
Vue.use(Scrollbar)
Vue.use(Slider)
Vue.use(Submenu)
Vue.use(Switch)
Vue.use(TabPane)
Vue.use(Tabs)
Vue.use(Tooltip)
Vue.prototype.$message = Message
Vue.config.ignoredElements = [
/^yt-/

View File

@@ -16,9 +16,15 @@
<el-form-item :label="$t('home.showGift')">
<el-switch v-model="form.showGift"></el-switch>
</el-form-item>
<el-form-item :label="$t('home.showGiftName')">
<el-switch v-model="form.showGiftName"></el-switch>
</el-form-item>
<el-form-item :label="$t('home.mergeSimilarDanmaku')">
<el-switch v-model="form.mergeSimilarDanmaku"></el-switch>
</el-form-item>
<el-form-item :label="$t('home.mergeGift')">
<el-switch v-model="form.mergeGift"></el-switch>
</el-form-item>
<el-form-item :label="$t('home.minGiftPrice')">
<el-input v-model.number="form.minGiftPrice" type="number" min="0"></el-input>
</el-form-item>

View File

@@ -1,5 +1,5 @@
<template>
<chat-renderer ref="renderer" :maxNumber="config.maxNumber"></chat-renderer>
<chat-renderer ref="renderer" :maxNumber="config.maxNumber" :showGiftName="config.showGiftName"></chat-renderer>
</template>
<script>
@@ -43,6 +43,11 @@ export default {
created() {
this.updateConfig()
this.wsConnect()
// 提示用户已加载
this.$message({
message: 'Loaded',
duration: '500'
})
},
beforeDestroy() {
this.isDestroying = true
@@ -60,9 +65,11 @@ export default {
cfg = mergeConfig(cfg, config.DEFAULT_CONFIG)
cfg.minGiftPrice = toInt(cfg.minGiftPrice, config.DEFAULT_CONFIG.minGiftPrice)
cfg.mergeSimilarDanmaku = toBool(cfg.mergeSimilarDanmaku)
cfg.showDanmaku = toBool(cfg.showDanmaku)
cfg.showGift = toBool(cfg.showGift)
cfg.showGiftName = toBool(cfg.showGiftName)
cfg.mergeSimilarDanmaku = toBool(cfg.mergeSimilarDanmaku)
cfg.mergeGift = toBool(cfg.mergeGift)
cfg.maxNumber = toInt(cfg.maxNumber, config.DEFAULT_CONFIG.maxNumber)
cfg.blockGiftDanmaku = toBool(cfg.blockGiftDanmaku)
cfg.blockLevel = toInt(cfg.blockLevel, config.DEFAULT_CONFIG.blockLevel)
@@ -153,20 +160,21 @@ export default {
break
}
let price = data.totalCoin / 1000
if (price < this.config.minGiftPrice) { // 丢人
if (this.mergeSimilarGift(data.authorName, price, data.giftName, data.num)) {
break
}
if (this.mergeSimilarGift(data.authorName, price)) {
if (price < this.config.minGiftPrice) { // 丢人
break
}
message = {
id: data.id,
type: constants.MESSAGE_TYPE_SUPER_CHAT,
type: constants.MESSAGE_TYPE_GIFT,
avatarUrl: data.avatarUrl,
time: new Date(data.timestamp * 1000),
authorName: data.authorName,
price: price,
time: new Date(data.timestamp * 1000),
content: '' // 有了SC礼物不需要内容了
giftName: data.giftName,
num: data.num
}
break
}
@@ -257,11 +265,11 @@ export default {
}
return this.$refs.renderer.mergeSimilarText(content)
},
mergeSimilarGift(authorName, price) {
if (!this.config.mergeSimilarDanmaku) {
mergeSimilarGift(authorName, price, giftName, num) {
if (!this.config.mergeGift) {
return false
}
return this.$refs.renderer.mergeSimilarGift(authorName, price)
return this.$refs.renderer.mergeSimilarGift(authorName, price, giftName, num)
}
}
}

View File

@@ -268,8 +268,8 @@ const EXAMPLE_MESSAGES = [
{
...legacyPaidMessageTemplate,
id: (nextId++).toString(),
authorName: '少年Pi',
content: 'Welcome 少年Pi!'
authorName: '进击的冰糖',
content: 'Welcome 进击的冰糖!'
},
{
...paidMessageTemplate,

View File

@@ -4,7 +4,7 @@ import asyncio
import aiohttp
VERSION = 'v1.4.0'
VERSION = 'v1.4.1'
def check_update():