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 => {