Files
mixtape/zero.Backoffice/Services/Icons/IconService.cs
T
2021-12-06 13:29:15 +01:00

113 lines
2.7 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Concurrent;
using System.IO;
using System.Text;
using System.Xml.Linq;
namespace zero.Backoffice.Services;
public class IconService : IIconService
{
protected IOptions<BackofficeOptions> Options { get; set; }
protected IBackofficeAssetFileSystem FileSystem { get; set; }
protected ILogger<IconService> Logger { get; set; }
protected ConcurrentBag<BackofficeIconSetPresentation> CachedSets { get; private set; } = new();
protected string CachedSvg { get; set; }
protected bool IsLoaded { get; set; }
public IconService(IOptions<BackofficeOptions> options, IBackofficeAssetFileSystem fileSystem, ILogger<IconService> logger)
{
Options = options;
FileSystem = fileSystem;
Logger = logger;
}
/// <inheritdoc />
public async Task<IEnumerable<BackofficeIconSetPresentation>> GetSets()
{
await EnsureIconsAreLoaded();
return CachedSets;
}
/// <inheritdoc />
public async Task<string> GetCompiledSvg()
{
await EnsureIconsAreLoaded();
return CachedSvg;
}
async Task EnsureIconsAreLoaded()
{
if (IsLoaded)
{
return;
}
StringBuilder svg = new();
foreach (BackofficeIconSet set in Options.Value.IconSets)
{
if (!await FileSystem.Exists(set.SpritePath))
{
Logger.LogWarning("Could not load icon set {alias} from path {path}", set.Alias, FileSystem.Map(set.SpritePath));
continue;
}
using Stream stream = await FileSystem.StreamFile(set.SpritePath);
XDocument xml = XDocument.Load(stream);
IEnumerable<XElement> symbols = xml.Descendants().Where(x => x.Name.LocalName == "symbol");
if (!symbols.Any())
{
Logger.LogWarning("Icon set {alias} does not contain any <symbol>", set.Alias);
continue;
}
HashSet<string> icons = new();
foreach (XElement symbol in symbols)
{
string symbolAlias = set.Prefix + "-" + symbol.Attribute("id").Value.ToString();
symbol.SetAttributeValue("id", symbolAlias);
svg.Append(symbol.ToString().RemoveNewLines());
icons.Add(symbolAlias);
}
CachedSets.Add(new()
{
Alias = set.Alias,
Name = set.Name,
Prefix = set.Prefix,
Icons = icons
});
}
CachedSvg = svg.ToString();
IsLoaded = true;
}
}
public interface IIconService
{
/// <summary>
/// Get all registered icon sets with all their containing icons
/// </summary>
Task<IEnumerable<BackofficeIconSetPresentation>> GetSets();
/// <summary>
/// Get compiled SVG string for alle registered icon sets
/// </summary>
Task<string> GetCompiledSvg();
}