mirror of
https://github.com/xfgryujk/blivechat.git
synced 2025-03-13 11:20:42 +08:00
添加生成样式
This commit is contained in:
parent
05180c3acb
commit
e0df7bc3d6
@ -11,6 +11,7 @@
|
||||
"axios": "^0.19.0",
|
||||
"core-js": "^2.6.5",
|
||||
"element-ui": "^2.9.1",
|
||||
"lodash": "^4.17.11",
|
||||
"vue": "^2.6.10",
|
||||
"vue-router": "^3.0.6"
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import {mergeConfig} from '@/utils'
|
||||
|
||||
const DEFAULT_CSS = `@import url("https://fonts.googleapis.com/css?family=Changa%20One");
|
||||
@import url("https://fonts.googleapis.com/css?family=Imprima");
|
||||
/* @import url("https://fonts.lug.ustc.edu.cn/css?family=Changa%20One"); */
|
||||
@ -230,16 +232,8 @@ export const DEFAULT_CONFIG = {
|
||||
css: DEFAULT_CSS
|
||||
}
|
||||
|
||||
function mergeConfig (config) {
|
||||
let res = {}
|
||||
for (let i in DEFAULT_CONFIG) {
|
||||
res[i] = i in config ? config[i] : DEFAULT_CONFIG[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
export function setLocalConfig (config) {
|
||||
config = mergeConfig(config)
|
||||
config = mergeConfig(config, DEFAULT_CONFIG)
|
||||
window.localStorage.config = JSON.stringify(config)
|
||||
}
|
||||
|
||||
@ -247,22 +241,22 @@ export function getLocalConfig () {
|
||||
if (!window.localStorage.config) {
|
||||
return DEFAULT_CONFIG
|
||||
}
|
||||
return mergeConfig(JSON.parse(window.localStorage.config))
|
||||
return mergeConfig(JSON.parse(window.localStorage.config), DEFAULT_CONFIG)
|
||||
}
|
||||
|
||||
export async function createRemoteConfig (config) {
|
||||
config = mergeConfig(config)
|
||||
config = mergeConfig(config, DEFAULT_CONFIG)
|
||||
return (await axios.post('/config', config)).data
|
||||
}
|
||||
|
||||
export async function setRemoteConfig (id, config) {
|
||||
config = mergeConfig(config)
|
||||
config = mergeConfig(config, DEFAULT_CONFIG)
|
||||
return (await axios.put(`/config/${id}`, config)).data
|
||||
}
|
||||
|
||||
export async function getRemoteConfig (id) {
|
||||
let config = (await axios.get(`/config/${id}`)).data
|
||||
return mergeConfig(config)
|
||||
return mergeConfig(config, DEFAULT_CONFIG)
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -7,7 +7,7 @@ import axios from 'axios'
|
||||
import App from './App.vue'
|
||||
import Layout from './layout'
|
||||
import Home from './views/Home.vue'
|
||||
import StyleGenerator from './views/StyleGenerator.vue'
|
||||
import StyleGenerator from './views/StyleGenerator'
|
||||
import Room from './views/Room'
|
||||
import NotFound from './views/NotFound.vue'
|
||||
|
||||
|
11
frontend/src/utils.js
Normal file
11
frontend/src/utils.js
Normal file
@ -0,0 +1,11 @@
|
||||
export function mergeConfig (config, defaultConfig) {
|
||||
let res = {}
|
||||
for (let i in defaultConfig) {
|
||||
res[i] = i in config ? config[i] : defaultConfig[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
export default {
|
||||
mergeConfig
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
<el-switch v-model="form.mergeSimilarDanmaku"></el-switch>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="屏蔽">
|
||||
<el-form-item label="礼物弹幕" prop="blockGiftDanmaku">
|
||||
<el-switch v-model="form.blockGiftDanmaku"></el-switch>
|
||||
@ -37,19 +38,21 @@
|
||||
<el-input v-model="form.blockUsers" type="textarea" :rows="5" placeholder="一行一个"></el-input>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="样式">
|
||||
<el-form-item label="CSS" prop="css">
|
||||
<el-input v-model="form.css" type="textarea" :rows="20"></el-input>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="房间URL" v-show="roomUrl">
|
||||
<el-input ref="roomUrlInput" readonly :value="roomUrl" style="width: calc(100% - 6em); margin-right: 1em;"></el-input>
|
||||
<el-button type="primary" @click="copyUrl">复制</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="saveConfig()">保存配置</el-button>
|
||||
<el-button type="primary" @click="saveConfig">保存配置</el-button>
|
||||
<el-button type="primary" :disabled="!roomUrl" @click="enterRoom">进入房间</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
@ -1,9 +0,0 @@
|
||||
<template>
|
||||
<p>WIP</p>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'StyleGenerator'
|
||||
}
|
||||
</script>
|
14
frontend/src/views/StyleGenerator/fonts.js
Normal file
14
frontend/src/views/StyleGenerator/fonts.js
Normal file
File diff suppressed because one or more lines are too long
246
frontend/src/views/StyleGenerator/index.vue
Normal file
246
frontend/src/views/StyleGenerator/index.vue
Normal file
@ -0,0 +1,246 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form label-width="150px" size="mini">
|
||||
<h3>描边</h3>
|
||||
<el-form-item label="显示描边">
|
||||
<el-switch v-model="form.showOutlines"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="描边尺寸">
|
||||
<el-input v-model.number="form.outlineSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描边颜色">
|
||||
<el-color-picker v-model="form.outlineColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
|
||||
<h3>头像</h3>
|
||||
<el-form-item label="显示头像">
|
||||
<el-switch v-model="form.showAvatars"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="头像尺寸">
|
||||
<el-input v-model.number="form.avatarSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<h3>用户名</h3>
|
||||
<el-form-item label="字体">
|
||||
<el-autocomplete v-model="form.userNameFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体尺寸">
|
||||
<el-input v-model.number="form.userNameFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="行高(0为默认)">
|
||||
<el-input v-model.number="form.userNameLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="普通颜色">
|
||||
<el-color-picker v-model="form.userNameColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="主播颜色">
|
||||
<el-color-picker v-model="form.ownerUserNameColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="房管颜色">
|
||||
<el-color-picker v-model="form.moderatorUserNameColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="舰长颜色">
|
||||
<el-color-picker v-model="form.memberUserNameColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示勋章">
|
||||
<el-switch v-model="form.showBadges"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户名后显示冒号">
|
||||
<el-switch v-model="form.showColon"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<h3>消息</h3>
|
||||
<el-form-item label="字体">
|
||||
<el-autocomplete v-model="form.messageFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体尺寸">
|
||||
<el-input v-model.number="form.messageFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="行高(0为默认)">
|
||||
<el-input v-model.number="form.messageLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="颜色">
|
||||
<el-color-picker v-model="form.messageColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="在新行显示">
|
||||
<el-switch v-model="form.messageOnNewLine"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<h3>时间</h3>
|
||||
<el-form-item label="显示时间">
|
||||
<el-switch v-model="form.showTime"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体">
|
||||
<el-autocomplete v-model="form.timeFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体尺寸">
|
||||
<el-input v-model.number="form.timeFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="行高(0为默认)">
|
||||
<el-input v-model.number="form.timeLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="颜色">
|
||||
<el-color-picker v-model="form.timeColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
|
||||
<h3>背景</h3>
|
||||
<el-form-item label="背景色">
|
||||
<el-color-picker v-model="form.bgColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="用条代替背景">
|
||||
<el-switch v-model="form.useBarsInsteadOfBg"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="消息背景色">
|
||||
<el-color-picker v-model="form.messageBgColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="主播消息背景色">
|
||||
<el-color-picker v-model="form.ownerMessageBgColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="房管消息背景色">
|
||||
<el-color-picker v-model="form.moderatorMessageBgColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="舰长消息背景色">
|
||||
<el-color-picker v-model="form.memberMessageBgColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
|
||||
<h3>礼物、舰长</h3>
|
||||
<el-form-item label="第一行字体">
|
||||
<el-autocomplete v-model="form.firstLineFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="第一行字体尺寸">
|
||||
<el-input v-model.number="form.firstLineFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="第一行行高(0为默认)">
|
||||
<el-input v-model.number="form.firstLineLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="第一行颜色">
|
||||
<el-color-picker v-model="form.firstLineColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二行字体">
|
||||
<el-autocomplete v-model="form.secondLineFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二行字体尺寸">
|
||||
<el-input v-model.number="form.secondLineFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二行行高(0为默认)">
|
||||
<el-input v-model.number="form.secondLineLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="第二行颜色">
|
||||
<el-color-picker v-model="form.secondLineColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="SuperChat内容字体">
|
||||
<el-autocomplete v-model="form.scContentFont" :fetch-suggestions="getFontSuggestions"></el-autocomplete>
|
||||
</el-form-item>
|
||||
<el-form-item label="SuperChat字体尺寸">
|
||||
<el-input v-model.number="form.scContentFontSize" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="SuperChat行高(0为默认)">
|
||||
<el-input v-model.number="form.scContentLineHeight" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="SuperChat颜色">
|
||||
<el-color-picker v-model="form.scContentColor"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示新舰长背景">
|
||||
<el-switch v-model="form.showNewMemberBg"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示SuperChat贴纸">
|
||||
<el-switch v-model="form.showScTicker"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示SuperChat贴纸之外的内容">
|
||||
<el-switch v-model="form.showOtherThings"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<h3>动画</h3>
|
||||
<el-form-item label="进入动画">
|
||||
<el-switch v-model="form.animateIn"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="淡入时间(毫秒)">
|
||||
<el-input v-model.number="form.fadeInTime" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="移除旧消息">
|
||||
<el-switch v-model="form.animateOut"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="等待时间(秒)">
|
||||
<el-input v-model.number="form.animateOutWaitTime" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="淡出时间(毫秒)">
|
||||
<el-input v-model.number="form.fadeOutTime" type="number" min="0"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="滑动">
|
||||
<el-switch v-model="form.slide"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="反向滑动">
|
||||
<el-switch v-model="form.reverseSlide"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<h3>结果</h3>
|
||||
<el-form-item label="CSS">
|
||||
<el-input v-model="result" ref="result" type="textarea" :rows="10"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="copyResult">复制</el-button>
|
||||
<el-button @click="resetConfig">恢复默认设置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
预览
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash'
|
||||
|
||||
import stylegen from './stylegen'
|
||||
import fonts from './fonts'
|
||||
|
||||
export default {
|
||||
name: 'StyleGenerator',
|
||||
data() {
|
||||
let config = stylegen.getLocalConfig()
|
||||
return {
|
||||
FONTS: [...fonts.LOCAL_FONTS, ...fonts.NETWORK_FONTS],
|
||||
form: {...config},
|
||||
result: stylegen.getStyle(config)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
computedResult() {
|
||||
return stylegen.getStyle(this.form)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getFontSuggestions(query, callback) {
|
||||
let res = this.FONTS.map(font => {return {value: font}})
|
||||
if (query) {
|
||||
query = query.toLowerCase()
|
||||
res = res.filter(
|
||||
font => font.value.toLowerCase().indexOf(query) !== -1
|
||||
)
|
||||
}
|
||||
callback(res)
|
||||
},
|
||||
copyResult() {
|
||||
this.$refs.result.select()
|
||||
document.execCommand('Copy')
|
||||
},
|
||||
resetConfig() {
|
||||
this.form = {...stylegen.DEFAULT_CONFIG}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
computedResult: _.debounce(function (result) {
|
||||
this.result = result
|
||||
stylegen.setLocalConfig(this.form)
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-form {
|
||||
max-width: 800px;
|
||||
}
|
||||
</style>
|
408
frontend/src/views/StyleGenerator/stylegen.js
Normal file
408
frontend/src/views/StyleGenerator/stylegen.js
Normal file
@ -0,0 +1,408 @@
|
||||
import {mergeConfig} from '@/utils'
|
||||
import fonts from './fonts'
|
||||
|
||||
export const DEFAULT_CONFIG = {
|
||||
showOutlines: true,
|
||||
outlineSize: 2,
|
||||
outlineColor: '#000000',
|
||||
|
||||
showAvatars: true,
|
||||
avatarSize: 24,
|
||||
|
||||
userNameFont: 'Changa One',
|
||||
userNameFontSize: 20,
|
||||
userNameLineHeight: 0,
|
||||
userNameColor: '#cccccc',
|
||||
ownerUserNameColor: '#ffd600',
|
||||
moderatorUserNameColor: '#5e84f1',
|
||||
memberUserNameColor: '#0f9d58',
|
||||
showBadges: false,
|
||||
showColon: true,
|
||||
|
||||
messageFont: 'Imprima',
|
||||
messageFontSize: 18,
|
||||
messageLineHeight: 0,
|
||||
messageColor: '#ffffff',
|
||||
messageOnNewLine: false,
|
||||
|
||||
showTime: false,
|
||||
timeFont: 'Imprima',
|
||||
timeFontSize: 16,
|
||||
timeLineHeight: 0,
|
||||
timeColor: '#999999',
|
||||
|
||||
bgColor: '#000000',
|
||||
useBarsInsteadOfBg: false,
|
||||
messageBgColor: '#cccccc',
|
||||
ownerMessageBgColor: '#ffd600',
|
||||
moderatorMessageBgColor: '#5e84f1',
|
||||
memberMessageBgColor: '#0f9d58',
|
||||
|
||||
firstLineFont: 'Changa One',
|
||||
firstLineFontSize: 20,
|
||||
firstLineLineHeight: 0,
|
||||
firstLineColor: '#ffffff',
|
||||
secondLineFont: 'Imprima',
|
||||
secondLineFontSize: 18,
|
||||
secondLineLineHeight: 0,
|
||||
secondLineColor: '#ffffff',
|
||||
scContentFont: 'Imprima',
|
||||
scContentFontSize: 28,
|
||||
scContentLineHeight: 0,
|
||||
scContentColor: '#ffffff',
|
||||
showNewMemberBg: true,
|
||||
showScTicker: false,
|
||||
showOtherThings: true,
|
||||
|
||||
animateIn: false,
|
||||
fadeInTime: 200, // ms
|
||||
animateOut: false,
|
||||
animateOutWaitTime: 30, // s
|
||||
fadeOutTime: 200, // ms
|
||||
slide: false,
|
||||
reverseSlide: false
|
||||
}
|
||||
|
||||
export function setLocalConfig (config) {
|
||||
config = mergeConfig(config, DEFAULT_CONFIG)
|
||||
window.localStorage.stylegenConfig = JSON.stringify(config)
|
||||
}
|
||||
|
||||
export function getLocalConfig () {
|
||||
if (!window.localStorage.stylegenConfig) {
|
||||
return DEFAULT_CONFIG
|
||||
}
|
||||
return mergeConfig(JSON.parse(window.localStorage.stylegenConfig), DEFAULT_CONFIG)
|
||||
}
|
||||
|
||||
export function getStyle (config) {
|
||||
config = mergeConfig(config, DEFAULT_CONFIG)
|
||||
return `${getImports(config)}
|
||||
|
||||
/* Background colors */
|
||||
body {
|
||||
overflow: hidden;
|
||||
${config.bgColor ? `background-color: ${config.bgColor};` : ''}
|
||||
}
|
||||
|
||||
/* Transparent background. */
|
||||
yt-live-chat-renderer {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
${getMessageColorStyle('', config.messageBgColor, config.useBarsInsteadOfBg)}
|
||||
|
||||
${getMessageColorStyle('owner', config.ownerMessageBgColor, config.useBarsInsteadOfBg)}
|
||||
|
||||
${getMessageColorStyle('moderator', config.moderatorMessageBgColor, config.useBarsInsteadOfBg)}
|
||||
|
||||
${getMessageColorStyle('member', config.memberMessageBgColor, config.useBarsInsteadOfBg)}
|
||||
|
||||
yt-live-chat-author-chip #author-name {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Outlines */
|
||||
yt-live-chat-renderer * {
|
||||
${getShowOutlinesStyle(config)}
|
||||
font-family: "${config.messageFont}", sans-serif;
|
||||
font-size: ${config.messageFontSize}px !important;
|
||||
line-height: ${config.messageLineHeight}px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #content,
|
||||
yt-live-chat-legacy-paid-message-renderer #content {
|
||||
overflow: initial !important;
|
||||
}
|
||||
|
||||
/* Hide scrollbar. */
|
||||
yt-live-chat-item-list-renderer #items{
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
yt-live-chat-item-list-renderer #item-scroller{
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* Hide header and input. */
|
||||
yt-live-chat-header-renderer,
|
||||
yt-live-chat-message-input-renderer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Reduce side padding. */
|
||||
yt-live-chat-text-message-renderer,
|
||||
yt-live-chat-legacy-paid-message-renderer {
|
||||
${getPaddingStyle(config)}
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #header {
|
||||
${getPaddingStyle(config)}
|
||||
}
|
||||
|
||||
/* Avatars. */
|
||||
yt-live-chat-text-message-renderer #author-photo,
|
||||
yt-live-chat-paid-message-renderer #author-photo,
|
||||
yt-live-chat-legacy-paid-message-renderer #author-photo {
|
||||
${config.showAvatars ? '' : 'display: none !important;'}
|
||||
width: ${config.avatarSize}px !important;
|
||||
height: ${config.avatarSize}px !important;
|
||||
border-radius: ${config.avatarSize}px !important;
|
||||
margin-right: ${config.avatarSize / 4}px !important;
|
||||
}
|
||||
|
||||
/* Hide badges. */
|
||||
yt-live-chat-text-message-renderer #author-badges {
|
||||
${config.showBadges ? '' : 'display: none !important;'}
|
||||
vertical-align: text-top !important;
|
||||
}
|
||||
|
||||
/* Timestamps. */
|
||||
yt-live-chat-text-message-renderer #timestamp {
|
||||
${config.showTime ? '' : 'display: none !important;'}
|
||||
${config.timeColor ? `color: ${config.timeColor} !important;` : ''}
|
||||
font-family: "${config.timeFont}", sans-serif;
|
||||
font-size: ${config.timeFontSize}px !important;
|
||||
line-height: ${config.timeLineHeight || config.timeFontSize}px !important;
|
||||
}
|
||||
|
||||
/* Badges. */
|
||||
yt-live-chat-text-message-renderer #author-name[type="owner"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="owner"] {
|
||||
${config.ownerUserNameColor ? `color: ${config.ownerUserNameColor} !important;` : ''}
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name[type="moderator"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="moderator"] {
|
||||
${config.moderatorUserNameColor ? `color: ${config.moderatorUserNameColor} !important;` : ''}
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer #author-name[type="member"],
|
||||
yt-live-chat-text-message-renderer yt-live-chat-author-badge-renderer[type="member"] {
|
||||
${config.memberUserNameColor ? `color: ${config.memberUserNameColor} !important;` : ''}
|
||||
}
|
||||
|
||||
/* Channel names. */
|
||||
yt-live-chat-text-message-renderer #author-name {
|
||||
${config.userNameColor ? `color: ${config.userNameColor} !important;` : ''}
|
||||
font-family: "${config.userNameFont}", sans-serif;
|
||||
font-size: ${config.userNameFontSize}px !important;
|
||||
line-height: ${config.userNameLineHeight || config.userNameFontSize}px !important;
|
||||
}
|
||||
|
||||
${getShowColonStyle(config)}
|
||||
|
||||
/* Messages. */
|
||||
yt-live-chat-text-message-renderer #message,
|
||||
yt-live-chat-text-message-renderer #message * {
|
||||
${config.messageColor ? `color: ${config.messageColor} !important;` : ''}
|
||||
font-family: "${config.messageFont}", sans-serif;
|
||||
font-size: ${config.messageFontSize}px !important;
|
||||
line-height: ${config.messageLineHeight || config.messageFontSize}px !important;
|
||||
}
|
||||
|
||||
${!config.messageOnNewLine ? '' : `yt-live-chat-text-message-renderer #message {
|
||||
display: block !important;
|
||||
}`}
|
||||
|
||||
/* SuperChat/Fan Funding Messages. */
|
||||
yt-live-chat-paid-message-renderer #author-name,
|
||||
yt-live-chat-paid-message-renderer #author-name *,
|
||||
yt-live-chat-legacy-paid-message-renderer #event-text,
|
||||
yt-live-chat-legacy-paid-message-renderer #event-text * {
|
||||
${config.firstLineColor ? `color: ${config.firstLineColor} !important;` : ''}
|
||||
font-family: "${config.firstLineFont}", sans-serif;
|
||||
font-size: ${config.firstLineFontSize}px !important;
|
||||
line-height: ${config.firstLineLineHeight || config.firstLineFontSize}px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #purchase-amount,
|
||||
yt-live-chat-paid-message-renderer #purchase-amount *,
|
||||
yt-live-chat-legacy-paid-message-renderer #detail-text,
|
||||
yt-live-chat-legacy-paid-message-renderer #detail-text * {
|
||||
${config.secondLineColor ? `color: ${config.secondLineColor} !important;` : ''}
|
||||
font-family: "${config.secondLineFont}", sans-serif;
|
||||
font-size: ${config.secondLineFontSize}px !important;
|
||||
line-height: ${config.secondLineLineHeight || config.secondLineFontSize}px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer #content,
|
||||
yt-live-chat-paid-message-renderer #content * {
|
||||
${config.scContentColor ? `color: ${config.scContentColor} !important;` : ''}
|
||||
font-family: "${config.scContentFont}", sans-serif;
|
||||
font-size: ${config.scContentFontSize}px !important;
|
||||
line-height: ${config.scContentLineHeight || config.scContentFontSize}px !important;
|
||||
}
|
||||
|
||||
yt-live-chat-paid-message-renderer {
|
||||
margin: 4px 0 !important;
|
||||
}
|
||||
|
||||
yt-live-chat-legacy-paid-message-renderer #card {
|
||||
${getShowNewMemberBgStyle(config)}
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer a,
|
||||
yt-live-chat-legacy-paid-message-renderer a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer[is-deleted],
|
||||
yt-live-chat-legacy-paid-message-renderer[is-deleted] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
yt-live-chat-ticker-renderer {
|
||||
background-color: transparent !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
${config.showScTicker ? '' : `yt-live-chat-ticker-renderer {
|
||||
display: none !important;
|
||||
}`}
|
||||
|
||||
${config.showOtherThings ? '' : `yt-live-chat-item-list-renderer {
|
||||
display: none !important;
|
||||
}`}
|
||||
|
||||
yt-live-chat-ticker-paid-message-item-renderer,
|
||||
yt-live-chat-ticker-paid-message-item-renderer *,
|
||||
yt-live-chat-ticker-sponsor-item-renderer,
|
||||
yt-live-chat-ticker-sponsor-item-renderer * {
|
||||
${config.secondLineColor ? `color: ${config.secondLineColor} !important;` : ''}
|
||||
font-family: "${config.secondLineFont}", sans-serif;
|
||||
}
|
||||
|
||||
yt-live-chat-mode-change-message-renderer,
|
||||
yt-live-chat-viewer-engagement-message-renderer,
|
||||
yt-live-chat-restricted-participation-renderer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
${getAnimationStyle(config)}
|
||||
`
|
||||
}
|
||||
|
||||
function getImports (config) {
|
||||
let fontsNeedToImport = new Set()
|
||||
for (let name of ['userNameFont', 'messageFont', 'timeFont', 'firstLineFont', 'secondLineFont', 'scContentFont']) {
|
||||
let font = config[name]
|
||||
if (fonts.NETWORK_FONTS.indexOf(font) !== -1) {
|
||||
fontsNeedToImport.add(font)
|
||||
}
|
||||
}
|
||||
let res = []
|
||||
for (let font of fontsNeedToImport) {
|
||||
res.push(`@import url("https://fonts.googleapis.com/css?family=${encodeURIComponent(font)}");`)
|
||||
}
|
||||
return res.join('\n')
|
||||
}
|
||||
|
||||
function getMessageColorStyle (authorType, color, useBarsInsteadOfBg) {
|
||||
let typeSelector = authorType ? `[author-type="${authorType}"]` : ''
|
||||
if (!useBarsInsteadOfBg) {
|
||||
return `yt-live-chat-text-message-renderer${typeSelector},
|
||||
yt-live-chat-text-message-renderer${typeSelector}[is-highlighted] {
|
||||
${color ? `background-color: ${color} !important;` : ''}
|
||||
}`
|
||||
} else {
|
||||
return `yt-live-chat-text-message-renderer${typeSelector}::after {
|
||||
${color ? `border: 2px solid ${color};` : ''}
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 8px;
|
||||
top: 4px;
|
||||
bottom: 4px;
|
||||
width: 1px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 2px;
|
||||
}`
|
||||
}
|
||||
}
|
||||
|
||||
function getShowOutlinesStyle (config) {
|
||||
if (!config.showOutlines || !config.outlineSize) {
|
||||
return ''
|
||||
}
|
||||
let shadow = []
|
||||
for (var x = -config.outlineSize; x <= config.outlineSize; x += Math.ceil(config.outlineSize / 4)) {
|
||||
for (var y = -config.outlineSize; y <= config.outlineSize; y += Math.ceil(config.outlineSize / 4)) {
|
||||
shadow.push(`${x}px ${y}px ${config.outlineColor}`)
|
||||
}
|
||||
}
|
||||
return `text-shadow: ${shadow.join(', ')};`
|
||||
}
|
||||
|
||||
function getPaddingStyle (config) {
|
||||
return `padding-left: ${config.useBarsInsteadOfBg ? 20 : 4}px !important;
|
||||
padding-right: 4px !important;`
|
||||
}
|
||||
|
||||
function getShowColonStyle (config) {
|
||||
if (!config.showColon) {
|
||||
return ''
|
||||
}
|
||||
return `yt-live-chat-text-message-renderer #author-name::after {
|
||||
content: ":";
|
||||
margin-left: ${config.outlineSize}px;
|
||||
}`
|
||||
}
|
||||
|
||||
function getShowNewMemberBgStyle (config) {
|
||||
if (config.showNewMemberBg) {
|
||||
return `background-color: ${config.memberUserNameColor} !important;
|
||||
margin: 4px 0 !important;`
|
||||
} else {
|
||||
return `background-color: transparent !important;
|
||||
box-shadow: none !important;
|
||||
margin: 0 !important;`
|
||||
}
|
||||
}
|
||||
|
||||
function getAnimationStyle (config) {
|
||||
if (!config.animateIn && !config.animateOut) {
|
||||
return ''
|
||||
}
|
||||
let totalTime = 0
|
||||
if (config.animateIn) {
|
||||
totalTime += config.fadeInTime
|
||||
}
|
||||
if (config.animateOut) {
|
||||
totalTime += config.animateOutWaitTime * 1000
|
||||
totalTime += config.fadeOutTime
|
||||
}
|
||||
let keyframes = []
|
||||
let curTime = 0
|
||||
if (config.animateIn) {
|
||||
keyframes.push(` 0% { opacity: 0;${!config.slide ? ''
|
||||
: ` transform: translateX(${config.reverseSlide ? 16 : -16}px);`
|
||||
} }`)
|
||||
curTime += config.fadeInTime
|
||||
keyframes.push(` ${(curTime / totalTime) * 100}% { opacity: 1; transform: none;}`)
|
||||
}
|
||||
if (config.animateOut) {
|
||||
curTime += config.animateOutWaitTime * 1000
|
||||
keyframes.push(` ${(curTime / totalTime) * 100}% { opacity: 1; transform: none;}`)
|
||||
curTime += config.fadeOutTime
|
||||
keyframes.push(` ${(curTime / totalTime) * 100}% { opacity: 0;${!config.slide ? ''
|
||||
: ` transform: translateX(${config.reverseSlide ? -16 : 16}px);`
|
||||
} }`)
|
||||
}
|
||||
return `@keyframes anim {
|
||||
${keyframes.join('\n')}
|
||||
}
|
||||
|
||||
yt-live-chat-text-message-renderer,
|
||||
yt-live-chat-legacy-paid-message-renderer {
|
||||
animation: anim ${totalTime}ms;
|
||||
animation-fill-mode: both;
|
||||
}`
|
||||
}
|
||||
|
||||
export default {
|
||||
DEFAULT_CONFIG,
|
||||
setLocalConfig,
|
||||
getLocalConfig,
|
||||
getStyle
|
||||
}
|
Loading…
Reference in New Issue
Block a user