Vibe Google Analytics

This commit is contained in:
2026-06-25 18:55:04 -04:00
parent fdf8e754f5
commit 73ae3eac53
86 changed files with 53925 additions and 46039 deletions
+57 -48
View File
@@ -1,3 +1,4 @@
@using System.Text.RegularExpressions
@namespace Chrono.Components
@if (Card != null)
@@ -10,7 +11,7 @@
{
<div class="detail-image">
<img src="@Card.ImagePath" alt="@Card.Name"
onerror="this.style.display='none';this.parentElement.style.display='none'" />
onerror="this.style.display='none';this.parentElement.style.display='none'"/>
</div>
}
<div class="detail-info">
@@ -88,7 +89,8 @@
var target = LookupCard(targetName);
if (target != null)
{
<button class="inline-card-btn" @onclick="() => Navigate(target)">@targetName</button>
<button class="inline-card-btn"
@onclick="() => Navigate(target)">@targetName</button>
}
else
{
@@ -108,7 +110,8 @@
var fromCard = LookupCard(Card.ImmortalizeFrom);
if (fromCard != null)
{
<button class="inline-card-btn" @onclick="() => Navigate(fromCard)">@Card.ImmortalizeFrom</button>
<button class="inline-card-btn"
@onclick="() => Navigate(fromCard)">@Card.ImmortalizeFrom</button>
}
else
{
@@ -181,7 +184,9 @@
{
await Http.PostAsJsonAsync("api/notes", new CardNote { CardName = Card.Name, Note = currentNote });
}
catch { }
catch
{
}
finally
{
isSaving = false;
@@ -209,64 +214,68 @@
string.Equals(c.Name, cardName, StringComparison.OrdinalIgnoreCase));
}
private RenderFragment RenderDescription(string description) => builder =>
private RenderFragment RenderDescription(string description)
{
var cardNames = CardDatabase.Cards
.Select(c => c.Name)
.Where(n => !string.IsNullOrWhiteSpace(n))
.OrderByDescending(n => n.Length)
.ToList();
int seq = 0;
var remaining = description;
while (!string.IsNullOrEmpty(remaining))
return builder =>
{
int bestIdx = -1;
string? bestName = null;
var cardNames = CardDatabase.Cards
.Select(c => c.Name)
.Where(n => !string.IsNullOrWhiteSpace(n))
.OrderByDescending(n => n.Length)
.ToList();
foreach (var name in cardNames)
var seq = 0;
var remaining = description;
while (!string.IsNullOrEmpty(remaining))
{
var pattern = $@"\b{System.Text.RegularExpressions.Regex.Escape(name)}\b";
var match = System.Text.RegularExpressions.Regex.Match(remaining, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
var bestIdx = -1;
string? bestName = null;
if (match.Success)
foreach (var name in cardNames)
{
if (bestIdx == -1 || match.Index < bestIdx)
var pattern = $@"\b{Regex.Escape(name)}\b";
var match = Regex.Match(remaining, pattern, RegexOptions.IgnoreCase);
if (match.Success)
{
bestIdx = match.Index;
bestName = match.Value;
if (bestIdx == -1 || match.Index < bestIdx)
{
bestIdx = match.Index;
bestName = match.Value;
}
}
}
}
if (bestIdx != -1 && bestName != null)
{
if (bestIdx > 0)
builder.AddContent(seq++, remaining[..bestIdx]);
var card = LookupCard(bestName);
if (card != null)
if (bestIdx != -1 && bestName != null)
{
builder.OpenElement(seq++, "button");
builder.AddAttribute(seq++, "class", "inline-card-btn");
builder.AddAttribute(seq++, "onclick",
EventCallback.Factory.Create(this, () => Navigate(card)));
builder.AddContent(seq++, bestName);
builder.CloseElement();
if (bestIdx > 0)
builder.AddContent(seq++, remaining[..bestIdx]);
var card = LookupCard(bestName);
if (card != null)
{
builder.OpenElement(seq++, "button");
builder.AddAttribute(seq++, "class", "inline-card-btn");
builder.AddAttribute(seq++, "onclick",
EventCallback.Factory.Create(this, () => Navigate(card)));
builder.AddContent(seq++, bestName);
builder.CloseElement();
}
else
{
builder.AddContent(seq++, bestName);
}
remaining = remaining[(bestIdx + bestName.Length)..];
}
else
{
builder.AddContent(seq++, bestName);
builder.AddContent(seq++, remaining);
remaining = "";
}
}
};
}
remaining = remaining[(bestIdx + bestName.Length)..];
}
else
{
builder.AddContent(seq++, remaining);
remaining = "";
}
}
};
}
+8 -3
View File
@@ -8,8 +8,12 @@
}
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.card-detail {
@@ -231,7 +235,8 @@
text-decoration-color: #7b73ff;
}
@@media (max-width: 768px) {
@
@media (max-width: 768px) {
.detail-layout {
flex-direction: column;
padding: 1rem;