-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ca6ea64
commit 69406c9
Showing
8 changed files
with
733 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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."); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
src/DotNetElements.Extensions.Icons/DotNetElements.Extensions.Icons.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
176
src/DotNetElements.Extensions.Icons/FontAwesomeSvgGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
} | ||
} |
Oops, something went wrong.