feat(plugins): add SVG icon support with authenticated inline rendering

This commit is contained in:
viper151
2026-03-06 12:36:15 +01:00
parent 95ba61ea3e
commit a09aa5f68e
2 changed files with 45 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
import { useState, useEffect } from 'react';
import { authenticatedFetch } from '../../utils/api';
type Props = {
pluginName: string;
iconFile: string;
className?: string;
};
// Module-level cache so repeated renders don't re-fetch
const svgCache = new Map<string, string>();
export default function PluginIcon({ pluginName, iconFile, className }: Props) {
const url = `/api/plugins/${encodeURIComponent(pluginName)}/assets/${encodeURIComponent(iconFile)}`;
const [svg, setSvg] = useState<string | null>(svgCache.get(url) ?? null);
useEffect(() => {
if (svgCache.has(url)) return;
authenticatedFetch(url)
.then((r) => r.text())
.then((text) => {
if (text.trimStart().startsWith('<svg')) {
svgCache.set(url, text);
setSvg(text);
}
})
.catch(() => {});
}, [url]);
if (!svg) return <span className={className} />;
return (
<span
className={className}
// SVG is fetched from the user's own installed plugin — same trust level as the plugin code itself
dangerouslySetInnerHTML={{ __html: svg }}
/>
);
}