diff --git a/AppImage/components/lxc-app-panel.tsx b/AppImage/components/lxc-app-panel.tsx index 43fefdd6..f3a65942 100644 --- a/AppImage/components/lxc-app-panel.tsx +++ b/AppImage/components/lxc-app-panel.tsx @@ -391,32 +391,34 @@ const EMPTY_APP: AppConfig = { logo_url: "", } -// selfh.st publishes a `-light` variant of the logos that are dark, for dark -// backgrounds. These two ship a light logo by default, so the light theme -// takes their `-dark` variant. -const SELFHST_LIGHT_BY_DEFAULT = new Set(["frigate", "portainer"]) - -function selfhstThemeLogos(src: string) { - const match = src.match(/^(https:\/\/cdn\.jsdelivr\.net\/gh\/selfhst\/icons@[^/]+\/webp\/)([a-z0-9-]+?)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/i) - if (!match) return null - const [, base, name] = match - return { - lightTheme: `${base}${name}${SELFHST_LIGHT_BY_DEFAULT.has(name.toLowerCase()) ? "-dark" : ""}.webp`, - darkTheme: `${base}${name}-light.webp`, - } +const SELFHST_WEBP_BASE = "https://cdn.jsdelivr.net/gh/selfhst/icons@main/webp" +const SELFHST_THEME_LOGOS: Record = { + frigate: { + lightTheme: `${SELFHST_WEBP_BASE}/frigate-dark.webp`, + darkTheme: `${SELFHST_WEBP_BASE}/frigate-light.webp`, + }, + "llama-cpp": { + lightTheme: `${SELFHST_WEBP_BASE}/llama-cpp.webp`, + darkTheme: `${SELFHST_WEBP_BASE}/llama-cpp-light.webp`, + }, + portainer: { + lightTheme: `${SELFHST_WEBP_BASE}/portainer-dark.webp`, + darkTheme: `${SELFHST_WEBP_BASE}/portainer-light.webp`, + }, + tailscale: { + lightTheme: `${SELFHST_WEBP_BASE}/tailscale.webp`, + darkTheme: `${SELFHST_WEBP_BASE}/tailscale-light.webp`, + }, + vaultwarden: { + lightTheme: `${SELFHST_WEBP_BASE}/vaultwarden.webp`, + darkTheme: `${SELFHST_WEBP_BASE}/vaultwarden-light.webp`, + }, } -// A logo without the variant keeps the recorded one. -function FallbackLogo({ src, fallback, className }: { src: string; fallback: string; className: string }) { - const [failed, setFailed] = useState(false) - useEffect(() => setFailed(false), [src]) - return ( - { - if (!failed && fallback !== src) setFailed(true) - else e.currentTarget.style.display = "none" - }} /> - ) +function selfhstThemeLogos(src: string) { + if (!src.toLowerCase().includes("cdn.jsdelivr.net/gh/selfhst/icons")) return null + const match = src.toLowerCase().match(/\/(frigate|llama-cpp|portainer|tailscale|vaultwarden)(?:-(?:dark|light))?\.webp(?:[?#].*)?$/) + return match ? SELFHST_THEME_LOGOS[match[1]] : null } const LOCAL_LOGO_CACHE_PATH = /^\/api\/vms\/[1-9]\d*\/apps\/logo-cache\/[a-f0-9]{32}$/ @@ -462,8 +464,8 @@ export function ThemeAwareLogo({ src, className }: { src: string; className: str } return ( <> - -