feat: auto-detect preview image format (jpg/png/webp/gif)

This commit is contained in:
2026-07-27 11:32:26 +08:00
parent 64bf6d9603
commit 958482e5e6
2 changed files with 12 additions and 2 deletions
+9
View File
@@ -35,6 +35,7 @@ class DashboardTheme:
updated_at: str = "" updated_at: str = ""
is_builtin: bool = False is_builtin: bool = False
dir_path: str = "" dir_path: str = ""
preview_ext: str = ""
def to_dict(self) -> dict[str, Any]: def to_dict(self) -> dict[str, Any]:
return { return {
@@ -51,6 +52,7 @@ class DashboardTheme:
"created_at": self.created_at, "created_at": self.created_at,
"updated_at": self.updated_at, "updated_at": self.updated_at,
"is_builtin": self.is_builtin, "is_builtin": self.is_builtin,
"preview_ext": self.preview_ext,
} }
@classmethod @classmethod
@@ -59,6 +61,12 @@ class DashboardTheme:
with open(manifest_path, "r", encoding="utf-8") as f: with open(manifest_path, "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
config = data.get("config", {}) config = data.get("config", {})
dir_path = manifest_path.parent
preview_ext = ""
for ext in ["jpg", "jpeg", "png", "webp", "gif"]:
if (dir_path / f"preview.{ext}").exists():
preview_ext = ext
break
return cls( return cls(
id=data.get("id", manifest_path.parent.name), id=data.get("id", manifest_path.parent.name),
name=data.get("name", manifest_path.parent.name), name=data.get("name", manifest_path.parent.name),
@@ -74,6 +82,7 @@ class DashboardTheme:
updated_at=data.get("updated_at", ""), updated_at=data.get("updated_at", ""),
is_builtin=is_builtin, is_builtin=is_builtin,
dir_path=str(manifest_path.parent), dir_path=str(manifest_path.parent),
preview_ext=preview_ext,
) )
except Exception as e: except Exception as e:
logger.error("Failed to load dashboard manifest %s: %s", manifest_path, e) logger.error("Failed to load dashboard manifest %s: %s", manifest_path, e)
+3 -2
View File
@@ -289,10 +289,11 @@ const PageDashboard = {
const isAll = supported === 'all'; const isAll = supported === 'all';
const compatLabel = isAll ? '全' : '限'; const compatLabel = isAll ? '全' : '限';
const compatClass = isAll ? 'badge-info' : 'badge-warning'; const compatClass = isAll ? 'badge-info' : 'badge-warning';
const preview = `/dashboard/${theme.id}/preview.jpg`; const preview = theme.preview_ext ? `/dashboard/${theme.id}/preview.${theme.preview_ext}` : '';
const bgStyle = preview ? `background-image:url(${preview});background-size:cover;background-position:center` : '';
return ` return `
<div class="glass-card theme-card" data-theme-id="${theme.id}"> <div class="glass-card theme-card" data-theme-id="${theme.id}">
<div class="theme-card-preview" style="background-image:url(${preview});background-size:cover;background-position:center">${icon}</div> <div class="theme-card-preview" style="${bgStyle}">${preview?'':icon}</div>
<div class="theme-card-info"> <div class="theme-card-info">
<div class="theme-card-name">${theme.name || 'Unnamed'}</div> <div class="theme-card-name">${theme.name || 'Unnamed'}</div>
<div class="theme-card-meta"> <div class="theme-card-meta">