添加自定义模板缩略图

This commit is contained in:
John Smith
2025-04-06 18:35:10 +08:00
parent 22d80e3af2
commit 8c3dfa902c
3 changed files with 87 additions and 46 deletions

View File

@@ -117,8 +117,7 @@ class TemplatesHandler(api.base.ApiHandler):
self.set_header('Cache-Control', 'private, max-age=10') self.set_header('Cache-Control', 'private, max-age=10')
self.write({'templates': templates}) self.write({'templates': templates})
@staticmethod def _get_templates(self):
def _get_templates():
template_ids = [] template_ids = []
try: try:
with os.scandir(TEMPLATE_PATH) as it: with os.scandir(TEMPLATE_PATH) as it:
@@ -134,19 +133,36 @@ class TemplatesHandler(api.base.ApiHandler):
templates = [] templates = []
for template_id in template_ids: for template_id in template_ids:
try: try:
template = self._load_template_config(template_id)
templates.append(template)
except (OSError, json.JSONDecodeError, TypeError, ValueError):
logger.exception('template_id=%s failed to load config:', template_id)
return templates
@staticmethod
def _load_template_config(template_id):
config_path = os.path.join(TEMPLATE_PATH, template_id, 'template.json') config_path = os.path.join(TEMPLATE_PATH, template_id, 'template.json')
with open(config_path, encoding='utf-8') as f: with open(config_path, encoding='utf-8') as f:
cfg = json.load(f) cfg = json.load(f)
if not isinstance(cfg, dict): if not isinstance(cfg, dict):
raise TypeError(f'Config type error, type={type(cfg)}') raise TypeError(f'Config type error, type={type(cfg)}')
url_str = str(cfg.get('url', ''))
url = yarl.URL(url_str)
if not url.absolute:
# 相对于模板目录 # 相对于模板目录
base_url = yarl.URL(f'{TEMPLATE_BASE_URL}/{template_id}/') base_url = yarl.URL(f'{TEMPLATE_BASE_URL}/{template_id}/')
url = base_url.join(url)
url_str = str(url) def ensure_abs_url(url_str_):
url_ = yarl.URL(url_str_)
if not url_.absolute:
url_ = base_url.join(url_)
url_str_ = str(url_)
return url_str_
thumbnail_url_str = str(cfg.get('thumbnail', ''))
if thumbnail_url_str != '':
thumbnail_url_str = ensure_abs_url(thumbnail_url_str)
url_str = str(cfg.get('url', ''))
url_str = ensure_abs_url(url_str)
template = { template = {
'id': template_id, 'id': template_id,
@@ -154,12 +170,10 @@ class TemplatesHandler(api.base.ApiHandler):
'version': str(cfg.get('version', '')), 'version': str(cfg.get('version', '')),
'author': str(cfg.get('author', '')), 'author': str(cfg.get('author', '')),
'description': str(cfg.get('description', '')), 'description': str(cfg.get('description', '')),
'thumbnail': thumbnail_url_str,
'url': url_str, 'url': url_str,
} }
templates.append(template) return template
except (OSError, json.JSONDecodeError, TypeError, ValueError):
logger.exception('template_id=%s failed to load config:', template_id)
return templates
class NoCacheStaticFileHandler(tornado.web.StaticFileHandler): class NoCacheStaticFileHandler(tornado.web.StaticFileHandler):

View File

@@ -2,15 +2,15 @@
<div> <div>
<h1>{{ $t('help.help') }}</h1> <h1>{{ $t('help.help') }}</h1>
<p>{{ $t('help.p1_1') }} <a href="https://play-live.bilibili.com/" target="_blank">https://play-live.bilibili.com/</a> {{ $t('help.p1_2') }}</p> <p>{{ $t('help.p1_1') }} <a href="https://play-live.bilibili.com/" target="_blank">https://play-live.bilibili.com/</a> {{ $t('help.p1_2') }}</p>
<p class="img-container"><el-image fit="scale-down" src="/static/img/tutorial/tutorial-1.jpg"></el-image></p> <p><el-image lazy src="/static/img/tutorial/tutorial-1.jpg"></el-image></p>
<p>{{ $t('help.p2') }}</p> <p>{{ $t('help.p2') }}</p>
<p class="img-container large-img"><el-image fit="scale-down" src="/static/img/tutorial/tutorial-2.jpg"></el-image></p> <p><el-image lazy src="/static/img/tutorial/tutorial-2.jpg"></el-image></p>
<p>{{ $t('help.p3') }}</p> <p>{{ $t('help.p3') }}</p>
<p class="img-container large-img"><el-image fit="scale-down" src="/static/img/tutorial/tutorial-3.jpg"></el-image></p> <p><el-image lazy src="/static/img/tutorial/tutorial-3.jpg"></el-image></p>
<p>{{ $t('help.p4') }}</p> <p>{{ $t('help.p4') }}</p>
<p class="img-container"><el-image fit="scale-down" src="/static/img/tutorial/tutorial-4.jpg"></el-image></p> <p><el-image lazy src="/static/img/tutorial/tutorial-4.jpg"></el-image></p>
<p>{{ $t('help.p5') }}</p> <p>{{ $t('help.p5') }}</p>
<p class="img-container large-img"><el-image fit="scale-down" src="/static/img/tutorial/tutorial-5.jpg"></el-image></p> <p><el-image lazy src="/static/img/tutorial/tutorial-5.jpg"></el-image></p>
<p><br><br><br><br><br><br><br><br>--------------------------------------------------------------------------------------------------------</p> <p><br><br><br><br><br><br><br><br>--------------------------------------------------------------------------------------------------------</p>
<p>使用前必看<a href="https://github.com/xfgryujk/blivechat/wiki/%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%E5%92%8C%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98" target="_blank">注意事项和常见问题</a></p> <p>使用前必看<a href="https://github.com/xfgryujk/blivechat/wiki/%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%E5%92%8C%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98" target="_blank">注意事项和常见问题</a></p>
<p>喜欢的话可以推荐给别人 _(:з)_</p> <p>喜欢的话可以推荐给别人 _(:з)_</p>
@@ -22,13 +22,3 @@ export default {
name: 'Help' name: 'Help'
} }
</script> </script>
<style scoped>
.img-container {
text-align: center;
}
.img-container.large-img .el-image {
height: 80vh;
}
</style>

View File

@@ -6,7 +6,11 @@
<div class="title-line"> <div class="title-line">
<h3 class="name">{{ $t('home.templateDefaultTitle') }}</h3> <h3 class="name">{{ $t('home.templateDefaultTitle') }}</h3>
</div> </div>
<div class="description">{{ $t('home.templateDefaultDescription') }}</div> <div class="description-line">
<div class="description">
<p>{{ $t('home.templateDefaultDescription') }}</p>
</div>
</div>
</div> </div>
</el-radio> </el-radio>
@@ -15,7 +19,11 @@
<div class="title-line"> <div class="title-line">
<h3 class="name">{{ $t('home.templateCustomUrlTitle') }}</h3> <h3 class="name">{{ $t('home.templateCustomUrlTitle') }}</h3>
</div> </div>
<div class="description">{{ $t('home.templateCustomUrlDescription') }}</div> <div class="description-line">
<div class="description">
<p>{{ $t('home.templateCustomUrlDescription') }}</p>
</div>
</div>
<div> <div>
<el-input v-model="customUrl" placeholder="https://example.com/path/to/you/template/index.html"></el-input> <el-input v-model="customUrl" placeholder="https://example.com/path/to/you/template/index.html"></el-input>
</div> </div>
@@ -29,8 +37,13 @@
<span class="version">{{ template.version }}</span> <span class="version">{{ template.version }}</span>
<span class="author push-inline-end">{{ $t('home.author') }}{{ template.author }}</span> <span class="author push-inline-end">{{ $t('home.author') }}{{ template.author }}</span>
</div> </div>
<div v-if="template.description !== ''" class="description">{{ template.description }}</div> <div class="description-line">
<div>URL: {{ template.url }}</div> <el-image v-if="template.thumbnail !== ''" class="thumbnail" lazy fit="cover" :src="template.thumbnail"></el-image>
<div class="description">
<p v-if="template.description !== ''">{{ template.description }}</p>
<p>URL: {{ template.url }}</p>
</div>
</div>
</div> </div>
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
@@ -140,13 +153,12 @@ export default {
} }
.card-body { .card-body {
max-height: 200px;
display: flex; display: flex;
flex-flow: column nowrap; flex-flow: column nowrap;
gap: 1em;
} }
.title-line { .title-line {
margin-block-end: 1em;
flex: none; flex: none;
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
@@ -168,10 +180,35 @@ export default {
color: #606266; color: #606266;
} }
.description-line {
flex: none;
display: flex;
flex-flow: row nowrap;
gap: 1em;
max-height: 300px;
}
.thumbnail {
flex: none;
width: 400px;
height: 300px;
}
.description { .description {
margin-block-end: 1em;
flex: auto; flex: auto;
overflow-y: auto; overflow-y: auto;
text-wrap: wrap; text-wrap: wrap;
word-wrap: break-word;
}
@media only screen and (max-width: 992px) {
.description-line {
flex-wrap: wrap;
max-height: unset;
}
.thumbnail {
max-width: 100%;
}
} }
</style> </style>