-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial Roster Formatting prototype for #14
- Loading branch information
Showing
6 changed files
with
165 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,8 @@ | ||
namespace Phalanx.App.Pages.Printing; | ||
|
||
public class RosterFormat | ||
{ | ||
public string? Name { get; set; } | ||
|
||
public string? HandlebarsTemplate { get; set; } | ||
} |
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,46 @@ | ||
using HandlebarsDotNet; | ||
using Microsoft.Extensions.Options; | ||
using WarHub.ArmouryModel.Source; | ||
|
||
namespace Phalanx.App.Pages.Printing; | ||
|
||
public class RosterFormatter | ||
{ | ||
private readonly Options options; | ||
|
||
public RosterFormatter(IOptions<Options> options) | ||
{ | ||
this.options = options.Value; | ||
} | ||
|
||
/// <summary> | ||
/// Handlebars template can reference members of <see cref="RosterCore"/> | ||
/// by accessing the root context's "roster" property: <code>Name: {{roster.name}}</code>. | ||
/// </summary> | ||
/// <param name="roster"></param> | ||
/// <param name="format"></param> | ||
/// <returns></returns> | ||
public string Format(RosterNode roster, RosterFormat format) | ||
{ | ||
var templateBuilder = Handlebars.Compile(format.HandlebarsTemplate); | ||
var context = new | ||
{ | ||
roster = roster.Core | ||
}; | ||
return templateBuilder(context); | ||
} | ||
|
||
public IEnumerable<RosterFormat> Formats => options.Formats; | ||
|
||
public class Options | ||
{ | ||
public List<RosterFormat> Formats { get; } = new() | ||
{ | ||
new() | ||
{ | ||
Name = "Default", | ||
HandlebarsTemplate = "Roster \"{{roster.name}}\"" | ||
} | ||
}; | ||
} | ||
} |
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,106 @@ | ||
@page "/print" | ||
@using Printing | ||
@using SampleDataset | ||
@using WarHub.ArmouryModel.Source | ||
@using WarHub.ArmouryModel.Workspaces.BattleScribe | ||
|
||
@inject Printing.RosterFormatter formatter | ||
|
||
<h1>Format roster</h1> | ||
|
||
<label>Select roster file</label> | ||
<InputFile OnChange="@LoadRosterFile" accept=".ros, .rosz" /> | ||
|
||
<p> | ||
<strong> | ||
Loaded: | ||
@if (RosterNode is null) | ||
{ | ||
<span>none</span> | ||
} | ||
else | ||
{ | ||
<span>@RosterNode.Name</span> | ||
} | ||
</strong> | ||
</p> | ||
|
||
<label>Select formatter</label> | ||
<fast-select current-value="@SelectedFormatIndex" @onchange="OnFormatIndexSelected"> | ||
@foreach (var (format, index) in formatter.Formats.Select((x, i) => (x, i))) | ||
{ | ||
<fast-option value="@index">@format.Name</fast-option> | ||
} | ||
</fast-select> | ||
@if (selectedFormat is not null) | ||
{ | ||
<section> | ||
<h2>Handlebars template <em>@selectedFormat.Name</em>:</h2> | ||
<fast-text-area current-value="@selectedFormat.HandlebarsTemplate" | ||
@onchange="e => selectedFormat.HandlebarsTemplate = e.Value?.ToString()" resize="both"> | ||
</fast-text-area> | ||
<hr /> | ||
</section> | ||
} | ||
<fast-button @onclick="RunFormatter" disabled="@(selectedFormat is null || RosterNode is null)">Format</fast-button> | ||
|
||
<section> | ||
<h2>Formatted output:</h2> | ||
<hr /> | ||
@formattedOutput | ||
<hr /> | ||
</section> | ||
|
||
@code { | ||
private RosterNode? RosterNode; | ||
private string? formattedOutput; | ||
private RosterFormat? selectedFormat; | ||
private string? selectedFormatIndex; | ||
private string? SelectedFormatIndex | ||
{ | ||
get => selectedFormatIndex; | ||
set | ||
{ | ||
selectedFormatIndex = value; | ||
selectedFormat = int.TryParse(value, out var i) | ||
? formatter.Formats.ElementAtOrDefault(i) | ||
: null; | ||
} | ||
} | ||
|
||
protected override async Task OnInitializedAsync() | ||
{ | ||
await base.OnInitializedAsync(); | ||
selectedFormat = formatter.Formats.FirstOrDefault(); | ||
var rosterFile = SampleDataResources.CreateXmlWorkspace().DocumentsByKind[XmlDocumentKind.Roster][0]; | ||
RosterNode = (RosterNode?)(await rosterFile.GetRootAsync()); | ||
} | ||
|
||
void OnFormatIndexSelected(ChangeEventArgs e) | ||
{ | ||
SelectedFormatIndex = e.Value?.ToString(); | ||
} | ||
|
||
async Task LoadRosterFile(InputFileChangeEventArgs eventArgs) | ||
{ | ||
// 10MB | ||
const long maxSize = 10 << 10 << 10; | ||
using var stream = eventArgs.File.OpenReadStream(maxAllowedSize: maxSize); | ||
// it's bad but WHAM doesn't support async reading currently :( | ||
// TODO fix when wham gains async support, consider migrating? | ||
using var memStream = new MemoryStream(); | ||
await stream.CopyToAsync(memStream); | ||
memStream.Position = 0; | ||
RosterNode = (RosterNode)await memStream.LoadSourceAuto(eventArgs.File.Name).GetDataOrThrowAsync<RosterNode>(); | ||
} | ||
|
||
void RunFormatter() | ||
{ | ||
if (RosterNode is null || selectedFormat is null) | ||
{ | ||
formattedOutput = null; | ||
return; | ||
} | ||
formattedOutput = formatter.Format(RosterNode, selectedFormat); | ||
} | ||
} |
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 |
---|---|---|
@@ -1,11 +1,13 @@ | ||
using Microsoft.AspNetCore.Components.Web; | ||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; | ||
using Phalanx.App; | ||
using Phalanx.App.Pages.Printing; | ||
|
||
var builder = WebAssemblyHostBuilder.CreateDefault(args); | ||
builder.RootComponents.Add<App>("#app"); | ||
builder.RootComponents.Add<HeadOutlet>("head::after"); | ||
|
||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); | ||
builder.Services.AddScoped<RosterFormatter>(); | ||
|
||
await builder.Build().RunAsync(); |
7f7723c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's supposed to be for #34 - a typo on my side.