80 lines
2.6 KiB
C#
80 lines
2.6 KiB
C#
using Microsoft.AspNetCore.Components;
|
|
using Chrono.Model;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Shared.Services;
|
|
|
|
public class CardRenderingService
|
|
{
|
|
private readonly List<string> _cardNames;
|
|
private readonly Dictionary<string, CardData> _cardLookup;
|
|
private readonly Regex _nameRegex;
|
|
|
|
public CardRenderingService()
|
|
{
|
|
var allCards = CardDatabase.Cards
|
|
.Where(c => !string.IsNullOrWhiteSpace(c.Name))
|
|
.ToList();
|
|
|
|
_cardLookup = allCards
|
|
.GroupBy(c => c.Name, StringComparer.OrdinalIgnoreCase)
|
|
.ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase);
|
|
|
|
_cardNames = allCards
|
|
.Select(c => c.Name)
|
|
.OrderByDescending(n => n.Length)
|
|
.ToList();
|
|
|
|
var pattern = string.Join("|", _cardNames.Select(n => $@"\b{Regex.Escape(n)}\b"));
|
|
_nameRegex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
|
}
|
|
|
|
public RenderFragment RenderDescription(string description, Action<CardData?> onCardClick)
|
|
{
|
|
return builder =>
|
|
{
|
|
int sequence = 0;
|
|
var paragraphs = description.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
foreach (var paragraph in paragraphs)
|
|
{
|
|
builder.OpenElement(sequence++, "p");
|
|
|
|
var matches = _nameRegex.Matches(paragraph);
|
|
int lastIndex = 0;
|
|
|
|
foreach (Match match in matches)
|
|
{
|
|
if (match.Index > lastIndex)
|
|
{
|
|
builder.AddContent(sequence++, paragraph.Substring(lastIndex, match.Index - lastIndex));
|
|
}
|
|
|
|
var cardName = match.Value;
|
|
var card = LookupCard(cardName);
|
|
|
|
builder.OpenElement(sequence++, "button");
|
|
builder.AddAttribute(sequence++, "class", "inline-card-btn");
|
|
builder.AddAttribute(sequence++, "onclick", EventCallback.Factory.Create(this, () => onCardClick(card)));
|
|
builder.AddContent(sequence++, cardName);
|
|
builder.CloseElement();
|
|
|
|
lastIndex = match.Index + match.Length;
|
|
}
|
|
|
|
if (lastIndex < paragraph.Length)
|
|
{
|
|
builder.AddContent(sequence++, paragraph.Substring(lastIndex));
|
|
}
|
|
|
|
builder.CloseElement();
|
|
}
|
|
};
|
|
}
|
|
|
|
private CardData? LookupCard(string cardName)
|
|
{
|
|
return _cardLookup.GetValueOrDefault(cardName);
|
|
}
|
|
}
|