Skip to content

Commit

Permalink
Added icons extension project.
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix-CodingClimber committed Jun 29, 2024
1 parent ca6ea64 commit 69406c9
Show file tree
Hide file tree
Showing 8 changed files with 733 additions and 0 deletions.
6 changes: 6 additions & 0 deletions DotNetElements.sln
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetElements.Web.Blazor",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetElements.Web.AspNetCore", "src\DotNetElements.Web.AspNetCore\DotNetElements.Web.AspNetCore.csproj", "{8097E610-C806-44A2-B367-9F7EA4888BEA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetElements.Extensions.Icons", "src\DotNetElements.Extensions.Icons\DotNetElements.Extensions.Icons.csproj", "{12509DFE-E26F-4B58-84C3-3E099AD94082}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,6 +41,10 @@ Global
{8097E610-C806-44A2-B367-9F7EA4888BEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8097E610-C806-44A2-B367-9F7EA4888BEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8097E610-C806-44A2-B367-9F7EA4888BEA}.Release|Any CPU.Build.0 = Release|Any CPU
{12509DFE-E26F-4B58-84C3-3E099AD94082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12509DFE-E26F-4B58-84C3-3E099AD94082}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12509DFE-E26F-4B58-84C3-3E099AD94082}.Release|Any CPU.ActiveCfg = Release|Any CPU
{12509DFE-E26F-4B58-84C3-3E099AD94082}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
58 changes: 58 additions & 0 deletions src/DotNetElements.Extensions.Icons/ConsoleApplication.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace DotNetElements.Extensions.Icons;

internal sealed class ConsoleApplication : IHostedService
{
private readonly ILogger logger;
private readonly FontAwesomeSvgGenerator fontAwesomeSvgGenerator;
private readonly MaterialIconsSvgGenerator materialIconsSvgGenerator;

public ConsoleApplication(
ILogger<ConsoleApplication> logger,
IHostApplicationLifetime appLifetime,
FontAwesomeSvgGenerator fontAwesomeSvgGenerator,
MaterialIconsSvgGenerator materialIconsSvgGenerator)
{
this.logger = logger;
this.fontAwesomeSvgGenerator = fontAwesomeSvgGenerator;
this.materialIconsSvgGenerator = materialIconsSvgGenerator;

appLifetime.ApplicationStarted.Register(OnStarted);
appLifetime.ApplicationStopping.Register(OnStopping);
appLifetime.ApplicationStopped.Register(OnStopped);
}

public Task StartAsync(CancellationToken cancellationToken)
{
logger.LogInformation("Starting...");


return Task.CompletedTask;
}

public Task StopAsync(CancellationToken cancellationToken)
{
logger.LogInformation("Stopping...");
return Task.CompletedTask;
}

private async void OnStarted()
{
logger.LogInformation("Application started.");

await fontAwesomeSvgGenerator.Run();
await materialIconsSvgGenerator.Run();
}

private void OnStopping()
{
logger.LogInformation("Application stopping.");
}

private void OnStopped()
{
logger.LogInformation("Application stoped.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>

</Project>
176 changes: 176 additions & 0 deletions src/DotNetElements.Extensions.Icons/FontAwesomeSvgGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
using Microsoft.Extensions.Logging;
using System.Net.Http.Json;
using System.Text;

namespace DotNetElements.Extensions.Icons;

internal class FontAwesomeSvgGenerator
{
private readonly HttpClient httpClient;
private readonly ILogger<FontAwesomeSvgGenerator> logger;

public FontAwesomeSvgGenerator(HttpClient httpClient, ILogger<FontAwesomeSvgGenerator> logger)
{
this.httpClient = httpClient;
this.logger = logger;
}

public async Task Run()
{
IReadOnlyList<FontAwesomeIcon>? iconInfo = await GetIconInfoAsync();

if (iconInfo is null)
return;

await WriteToFileAsync(iconInfo);

logger.LogInformation("Generated FontAwesome icons");
}

private async Task<IReadOnlyList<FontAwesomeIcon>?> GetIconInfoAsync()
{
Dictionary<string, FontAwesomeIcon>? iconInfo = await httpClient.GetFromJsonAsync<Dictionary<string, FontAwesomeIcon>>("metadata/icons.json");

if (iconInfo is null)
{
logger.LogError("Failed to get icon info from Github!");
return null;
}

return iconInfo.Select(kvp =>
{
kvp.Value.Id = kvp.Key;

return kvp.Value;
}).ToList();
}

private async Task WriteToFileAsync(IReadOnlyList<FontAwesomeIcon> iconInfo)
{
StringBuilder resultBuilder = new StringBuilder();
resultBuilder.AppendLine(fileHeader);

StringBuilder iconRegularBuilder = new StringBuilder();
StringBuilder iconSolidBuilder = new StringBuilder();
StringBuilder iconBrandsBuilder = new StringBuilder();

foreach (FontAwesomeIcon icon in iconInfo)
{
if (icon.Id is null)
{
logger.LogWarning($"Skipped icon {icon.Label}, no icon id was found");
continue;
}

ISvgDescription? svgDescription = icon.Svg.GetDescription();

if (svgDescription is null)
{
logger.LogWarning($"Skipped icon {icon.Id}, no svg description was found");
continue;
}

if (icon.Svg.Regular is not null)
AppendIconValue(ref iconRegularBuilder, icon, svgDescription);
else if (icon.Svg.Solid is not null)
AppendIconValue(ref iconSolidBuilder, icon, svgDescription);
else
AppendIconValue(ref iconBrandsBuilder, icon, svgDescription);
}

resultBuilder.Append(iconRegularBuilder);
resultBuilder.AppendLine(
"""
}
public static class Solid
{
""");
resultBuilder.Append(iconSolidBuilder);
resultBuilder.AppendLine(
"""
}
public static class Brands
{
""");
resultBuilder.Append(iconBrandsBuilder);
resultBuilder.Append(fileFooter);

await File.WriteAllTextAsync("FontAwesomeIcons.cs", resultBuilder.ToString());
}

private const string fileHeader =
"""
//----------------------
// <auto-generated>
// Generated by the BlazorSpa.Tools FontAwesomeGenerator. DO NOT EDIT!
// source: FontAwesomeGenerator.cs
// </auto-generated>
//----------------------
namespace BlazorSpa.Components;
public static partial class Icons
{
public static partial class FontAwesome
{
public static class Regular
{
""";

private static void AppendIconValue(ref StringBuilder stringBuilder, FontAwesomeIcon icon, ISvgDescription svgDescription)
{
stringBuilder.AppendLine(
$"""
/// <summary>
/// <para>
/// <b>FontAwesomeIcon</b>
/// </para>
/// <para>
/// <b>Style:</b> {svgDescription.GetType().Name.ToLowerInvariant()}
/// <b>Label:</b> {icon.Label}
/// </para>
/// </summary>
""");

string varName = icon.Id!.ConvertDashToPascalCase();
if (varName == "FontAwesome")
varName = $"_{varName}";

stringBuilder.AppendLine($" public const string {varName} = \"{svgDescription.Width},{svgDescription.Height},{svgDescription.Path}\";");
stringBuilder.AppendLine();
}

private const string fileFooter =
"""
}
}
}
""";

private record FontAwesomeIcon(string[] Styles, string Label, Svg Svg)
{
public string? Id { get; set; }
}
private record Svg(Regular? Regular, Solid? Solid, Brands? Brands)
{
public ISvgDescription? GetDescription() =>
Regular is not null ? Regular
: Solid is not null ? Solid
: Brands is not null ? Brands
: null;
}

private record Regular(int Width, int Height, string Path) : ISvgDescription;
private record Solid(int Width, int Height, string Path) : ISvgDescription;
private record Brands(int Width, int Height, string Path) : ISvgDescription;

private interface ISvgDescription
{
int Height { get; init; }
string Path { get; init; }
int Width { get; init; }
}
}
Loading

0 comments on commit 69406c9

Please sign in to comment.