diff --git a/.dockerignore b/.dockerignore
index dd66663..a29df70 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -21,4 +21,8 @@ data/*
!data/emoticons/
data/emoticons/*
!data/emoticons/.gitkeep
+!data/custom_public/
+data/custom_public/*
+!data/custom_public/README.txt
+!data/custom_public/preset.css
log/*
diff --git a/.gitignore b/.gitignore
index 99e4566..7562b96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -110,4 +110,8 @@ data/*
!data/emoticons/
data/emoticons/*
!data/emoticons/.gitkeep
+!data/custom_public/
+data/custom_public/*
+!data/custom_public/README.txt
+!data/custom_public/preset.css
log/*
diff --git a/api/main.py b/api/main.py
index b331baf..3bdb50f 100644
--- a/api/main.py
+++ b/api/main.py
@@ -14,6 +14,7 @@ logger = logging.getLogger(__name__)
EMOTICON_UPLOAD_PATH = os.path.join(config.DATA_PATH, 'emoticons')
EMOTICON_BASE_URL = '/emoticons'
+CUSTOM_PUBLIC_PATH = os.path.join(config.DATA_PATH, 'custom_public')
class MainHandler(tornado.web.StaticFileHandler):
@@ -85,6 +86,11 @@ class UploadEmoticonHandler(api.base.ApiHandler):
return f'{EMOTICON_BASE_URL}/{filename}'
+class NoCacheStaticFileHandler(tornado.web.StaticFileHandler):
+ def set_extra_headers(self, path):
+ self.set_header('Cache-Control', 'no-cache')
+
+
ROUTES = [
(r'/api/server_info', ServerInfoHandler),
(r'/api/emoticon', UploadEmoticonHandler),
@@ -92,5 +98,7 @@ ROUTES = [
# 通配的放在最后
LAST_ROUTES = [
(rf'{EMOTICON_BASE_URL}/(.*)', tornado.web.StaticFileHandler, {'path': EMOTICON_UPLOAD_PATH}),
+ # 这个目录不保证文件内容不会变,还是不用缓存了
+ (r'/custom_public/(.*)', NoCacheStaticFileHandler, {'path': CUSTOM_PUBLIC_PATH}),
(r'/(.*)', MainHandler, {'path': config.WEB_ROOT}),
]
diff --git a/data/custom_public/README.txt b/data/custom_public/README.txt
new file mode 100644
index 0000000..34edfae
--- /dev/null
+++ b/data/custom_public/README.txt
@@ -0,0 +1,7 @@
+这个目录用来暴露一些自定义文件给前端,例如图片、CSS、字体等
+你可以在网页路径 /custom_public/README.txt 访问到这个文件
+警告:不要在这个目录里存放密钥等敏感信息,因为可能会被远程访问
+
+This directory is used to expose some custom files to the front end, such as images, CSS, fonts, etc.
+You can access this file on the web path: /custom_public/README.txt
+WARNING: DO NOT store sensitive information such as secrets in this directory, because it may be accessed by remote
diff --git a/data/custom_public/preset.css b/data/custom_public/preset.css
new file mode 100644
index 0000000..b9f3396
--- /dev/null
+++ b/data/custom_public/preset.css
@@ -0,0 +1,8 @@
+/*
+这是服务器预设CSS文件
+前端可以通过“导入服务器预设CSS”选项自动导入这个CSS,而不需要在OBS里面设置自定义CSS
+
+This is the server preset CSS file
+The front end can automatically import this CSS through the "Import the server preset CSS" option,
+instead of setting the custom CSS in OBS
+*/
diff --git a/frontend/src/api/chatConfig.js b/frontend/src/api/chatConfig.js
index bde941f..a508936 100644
--- a/frontend/src/api/chatConfig.js
+++ b/frontend/src/api/chatConfig.js
@@ -22,6 +22,7 @@ export const DEFAULT_CONFIG = {
relayMessagesByServer: false,
autoTranslate: false,
giftUsernamePronunciation: '',
+ importPresetCss: false,
emoticons: [] // [{ keyword: '', url: '' }, ...]
}
diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js
index 09fed42..3a9e013 100644
--- a/frontend/src/lang/en.js
+++ b/frontend/src/lang/en.js
@@ -48,6 +48,8 @@ export default {
dontShow: 'None',
pinyin: 'Pinyin',
kana: 'Kana',
+ importPresetCss: 'Import the server preset CSS',
+ importPresetCssTip: 'Automatically import the server CSS file: data/custom_public/preset.css',
emoticon: 'Custom Emotes',
emoticonKeyword: 'Emote Code',
diff --git a/frontend/src/lang/ja.js b/frontend/src/lang/ja.js
index f8f6db6..779720f 100644
--- a/frontend/src/lang/ja.js
+++ b/frontend/src/lang/ja.js
@@ -48,6 +48,8 @@ export default {
dontShow: '非表示',
pinyin: 'ピンイン',
kana: '仮名',
+ importPresetCss: 'サーバープリセットのCSSをインポートする',
+ importPresetCssTip: 'サーバーのCSSファイル「data/custom_public/preset.css」を自動的にインポートする',
emoticon: 'カスタムスタンプ',
emoticonKeyword: '置き換えるキーワード',
diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js
index 4e6821c..c7789af 100644
--- a/frontend/src/lang/zh.js
+++ b/frontend/src/lang/zh.js
@@ -48,6 +48,8 @@ export default {
dontShow: '不显示',
pinyin: '拼音',
kana: '日文假名',
+ importPresetCss: '导入服务器预设CSS',
+ importPresetCssTip: '自动导入服务器的CSS文件:data/custom_public/preset.css',
emoticon: '自定义表情',
emoticonKeyword: '替换关键词',
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index dd25f5f..7b7ce95 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -170,6 +170,15 @@
{{$t('home.kana')}}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/Room.vue b/frontend/src/views/Room.vue
index 46dbee0..2510938 100644
--- a/frontend/src/views/Room.vue
+++ b/frontend/src/views/Room.vue
@@ -43,6 +43,7 @@ export default {
pronunciationConverter: null,
customStyleElement, // 仅用于样式生成器中预览样式
+ presetCssLinkElement: null,
}
},
computed: {
@@ -92,6 +93,9 @@ export default {
}
document.head.removeChild(this.customStyleElement)
+ if (this.presetCssLinkElement) {
+ document.head.removeChild(this.presetCssLinkElement)
+ }
},
methods: {
onVisibilityChange() {
@@ -110,6 +114,12 @@ export default {
this.pronunciationConverter = new pronunciation.PronunciationConverter()
this.pronunciationConverter.loadDict(this.config.giftUsernamePronunciation)
}
+ if (this.config.importPresetCss) {
+ this.presetCssLinkElement = document.createElement('link')
+ this.presetCssLinkElement.rel = 'stylesheet'
+ this.presetCssLinkElement.href = '/custom_public/preset.css'
+ document.head.appendChild(this.presetCssLinkElement)
+ }
try {
// 其他初始化就不用等了,就算失败了也不会有很大影响
@@ -159,6 +169,8 @@ export default {
cfg.relayMessagesByServer = toBool(cfg.relayMessagesByServer)
cfg.autoTranslate = toBool(cfg.autoTranslate)
+ cfg.importPresetCss = toBool(cfg.importPresetCss)
+
cfg.emoticons = this.toObjIfJson(cfg.emoticons)
chatConfig.sanitizeConfig(cfg)
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index 8d76b39..5cf51a3 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -10,7 +10,10 @@ module.exports = {
},
'/emoticons': {
target: API_BASE_URL
- }
+ },
+ '/custom_public': {
+ target: API_BASE_URL
+ },
}
},
chainWebpack: config => {