mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-03-13 03:10:47 +08:00
添加标注打赏用户名读音
This commit is contained in:
parent
8c7fc2780d
commit
4f0964c0b3
@ -1,5 +1,5 @@
|
||||
import axios from 'axios'
|
||||
import {inflate} from 'pako'
|
||||
import * as pako from 'pako'
|
||||
|
||||
import {getUuid4Hex} from '@/utils'
|
||||
import * as avatar from './avatar'
|
||||
@ -172,7 +172,7 @@ export default class ChatClientDirect {
|
||||
case OP_SEND_MSG_REPLY: {
|
||||
let body = new Uint8Array(data.buffer, offset + HEADER_SIZE, packLen - HEADER_SIZE)
|
||||
if (ver == WS_BODY_PROTOCOL_VERSION_DEFLATE) {
|
||||
body = inflate(body)
|
||||
body = pako.inflate(body)
|
||||
this.handlerMessage(body)
|
||||
} else {
|
||||
try {
|
||||
|
@ -18,7 +18,8 @@ export const DEFAULT_CONFIG = {
|
||||
blockMedalLevel: 0,
|
||||
|
||||
relayMessagesByServer: false,
|
||||
autoTranslate: false
|
||||
autoTranslate: false,
|
||||
giftUsernamePronunciation: ''
|
||||
}
|
||||
|
||||
export function setLocalConfig (config) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {DEFAULT_AVATAR_URL} from '@/api/chat/avatar'
|
||||
import * as avatar from '@/api/chat/avatar'
|
||||
|
||||
export default {
|
||||
name: 'ImgShadow',
|
||||
@ -26,8 +26,8 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onLoadError() {
|
||||
if (this.showImgUrl !== DEFAULT_AVATAR_URL) {
|
||||
this.showImgUrl = DEFAULT_AVATAR_URL
|
||||
if (this.showImgUrl !== avatar.DEFAULT_AVATAR_URL) {
|
||||
this.showImgUrl = avatar.DEFAULT_AVATAR_URL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,12 +24,12 @@
|
||||
<template v-if="pinnedMessage">
|
||||
<membership-item :key="pinnedMessage.id" v-if="pinnedMessage.type === MESSAGE_TYPE_MEMBER"
|
||||
class="style-scope yt-live-chat-ticker-renderer"
|
||||
:avatarUrl="pinnedMessage.avatarUrl" :authorName="pinnedMessage.authorName" :privilegeType="pinnedMessage.privilegeType"
|
||||
:avatarUrl="pinnedMessage.avatarUrl" :authorName="getShowAuthorName(pinnedMessage)" :privilegeType="pinnedMessage.privilegeType"
|
||||
:title="pinnedMessage.title" :time="pinnedMessage.time"
|
||||
></membership-item>
|
||||
<paid-message :key="pinnedMessage.id" v-else
|
||||
class="style-scope yt-live-chat-ticker-renderer"
|
||||
:price="pinnedMessage.price" :avatarUrl="pinnedMessage.avatarUrl" :authorName="pinnedMessage.authorName"
|
||||
:price="pinnedMessage.price" :avatarUrl="pinnedMessage.avatarUrl" :authorName="getShowAuthorName(pinnedMessage)"
|
||||
:time="pinnedMessage.time" :content="pinnedMessageShowContent"
|
||||
></paid-message>
|
||||
</template>
|
||||
@ -98,6 +98,7 @@ export default {
|
||||
window.clearInterval(this.updateTimerId)
|
||||
},
|
||||
methods: {
|
||||
getShowAuthorName: constants.getShowAuthorName,
|
||||
needToShow(message) {
|
||||
let pinTime = this.getPinTime(message)
|
||||
return (new Date() - message.addTime) / (60 * 1000) < pinTime
|
||||
|
@ -122,16 +122,23 @@ export function getPriceConfig (price) {
|
||||
return PRICE_CONFIGS[PRICE_CONFIGS.length - 1]
|
||||
}
|
||||
|
||||
export function getShowContent(message) {
|
||||
export function getShowContent (message) {
|
||||
if (message.translation) {
|
||||
return `${message.content}(${message.translation})`
|
||||
}
|
||||
return message.content
|
||||
}
|
||||
|
||||
export function getGiftShowContent(message, showGiftName) {
|
||||
export function getGiftShowContent (message, showGiftName) {
|
||||
if (!showGiftName) {
|
||||
return ''
|
||||
}
|
||||
return `Sent ${message.giftName}x${message.num}`
|
||||
}
|
||||
|
||||
export function getShowAuthorName (message) {
|
||||
if (message.authorNamePronunciation) {
|
||||
return `${message.authorName}(${message.authorNamePronunciation})`
|
||||
}
|
||||
return message.authorName
|
||||
}
|
||||
|
@ -18,17 +18,17 @@
|
||||
></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"
|
||||
:price="message.price" :avatarUrl="message.avatarUrl" :authorName="getShowAuthorName(message)"
|
||||
:time="message.time" :content="getGiftShowContent(message)"
|
||||
></paid-message>
|
||||
<membership-item :key="message.id" v-else-if="message.type === MESSAGE_TYPE_MEMBER"
|
||||
class="style-scope yt-live-chat-item-list-renderer"
|
||||
:avatarUrl="message.avatarUrl" :authorName="message.authorName" :privilegeType="message.privilegeType"
|
||||
:avatarUrl="message.avatarUrl" :authorName="getShowAuthorName(message)" :privilegeType="message.privilegeType"
|
||||
:title="message.title" :time="message.time"
|
||||
></membership-item>
|
||||
<paid-message :key="message.id" v-else-if="message.type === MESSAGE_TYPE_SUPER_CHAT"
|
||||
class="style-scope yt-live-chat-item-list-renderer"
|
||||
:price="message.price" :avatarUrl="message.avatarUrl" :authorName="message.authorName"
|
||||
:price="message.price" :avatarUrl="message.avatarUrl" :authorName="getShowAuthorName(message)"
|
||||
:time="message.time" :content="getShowContent(message)"
|
||||
></paid-message>
|
||||
</template>
|
||||
@ -132,6 +132,7 @@ export default {
|
||||
return constants.getGiftShowContent(message, this.showGiftName)
|
||||
},
|
||||
getShowContent: constants.getShowContent,
|
||||
getShowAuthorName: constants.getShowAuthorName,
|
||||
|
||||
addMessage(message) {
|
||||
this.addMessages([message])
|
||||
|
@ -33,6 +33,10 @@ export default {
|
||||
advanced: 'Advanced',
|
||||
relayMessagesByServer: 'Relay messages by server',
|
||||
autoTranslate: 'Auto translate messages to Japanese (requires relay messages by server)',
|
||||
giftUsernamePronunciation: 'Pronunciation of gift username',
|
||||
dontShow: 'None',
|
||||
pinyin: 'Pinyin',
|
||||
kana: 'Kana',
|
||||
|
||||
roomUrl: 'Room URL',
|
||||
copy: 'Copy',
|
||||
|
@ -33,6 +33,10 @@ export default {
|
||||
advanced: 'アドバンスド',
|
||||
relayMessagesByServer: 'サーバを介してメッセージを転送する',
|
||||
autoTranslate: 'コメントを日本語に翻訳する(サーバを介してメッセージを転送する必要)',
|
||||
giftUsernamePronunciation: 'スーパーチャットのユーザー名の発音',
|
||||
dontShow: '非表示',
|
||||
pinyin: 'ピンイン',
|
||||
kana: '仮名',
|
||||
|
||||
roomUrl: 'ルームのURL',
|
||||
copy: 'コピー',
|
||||
|
@ -33,6 +33,10 @@ export default {
|
||||
advanced: '高级',
|
||||
relayMessagesByServer: '通过服务器转发消息',
|
||||
autoTranslate: '自动翻译弹幕到日语(需要通过服务器转发消息)',
|
||||
giftUsernamePronunciation: '标注打赏用户名读音',
|
||||
dontShow: '不显示',
|
||||
pinyin: '拼音',
|
||||
kana: '日文假名',
|
||||
|
||||
roomUrl: '房间URL',
|
||||
copy: '复制',
|
||||
|
@ -36,7 +36,7 @@ export default {
|
||||
hideSidebar: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.onResize)
|
||||
this.onResize()
|
||||
},
|
||||
|
@ -3,7 +3,8 @@ import VueRouter from 'vue-router'
|
||||
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
|
||||
Input, Main, Menu, MenuItem, Message, Radio, RadioGroup, Row, Scrollbar, Slider, Submenu, Switch,
|
||||
TabPane, Tabs, Tooltip
|
||||
} from 'element-ui'
|
||||
import axios from 'axios'
|
||||
|
||||
@ -42,6 +43,8 @@ Vue.use(Input)
|
||||
Vue.use(Main)
|
||||
Vue.use(Menu)
|
||||
Vue.use(MenuItem)
|
||||
Vue.use(Radio)
|
||||
Vue.use(RadioGroup)
|
||||
Vue.use(Row)
|
||||
Vue.use(Scrollbar)
|
||||
Vue.use(Slider)
|
||||
|
20902
frontend/src/utils/pronunciation/dictKana.js
Normal file
20902
frontend/src/utils/pronunciation/dictKana.js
Normal file
File diff suppressed because it is too large
Load Diff
20902
frontend/src/utils/pronunciation/dictPinyin.js
Normal file
20902
frontend/src/utils/pronunciation/dictPinyin.js
Normal file
File diff suppressed because it is too large
Load Diff
54
frontend/src/utils/pronunciation/index.js
Normal file
54
frontend/src/utils/pronunciation/index.js
Normal file
@ -0,0 +1,54 @@
|
||||
export const DICT_PINYIN = 'pinyin'
|
||||
export const DICT_KANA = 'kana'
|
||||
|
||||
export class PronunciationConverter {
|
||||
constructor () {
|
||||
this.pronunciationMap = new Map()
|
||||
}
|
||||
|
||||
async loadDict (dictName) {
|
||||
let promise
|
||||
switch (dictName) {
|
||||
case DICT_PINYIN:
|
||||
promise = import('./dictPinyin')
|
||||
break
|
||||
case DICT_KANA:
|
||||
promise = import('./dictKana')
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
let dictTxt = (await promise).default
|
||||
let pronunciationMap = new Map()
|
||||
for (let item of dictTxt.split('\n')) {
|
||||
if (item.length === 0) {
|
||||
continue
|
||||
}
|
||||
pronunciationMap.set(item.substring(0, 1), item.substring(1))
|
||||
}
|
||||
this.pronunciationMap = pronunciationMap
|
||||
}
|
||||
|
||||
getPronunciation (text) {
|
||||
let res = []
|
||||
let lastHasPronunciation = null
|
||||
for (let char of text) {
|
||||
let pronunciation = this.pronunciationMap.get(char)
|
||||
if (pronunciation === undefined) {
|
||||
if (lastHasPronunciation !== null && lastHasPronunciation) {
|
||||
res.push(' ')
|
||||
}
|
||||
lastHasPronunciation = false
|
||||
res.push(char)
|
||||
} else {
|
||||
if (lastHasPronunciation !== null) {
|
||||
res.push(' ')
|
||||
}
|
||||
lastHasPronunciation = true
|
||||
res.push(pronunciation)
|
||||
}
|
||||
}
|
||||
return res.join('')
|
||||
}
|
||||
}
|
@ -64,6 +64,13 @@
|
||||
<el-form-item :label="$t('home.autoTranslate')">
|
||||
<el-switch v-model="form.autoTranslate" :disabled="!serverConfig.enableTranslate || !form.relayMessagesByServer"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('home.giftUsernamePronunciation')">
|
||||
<el-radio-group v-model="form.giftUsernamePronunciation">
|
||||
<el-radio label="">{{$t('home.dontShow')}}</el-radio>
|
||||
<el-radio label="pinyin">{{$t('home.pinyin')}}</el-radio>
|
||||
<el-radio label="kana">{{$t('home.kana')}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
<script>
|
||||
import {mergeConfig, toBool, toInt} from '@/utils'
|
||||
import * as pronunciation from '@/utils/pronunciation'
|
||||
import * as chatConfig from '@/api/chatConfig'
|
||||
import ChatClientDirect from '@/api/chat/ChatClientDirect'
|
||||
import ChatClientRelay from '@/api/chat/ChatClientRelay'
|
||||
@ -18,7 +19,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
config: {...chatConfig.DEFAULT_CONFIG},
|
||||
chatClient: null
|
||||
chatClient: null,
|
||||
pronunciationConverter: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -29,9 +31,14 @@ export default {
|
||||
return this.config.blockUsers.split('\n').filter(val => val)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
mounted() {
|
||||
this.initConfig()
|
||||
this.initChatClient()
|
||||
if (this.config.giftUsernamePronunciation !== '') {
|
||||
this.pronunciationConverter = new pronunciation.PronunciationConverter()
|
||||
this.pronunciationConverter.loadDict(this.config.giftUsernamePronunciation)
|
||||
}
|
||||
|
||||
// 提示用户已加载
|
||||
this.$message({
|
||||
message: 'Loaded',
|
||||
@ -122,6 +129,7 @@ export default {
|
||||
avatarUrl: data.avatarUrl,
|
||||
time: new Date(data.timestamp * 1000),
|
||||
authorName: data.authorName,
|
||||
authorNamePronunciation: this.getPronunciation(data.authorName),
|
||||
price: price,
|
||||
giftName: data.giftName,
|
||||
num: data.num
|
||||
@ -138,6 +146,7 @@ export default {
|
||||
avatarUrl: data.avatarUrl,
|
||||
time: new Date(data.timestamp * 1000),
|
||||
authorName: data.authorName,
|
||||
authorNamePronunciation: this.getPronunciation(data.authorName),
|
||||
privilegeType: data.privilegeType,
|
||||
title: 'New member'
|
||||
}
|
||||
@ -155,9 +164,11 @@ export default {
|
||||
type: constants.MESSAGE_TYPE_SUPER_CHAT,
|
||||
avatarUrl: data.avatarUrl,
|
||||
authorName: data.authorName,
|
||||
authorNamePronunciation: this.getPronunciation(data.authorName),
|
||||
price: data.price,
|
||||
time: new Date(data.timestamp * 1000),
|
||||
content: data.content.trim()
|
||||
content: data.content.trim(),
|
||||
translation: data.translation
|
||||
}
|
||||
this.$refs.renderer.addMessage(message)
|
||||
},
|
||||
@ -214,6 +225,12 @@ export default {
|
||||
return false
|
||||
}
|
||||
return this.$refs.renderer.mergeSimilarGift(authorName, price, giftName, num)
|
||||
},
|
||||
getPronunciation(text) {
|
||||
if (this.pronunciationConverter === null) {
|
||||
return ''
|
||||
}
|
||||
return this.pronunciationConverter.getPronunciation(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user