дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
feat(plugins): let plugin tool windows use an SVG icon from the package (#1363)
A view's `icon` could only be a built-in icon name, so a plugin's tool window button couldn't show the plugin's own mark. Like `fileIcons`, an `icon` ending in `.svg` is now a path in the package: the host reads and checks it at install time (a missing file or an SVG with `<script>` refuses the install), serves it as the `viewIcon/<id>` asset, and the tool window registers it as an external icon, falling back to the plugin icon if it can't be loaded. Icon names work as before. Closes #1335 Co-authored-by: yzPeedro <[email protected]>
Цей коміт міститься в:
1 джерело
ab2b53ff80
коміт
7ffaa0b5da
4 files changed
+116
-31
No files matched your search
@@ -290,6 +290,49 @@ function projectFileIcon(pluginId: string, decl: FileIconDecl): () => void {
|
||||
|
||||
export const pluginToolWindowId = (pluginId: string, view: string) => `plugin.${pluginId}.${view}`;
|
||||
|
||||
function registerView(pluginId: string, decl: ViewDecl, icon: string): () => void {
|
||||
return registerToolWindow({
|
||||
id: pluginToolWindowId(pluginId, decl.id),
|
||||
title: decl.title,
|
||||
icon,
|
||||
anchor: decl.location,
|
||||
order: 900,
|
||||
component: () =>
|
||||
decl.web ? (
|
||||
<WebView pluginId={pluginId} view={decl.id} label={decl.title} />
|
||||
) : (
|
||||
<PluginView pluginId={pluginId} view={decl.id} label={decl.title} />
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
function projectView(pluginId: string, decl: ViewDecl): () => void {
|
||||
if (!decl.icon?.endsWith(".svg")) return registerView(pluginId, decl, decl.icon ?? "plugin");
|
||||
let disposed = false;
|
||||
let undo = () => {};
|
||||
void pluginsBackend()
|
||||
.assets(pluginId, `viewIcon/${decl.id}`)
|
||||
.then((assets) => {
|
||||
if (disposed) return;
|
||||
const svg = assets.find(([id]) => id === `viewIcon/${decl.id}`)?.[1];
|
||||
const name = `ext:${pluginId}/view-${decl.id}`;
|
||||
const unregister = svg ? registerExternalIcons([[name, svg]]) : () => {};
|
||||
const remove = registerView(pluginId, decl, svg ? name : "plugin");
|
||||
undo = () => {
|
||||
remove();
|
||||
unregister();
|
||||
};
|
||||
})
|
||||
.catch((e: unknown) => {
|
||||
console.warn(`plugin ${pluginId}: view icon ${decl.id}`, e);
|
||||
if (!disposed) undo = registerView(pluginId, decl, "plugin");
|
||||
});
|
||||
return () => {
|
||||
disposed = true;
|
||||
undo();
|
||||
};
|
||||
}
|
||||
|
||||
/** Registers the client side of the P7 points; returns their disposer. */
|
||||
export function defineViewUiPoints(): () => void {
|
||||
const disposers = [
|
||||
@@ -326,20 +369,7 @@ export function defineViewUiPoints(): () => void {
|
||||
}),
|
||||
defineUiPoint<ViewDecl>("views", {
|
||||
title: "Tool Windows",
|
||||
project: ({ pluginId, decl }) =>
|
||||
registerToolWindow({
|
||||
id: pluginToolWindowId(pluginId, decl.id),
|
||||
title: decl.title,
|
||||
icon: decl.icon ?? "plugin",
|
||||
anchor: decl.location,
|
||||
order: 900,
|
||||
component: () =>
|
||||
decl.web ? (
|
||||
<WebView pluginId={pluginId} view={decl.id} label={decl.title} />
|
||||
) : (
|
||||
<PluginView pluginId={pluginId} view={decl.id} label={decl.title} />
|
||||
),
|
||||
}),
|
||||
project: ({ pluginId, decl }) => projectView(pluginId, decl),
|
||||
}),
|
||||
defineUiPoint<CustomEditorDecl>("customEditors", {
|
||||
title: "Editors",
|
||||
|
||||
Reference in new issue
Заблокувати користувача