添加自定义模板缩略图

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
api
frontend/src/views

View File

@ -117,8 +117,7 @@ class TemplatesHandler(api.base.ApiHandler):
self.set_header('Cache-Control', 'private, max-age=10')
self.write({'templates': templates})
@staticmethod
def _get_templates():
def _get_templates(self):
template_ids = []
try:
with os.scandir(TEMPLATE_PATH) as it:
@ -134,33 +133,48 @@ class TemplatesHandler(api.base.ApiHandler):
templates = []
for template_id in template_ids:
try:
config_path = os.path.join(TEMPLATE_PATH, template_id, 'template.json')
with open(config_path, encoding='utf-8') as f:
cfg = json.load(f)
if not isinstance(cfg, dict):
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}/')
url = base_url.join(url)
url_str = str(url)
template = {
'id': template_id,
'name': str(cfg.get('name', '')),
'version': str(cfg.get('version', '')),
'author': str(cfg.get('author', '')),
'description': str(cfg.get('description', '')),
'url': url_str,
}
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')
with open(config_path, encoding='utf-8') as f:
cfg = json.load(f)
if not isinstance(cfg, dict):
raise TypeError(f'Config type error, type={type(cfg)}')
# 相对于模板目录
base_url = yarl.URL(f'{TEMPLATE_BASE_URL}/{template_id}/')
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 = {
'id': template_id,
'name': str(cfg.get('name', '')),
'version': str(cfg.get('version', '')),
'author': str(cfg.get('author', '')),
'description': str(cfg.get('description', '')),
'thumbnail': thumbnail_url_str,
'url': url_str,
}
return template
class NoCacheStaticFileHandler(tornado.web.StaticFileHandler):
def set_extra_headers(self, path):

View File

@ -2,15 +2,15 @@
<div>
<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 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 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 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 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 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>使用前必看<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>
@ -22,13 +22,3 @@ export default {
name: 'Help'
}
</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">
<h3 class="name">{{ $t('home.templateDefaultTitle') }}</h3>
</div>
<div class="description">{{ $t('home.templateDefaultDescription') }}</div>
<div class="description-line">
<div class="description">
<p>{{ $t('home.templateDefaultDescription') }}</p>
</div>
</div>
</div>
</el-radio>
@ -15,7 +19,11 @@
<div class="title-line">
<h3 class="name">{{ $t('home.templateCustomUrlTitle') }}</h3>
</div>
<div class="description">{{ $t('home.templateCustomUrlDescription') }}</div>
<div class="description-line">
<div class="description">
<p>{{ $t('home.templateCustomUrlDescription') }}</p>
</div>
</div>
<div>
<el-input v-model="customUrl" placeholder="https://example.com/path/to/you/template/index.html"></el-input>
</div>
@ -29,8 +37,13 @@
<span class="version">{{ template.version }}</span>
<span class="author push-inline-end">{{ $t('home.author') }}{{ template.author }}</span>
</div>
<div v-if="template.description !== ''" class="description">{{ template.description }}</div>
<div>URL: {{ template.url }}</div>
<div class="description-line">
<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>
</el-radio>
</el-radio-group>
@ -140,13 +153,12 @@ export default {
}
.card-body {
max-height: 200px;
display: flex;
flex-flow: column nowrap;
gap: 1em;
}
.title-line {
margin-block-end: 1em;
flex: none;
display: flex;
flex-flow: row nowrap;
@ -168,10 +180,35 @@ export default {
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 {
margin-block-end: 1em;
flex: auto;
overflow-y: auto;
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>