Added icon support for plugins

This commit is contained in:
Thorsten Sommer 2025-03-25 19:24:21 +01:00
parent 08a0ac9e8c
commit ec31660017
Signed by: tsommer
GPG Key ID: 371BBA77A02C0108
9 changed files with 113 additions and 3 deletions

View File

@ -1,7 +1,34 @@
@using AIStudio.Tools.PluginSystem
@attribute [Route(Routes.PLUGINS)]
<div class="inner-scrolling-context">
<MudText Typo="Typo.h3" Class="mb-12">Plugins</MudText>
<MudText Typo="Typo.h3" Class="mb-12">
Plugins
</MudText>
<PreviewExperimental/>
<InnerScrolling>
<MudList T="string">
@foreach (var plugin in PluginFactory.AvailablePlugins)
{
<MudListItem>
<AvatarContent>
<MudAvatar Size="Size.Large" Class="align-content-stretch me-4">
<div class="plugin-icon-container">
@((MarkupString)plugin.IconSVG)
</div>
</MudAvatar>
</AvatarContent>
<ChildContent>
<MudText Typo="Typo.h6">
@plugin.Name
</MudText>
<MudJustifiedText Typo="Typo.body1">
@plugin.Description
</MudJustifiedText>
</ChildContent>
</MudListItem>
}
</MudList>
</InnerScrolling>
</div>

View File

@ -0,0 +1,5 @@
SVG = [[<svg width="1000" height="600" viewBox="0 0 5 3">
<rect id="black_stripe" width="5" height="3" y="0" x="0" fill="#000"/>
<rect id="red_stripe" width="5" height="2" y="1" x="0" fill="#D00"/>
<rect id="gold_stripe" width="5" height="1" y="2" x="0" fill="#FFCE00"/>
</svg>]]

View File

@ -1,4 +1,5 @@
require("contentHome")
require("icon")
-- The ID for this plugin:
ID = "43065dbc-78d0-45b7-92be-f14c2926e2dc"
@ -38,4 +39,6 @@ DEPRECATION_MESSAGE = ""
UI_TEXT_CONTENT = {
HOME = CONTENT_HOME,
}
}
ICON_SVG = SVG

View File

@ -0,0 +1,25 @@
SVG = [[<svg width="1235" height="650" viewBox="0 0 7410 3900">
<path d="M0,0h7410v3900H0" fill="#b31942"/>
<path d="M0,450H7410m0,600H0m0,600H7410m0,600H0m0,600H7410m0,600H0" stroke="#FFF" stroke-width="300"/>
<path d="M0,0h2964v2100H0" fill="#0a3161"/>
<g fill="#FFF">
<g id="s18">
<g id="s9">
<g id="s5">
<g id="s4">
<path id="s" d="M247,90 317.534230,307.082039 132.873218,172.917961H361.126782L176.465770,307.082039z"/>
<use xlink:href="#s" y="420"/>
<use xlink:href="#s" y="840"/>
<use xlink:href="#s" y="1260"/>
</g>
<use xlink:href="#s" y="1680"/>
</g>
<use xlink:href="#s4" x="247" y="210"/>
</g>
<use xlink:href="#s9" x="494"/>
</g>
<use xlink:href="#s18" x="988"/>
<use xlink:href="#s9" x="1976"/>
<use xlink:href="#s5" x="2470"/>
</g>
</svg>]]

View File

@ -1,4 +1,5 @@
require("contentHome")
require("icon")
-- The ID for this plugin:
ID = "97dfb1ba-50c4-4440-8dfa-6575daf543c8"
@ -38,4 +39,6 @@ DEPRECATION_MESSAGE = ""
UI_TEXT_CONTENT = {
HOME = CONTENT_HOME,
}
}
ICON_SVG = SVG

View File

@ -2,6 +2,11 @@ namespace AIStudio.Tools.PluginSystem;
public interface IPluginMetadata
{
/// <summary>
/// The icon of this plugin.
/// </summary>
public string IconSVG { get; }
/// <summary>
/// The type of this plugin.
/// </summary>

View File

@ -12,6 +12,9 @@ public abstract class PluginBase : IPluginMetadata
protected readonly LuaState state;
protected readonly List<string> pluginIssues = [];
/// <inheritdoc />
public string IconSVG { get; }
/// <inheritdoc />
public PluginType Type { get; }
@ -71,6 +74,10 @@ public abstract class PluginBase : IPluginMetadata
var issues = new List<string>();
if(!string.IsNullOrWhiteSpace(parseError))
issues.Add(parseError);
// Notice: when no icon is specified, the default icon will be used.
this.TryInitIconSVG(out _, out var iconSVG);
this.IconSVG = iconSVG;
if(this.TryInitId(out var issue, out var id))
this.Id = id;
@ -430,6 +437,28 @@ public abstract class PluginBase : IPluginMetadata
return true;
}
/// <summary>
/// Tries to initialize the icon of the plugin.
/// </summary>
/// <remarks>
/// When no icon is specified, the default icon will be used.
/// </remarks>
/// <param name="message">The error message, when the icon could not be read.</param>
/// <param name="iconSVG">The read icon as SVG.</param>
/// <returns>True, when the icon could be read successfully.</returns>
private bool TryInitIconSVG(out string message, out string iconSVG)
{
if (!this.state.Environment["ICON_SVG"].TryRead(out iconSVG))
{
iconSVG = Icons.Material.TwoTone.Extension;
message = "The field ICON_SVG does not exist or is not a valid string.";
return false;
}
message = string.Empty;
return true;
}
/// <summary>
/// Tries to initialize the UI text content of the plugin.
/// </summary>

View File

@ -4,6 +4,9 @@ public sealed class PluginMetadata(PluginBase plugin) : IPluginMetadata
{
#region Implementation of IPluginMetadata
/// <inheritdoc />
public string IconSVG { get; } = plugin.IconSVG;
/// <inheritdoc />
public PluginType Type { get; } = plugin.Type;

View File

@ -35,6 +35,16 @@
margin-top: 4px;
}
.plugin-icon-container {
width: var(--mud-icon-size-large);
height: var(--mud-icon-size-large);
}
.plugin-icon-container svg {
width: 200%;
height: 200%;
}
:root {
--confidence-color: #000000;
}