More notes and added store precons
This commit is contained in:
@@ -226,6 +226,14 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Overflow",
|
||||
Category = "Keyword",
|
||||
Description = "Adding more energy then your reserves increase this passive stack by 1.",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Overpower",
|
||||
Category = "Keyword",
|
||||
@@ -330,6 +338,20 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Beta Season 1 Track",
|
||||
Category = "Pass",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Onboarding Track",
|
||||
Category = "Pass",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Daily Wins",
|
||||
Category = "Quest",
|
||||
@@ -430,6 +452,14 @@ public static class CardDatabase
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Energy Reserves",
|
||||
Category = "Rule",
|
||||
Description = "Up to three unused mana can be banked per turn for spell usage only.",
|
||||
Archetypes = [
|
||||
],
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Fast",
|
||||
Category = "Rule",
|
||||
|
||||
@@ -7,6 +7,66 @@ public static class DeckDatabase
|
||||
{
|
||||
public static readonly System.Collections.Generic.List<DeckData> Decks =
|
||||
[
|
||||
new()
|
||||
{
|
||||
Name = "Aggro",
|
||||
Cards = [
|
||||
"Headbanging",
|
||||
"Headbanging",
|
||||
"Chronal Scan",
|
||||
"Chronal Scan",
|
||||
"Gilded Behemoth",
|
||||
"Gilded Behemoth",
|
||||
"Bathe in Flames",
|
||||
"Bathe in Flames",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Enhanced Retriever",
|
||||
"Enhanced Retriever",
|
||||
"Enhanced Retriever",
|
||||
"Fractal Phantasm",
|
||||
"Fractal Phantasm",
|
||||
"Fractal Phantasm",
|
||||
"Denizen of Flames",
|
||||
"Denizen of Flames",
|
||||
"Denizen of Flames",
|
||||
"Glittering Gladiator",
|
||||
"Glittering Gladiator",
|
||||
"Glittering Gladiator",
|
||||
"Desperate Primordial",
|
||||
"Desperate Primordial",
|
||||
"Desperate Primordial",
|
||||
"Blazing Shifter",
|
||||
"Blazing Shifter",
|
||||
"Blazing Shifter",
|
||||
"Devoted Bloodletter",
|
||||
"Devoted Bloodletter",
|
||||
"Devoted Bloodletter",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Bloodbolt",
|
||||
"Bloodbolt",
|
||||
"Bloodbolt",
|
||||
"Go for the Heart",
|
||||
"Go for the Heart",
|
||||
"Go for the Heart",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Efficient Scrapbot",
|
||||
"Bloodline Tracker",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Splintergleam",
|
||||
"Singularity",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Big Energy",
|
||||
@@ -69,6 +129,83 @@ public static class DeckDatabase
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "AUHUE2LHEBCW4ZLSM54SAQ3POB4QWY3PNZZXI4TVMN2GKZBTAADACASPCICESCQCAUFDCAYGAMCAGAQDDYBQCAYBAOTQCAYQAMDQG",
|
||||
DeckType = "custom",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Example",
|
||||
Cards = [
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
],
|
||||
IsVisible = false,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Kyln Control",
|
||||
Cards = [
|
||||
"Devourer Spawn",
|
||||
"Devourer Spawn",
|
||||
"Radiant Channeling",
|
||||
"Radiant Channeling",
|
||||
"Brilliant Martyr",
|
||||
"Brilliant Martyr",
|
||||
"Brilliant Martyr",
|
||||
"Hidden Locus",
|
||||
"Hidden Locus",
|
||||
"Hidden Locus",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Sunshock",
|
||||
"Sunshock",
|
||||
"Sunshock",
|
||||
"Throw into the Sun",
|
||||
"Throw into the Sun",
|
||||
"Throw into the Sun",
|
||||
"Enlightened Refugee",
|
||||
"Enlightened Refugee",
|
||||
"Enlightened Refugee",
|
||||
"Scuttling Spares",
|
||||
"Scuttling Spares",
|
||||
"Scuttling Spares",
|
||||
"Nascent Clone",
|
||||
"Nascent Clone",
|
||||
"Nascent Clone",
|
||||
"Recycler",
|
||||
"Recycler",
|
||||
"Recycler",
|
||||
"Rapid Iteration",
|
||||
"Rapid Iteration",
|
||||
"Rapid Iteration",
|
||||
"Frontline Fellowship",
|
||||
"Frontline Fellowship",
|
||||
"Frontline Fellowship",
|
||||
"Timestop",
|
||||
"Timestop",
|
||||
"Timestop",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Planet Seeder",
|
||||
"Traffic Conductor",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Sungrace",
|
||||
"Singularity",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
@@ -97,6 +234,246 @@ public static class DeckDatabase
|
||||
Factions = [
|
||||
],
|
||||
IsVisible = false,
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Rewind",
|
||||
Cards = [
|
||||
"Holder of the Instruments",
|
||||
"Holder of the Instruments",
|
||||
"Invigorating Balm",
|
||||
"Invigorating Balm",
|
||||
"Fervent Mycologist",
|
||||
"Fervent Mycologist",
|
||||
"Fervent Mycologist",
|
||||
"Pterosaur Rider",
|
||||
"Pterosaur Rider",
|
||||
"Pterosaur Rider",
|
||||
"Scent the Prey",
|
||||
"Scent the Prey",
|
||||
"Scent the Prey",
|
||||
"Curious Acolyte",
|
||||
"Curious Acolyte",
|
||||
"Curious Acolyte",
|
||||
"Temple Analyst",
|
||||
"Temple Analyst",
|
||||
"Temple Analyst",
|
||||
"Holy Cleaner",
|
||||
"Holy Cleaner",
|
||||
"Holy Cleaner",
|
||||
"Karmic Debtor",
|
||||
"Karmic Debtor",
|
||||
"Karmic Debtor",
|
||||
"Divergence Assassin",
|
||||
"Divergence Assassin",
|
||||
"Divergence Assassin",
|
||||
"Chronicle of the One",
|
||||
"Chronicle of the One",
|
||||
"Chronicle of the One",
|
||||
"Prayer of Rescue",
|
||||
"Prayer of Rescue",
|
||||
"Prayer of Rescue",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Rescind Authorization",
|
||||
"Rescind Authorization",
|
||||
"Rescind Authorization",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Zealot of the Hunt",
|
||||
"Nonlethal Special Forces",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Phasetide",
|
||||
"Lifeblood",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Somnus Spam",
|
||||
Cards = [
|
||||
"Return to Stillness",
|
||||
"Pressure Spike",
|
||||
"Pressure Spike",
|
||||
"Bury the Evidence",
|
||||
"Bury the Evidence",
|
||||
"Hush Now",
|
||||
"Hush Now",
|
||||
"Quiet Repose",
|
||||
"Quiet Repose",
|
||||
"Spirit's Lament",
|
||||
"Spirit's Lament",
|
||||
"Stern Arbiter",
|
||||
"Stern Arbiter",
|
||||
"Braindead Bouncer",
|
||||
"Braindead Bouncer",
|
||||
"Braindead Bouncer",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Nameless Spirit",
|
||||
"Nameless Spirit",
|
||||
"Nameless Spirit",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Sensory Deprivation Pod",
|
||||
"Sensory Deprivation Pod",
|
||||
"Sensory Deprivation Pod",
|
||||
"Mind Over Matter",
|
||||
"Mind Over Matter",
|
||||
"Mind Over Matter",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Backhand",
|
||||
"Snap Back",
|
||||
"Snap Back",
|
||||
"Snap Back",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Librarian's Assistant",
|
||||
"Bareknuckle Inquisitor",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Silence",
|
||||
"Phasetide",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Sunbleed",
|
||||
Cards = [
|
||||
"Chaos Control",
|
||||
"Chaos Control",
|
||||
"Chaos Control",
|
||||
"Persistent Squire",
|
||||
"Persistent Squire",
|
||||
"Persistent Squire",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Bright-Eyed Supplicant",
|
||||
"Red Reaper",
|
||||
"Red Reaper",
|
||||
"Red Reaper",
|
||||
"Hungry Engine",
|
||||
"Hungry Engine",
|
||||
"Hungry Engine",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Channel Vigor",
|
||||
"Kintsu-Kai",
|
||||
"Kintsu-Kai",
|
||||
"Kintsu-Kai",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Paradox Cacophony",
|
||||
"Ironblood Elixir",
|
||||
"Ironblood Elixir",
|
||||
"Ironblood Elixir",
|
||||
"Rippling Resplendence",
|
||||
"Rippling Resplendence",
|
||||
"Rippling Resplendence",
|
||||
"Soothing Glow",
|
||||
"Soothing Glow",
|
||||
"BREAK AND SHATTER!",
|
||||
"BREAK AND SHATTER!",
|
||||
"Kinetic Absorber",
|
||||
"Kinetic Absorber",
|
||||
"Kinetic Absorber",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
"Debris Collector",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Containment Breach",
|
||||
"Devoted Bloodletter",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Sungrace",
|
||||
"Splintergleam",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
},
|
||||
new()
|
||||
{
|
||||
Name = "Tempo Deplete",
|
||||
Cards = [
|
||||
"Cascading Serenity",
|
||||
"Mulch",
|
||||
"Mulch",
|
||||
"Unstoppable Growth",
|
||||
"Unstoppable Growth",
|
||||
"Somber Astronomer",
|
||||
"Somber Astronomer",
|
||||
"Destiny Ripper",
|
||||
"Destiny Ripper",
|
||||
"Forest Recluse",
|
||||
"Forest Recluse",
|
||||
"The Forgotten Tale",
|
||||
"The Forgotten Tale",
|
||||
"Gnosis",
|
||||
"Gnosis",
|
||||
"Muffle",
|
||||
"Muffle",
|
||||
"Hush Now",
|
||||
"Hush Now",
|
||||
"Sleepy Druid",
|
||||
"Sleepy Druid",
|
||||
"Sleepy Druid",
|
||||
"Zealot of the Hunt",
|
||||
"Zealot of the Hunt",
|
||||
"Zealot of the Hunt",
|
||||
"Bloom",
|
||||
"Bloom",
|
||||
"Bloom",
|
||||
"Focused Adaptation",
|
||||
"Focused Adaptation",
|
||||
"Focused Adaptation",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Rotting Rocker",
|
||||
"Telepathic Scavenger",
|
||||
"Telepathic Scavenger",
|
||||
"Telepathic Scavenger",
|
||||
"Not so Fast",
|
||||
"Not so Fast",
|
||||
"Not so Fast",
|
||||
],
|
||||
Keycards = [
|
||||
],
|
||||
Divers = [
|
||||
"Egg Tender",
|
||||
"Redactionist",
|
||||
],
|
||||
Description = "",
|
||||
Factions = [
|
||||
"Lifeblood",
|
||||
"Silence",
|
||||
],
|
||||
IsVisible = true,
|
||||
DeckCode = "",
|
||||
DeckType = "store",
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ public static class DocDatabase
|
||||
{
|
||||
Title = "Splintergleam",
|
||||
Category = "Faction",
|
||||
Content = "Concepts:\n- Self Damage\n- Bleed\n-",
|
||||
Content = "# Self Damage\n\nCan hurt it's own units for power. Has [[Bleed]] to make reoccurring damage on units very easy.\n\n# Core Damage \n\nCan hurt both cores easily. Has [[Breakdown]] to take advantage of having an injured core for more damage.",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Faction" },
|
||||
@@ -204,7 +204,7 @@ public static class DocDatabase
|
||||
{
|
||||
Title = "Sungrace",
|
||||
Category = "Faction",
|
||||
Content = "Concepts:\n- Ramp\n- Using and Replenishing Reserved Energy\n-",
|
||||
Content = "# Energy Reserves\n\nCare about always having banked energy. Spells can refund themselves when using [[Energy Reserves]], or get stronger is you [[Overflow]] your energy reserve.\n\nConcepts:\n- Ramp\n- Using and Replenishing Reserved Energy\n-",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Faction" },
|
||||
@@ -310,6 +310,17 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Overflow",
|
||||
Category = "Keyword",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Keyword" },
|
||||
{ "description", "Adding more energy then your reserves increase this passive stack by 1." },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Overpower",
|
||||
Category = "Keyword",
|
||||
@@ -453,6 +464,30 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Beta Season 1 Track",
|
||||
Category = "Pass",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Pass" },
|
||||
{ "expPer", "500" },
|
||||
{ "size", "30" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Onboarding Track",
|
||||
Category = "Pass",
|
||||
Content = "| Tier | Reward |\n| ---- | -------------------------------- |\n| 1 | Sprouts Record |\n| 2 | 120 Core Charges |\n| 3 | Burn Precon |\n| 4 | 120 Core Charges, 25 Flux |\n| 5 | Profile Pictures |\n| 6 | Emotes |\n| 7 | 120 Core Charges |\n| 8 | Profile Pictures |\n| 9 | 60 Core Charges, 50 Flux |\n| 10 | 240 Core Charges, 1 Draft Ticket |\n\n| Core Charges | Flux |\n| ------------ | ---- |\n| 660 | 75 |",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "expPer", "30" },
|
||||
{ "size", "10" },
|
||||
{ "category", "Pass" },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Daily Wins",
|
||||
Category = "Quest",
|
||||
@@ -596,6 +631,17 @@ public static class DocDatabase
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Energy Reserves",
|
||||
Category = "Rule",
|
||||
Content = "",
|
||||
Frontmatter = new()
|
||||
{
|
||||
{ "category", "Rule" },
|
||||
{ "description", "Up to three unused mana can be banked per turn for spell usage only." },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Title = "Fast",
|
||||
Category = "Rule",
|
||||
|
||||
@@ -6,8 +6,13 @@
|
||||
<div class="decks-page">
|
||||
<div class="decks-header">
|
||||
<h1>Decks</h1>
|
||||
<p class="text-secondary">@decks.Count deck@(decks.Count != 1 ? "s" : "")</p>
|
||||
<p class="text-primary">Please note these are my crafted decks. They are probably not optimal or good. See <a href="https://runeterra.ar/chrono/home">Runeterra.ar</a> and check out the decks from recognizable names there. This is not an ad, just common sense.</p>
|
||||
<div class="decks-header-row">
|
||||
<p class="text-secondary">@decks.Count deck@(decks.Count != 1 ? "s" : "")</p>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="showPrecons" @bind="showPrecons" @bind:after="RefreshDecks">
|
||||
<label class="form-check-label" for="showPrecons">Show Precons</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="deck-list">
|
||||
@@ -25,6 +30,11 @@
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="deck-card-factions">
|
||||
<span class="faction-badge">@deck.DeckType</span>
|
||||
</div>
|
||||
|
||||
<div class="deck-card-meta">
|
||||
<span>@deck.Cards.Distinct().Count() unique, @deck.Cards.Count total</span>
|
||||
@if (deck.Keycards.Count > 0)
|
||||
@@ -56,10 +66,22 @@
|
||||
|
||||
@code {
|
||||
private List<DeckData> decks = [];
|
||||
private bool showPrecons = false;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
decks = DeckDatabase.Decks.Where(d => d.IsVisible).ToList();
|
||||
RefreshDecks();
|
||||
}
|
||||
|
||||
private void RefreshDecks()
|
||||
{
|
||||
decks = DeckDatabase.Decks
|
||||
.Where(d => d.IsVisible)
|
||||
.Where(d =>
|
||||
showPrecons
|
||||
? d.DeckType is "precon" or "store" :
|
||||
d.DeckType is "custom")
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static string Truncate(string text, int maxLength)
|
||||
|
||||
@@ -8,6 +8,16 @@
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.decks-header-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.decks-header-row p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.decks-header h1 {
|
||||
margin: 0 0 0.25rem;
|
||||
}
|
||||
|
||||
+41
-125
@@ -39,10 +39,7 @@
|
||||
<div class="doc-card" @onclick="() => SelectDoc(doc)">
|
||||
<div class="doc-card-category">@doc.Category</div>
|
||||
<h3 class="doc-card-title">@doc.Title</h3>
|
||||
@{
|
||||
var desc = GetDescription(doc);
|
||||
}
|
||||
@if (desc != null)
|
||||
@if (GetField(doc, "description") is { Length: > 0 } desc)
|
||||
{
|
||||
<p class="doc-card-desc">@desc</p>
|
||||
}
|
||||
@@ -67,37 +64,34 @@
|
||||
<header class="doc-header">
|
||||
<div class="doc-meta">@selectedDoc.Category</div>
|
||||
<h1>@selectedDoc.Title</h1>
|
||||
@{
|
||||
var desc = GetDescription(selectedDoc);
|
||||
}
|
||||
@if (desc != null)
|
||||
{
|
||||
<p class="doc-description">@desc</p>
|
||||
}
|
||||
</header>
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(selectedDoc.Content))
|
||||
{
|
||||
<div class="doc-body">
|
||||
@((MarkupString)FormatContent(selectedDoc.Content))
|
||||
</div>
|
||||
}
|
||||
<div class="doc-fields">
|
||||
@{
|
||||
var fm = selectedDoc.Frontmatter;
|
||||
}
|
||||
|
||||
@if (HasExtraFrontmatter(selectedDoc))
|
||||
{
|
||||
<div class="doc-extra">
|
||||
<h3>Details</h3>
|
||||
<div class="doc-frontmatter">
|
||||
@foreach (var kvp in selectedDoc.Frontmatter.Where(kvp => kvp.Key != "category" && kvp.Key != "description"))
|
||||
@foreach (var kvp in fm)
|
||||
{
|
||||
var key = kvp.Key;
|
||||
var val = kvp.Value;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(val)) continue;
|
||||
|
||||
<div class="doc-field">
|
||||
<span class="doc-field-key">@GetLabel(key)</span>
|
||||
|
||||
@if (key == "description")
|
||||
{
|
||||
<div class="fm-item">
|
||||
<span class="fm-key">@kvp.Key</span>
|
||||
<span class="fm-value">@kvp.Value</span>
|
||||
</div>
|
||||
<p class="doc-field-desc">@val</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="doc-field-val">@val</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
}
|
||||
</main>
|
||||
@@ -122,8 +116,7 @@
|
||||
.Where(d => (selectedCategory == null || d.Category == selectedCategory) &&
|
||||
(string.IsNullOrWhiteSpace(searchQuery) ||
|
||||
d.Title.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ||
|
||||
(GetDescription(d)?.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||
d.Content.Contains(searchQuery, StringComparison.OrdinalIgnoreCase)));
|
||||
(GetField(d, "description")?.Contains(searchQuery, StringComparison.OrdinalIgnoreCase) ?? false)));
|
||||
|
||||
private void SelectCategory(string? category)
|
||||
{
|
||||
@@ -136,102 +129,25 @@
|
||||
selectedDoc = doc;
|
||||
}
|
||||
|
||||
private static string? GetDescription(DocData doc)
|
||||
private static string? GetField(DocData doc, string key)
|
||||
{
|
||||
return doc.Frontmatter.TryGetValue("description", out var desc) && !string.IsNullOrWhiteSpace(desc) ? desc : null;
|
||||
return doc.Frontmatter.TryGetValue(key, out var val) && !string.IsNullOrWhiteSpace(val) ? val : null;
|
||||
}
|
||||
|
||||
private static bool HasExtraFrontmatter(DocData doc)
|
||||
private static string GetLabel(string key) => key switch
|
||||
{
|
||||
var count = doc.Frontmatter.Count;
|
||||
if (count == 0) return false;
|
||||
if (count == 1 && doc.Frontmatter.ContainsKey("category")) return false;
|
||||
if (count == 2 && doc.Frontmatter.ContainsKey("category") && doc.Frontmatter.ContainsKey("description")) return false;
|
||||
return doc.Frontmatter.Any(kvp => kvp.Key != "category" && kvp.Key != "description");
|
||||
}
|
||||
|
||||
private string FormatContent(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content)) return "";
|
||||
|
||||
var lines = content.Replace("\r\n", "\n").Split('\n');
|
||||
var html = new System.Text.StringBuilder();
|
||||
var inList = false;
|
||||
|
||||
foreach (var rawLine in lines)
|
||||
{
|
||||
var line = rawLine.TrimEnd();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
if (inList) { html.AppendLine("</ul>"); inList = false; }
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.StartsWith("- "))
|
||||
{
|
||||
var item = line[2..].Trim();
|
||||
if (item.Length > 0)
|
||||
{
|
||||
if (!inList) { html.AppendLine("<ul class=\"doc-list-items\">"); inList = true; }
|
||||
html.Append("<li>");
|
||||
html.Append(EncodeInline(item));
|
||||
html.AppendLine("</li>");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inList) { html.AppendLine("</ul>"); inList = false; }
|
||||
|
||||
if (line.EndsWith(":") || line.Contains(":\n"))
|
||||
{
|
||||
var trimmed = line.TrimEnd(':');
|
||||
if (trimmed.Length > 0)
|
||||
{
|
||||
html.Append("<p class=\"doc-label\">");
|
||||
html.Append(System.Web.HttpUtility.HtmlEncode(trimmed));
|
||||
html.AppendLine("</p>");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.Append("<p>");
|
||||
html.Append(EncodeInline(line));
|
||||
html.AppendLine("</p>");
|
||||
}
|
||||
}
|
||||
|
||||
if (inList) html.AppendLine("</ul>");
|
||||
|
||||
return html.ToString();
|
||||
}
|
||||
|
||||
private string EncodeInline(string text)
|
||||
{
|
||||
var result = new System.Text.StringBuilder();
|
||||
var remaining = text;
|
||||
|
||||
while (remaining.Length > 0)
|
||||
{
|
||||
var boldIdx = remaining.IndexOf("**", StringComparison.Ordinal);
|
||||
if (boldIdx >= 0)
|
||||
{
|
||||
var endBold = remaining.IndexOf("**", boldIdx + 2, StringComparison.Ordinal);
|
||||
if (endBold >= 0)
|
||||
{
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining[..boldIdx]));
|
||||
result.Append("<strong>");
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining[(boldIdx + 2)..endBold]));
|
||||
result.Append("</strong>");
|
||||
remaining = remaining[(endBold + 2)..];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
result.Append(System.Web.HttpUtility.HtmlEncode(remaining));
|
||||
break;
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
"category" => "Category",
|
||||
"description" => "Description",
|
||||
"essencePrice" => "Essence Price",
|
||||
"crytalPrice" => "Crystal Price",
|
||||
"coreChargesPrice" => "Core Charges Price",
|
||||
"pricePerPack" => "Price per Pack",
|
||||
"codeCharges" => "Code Charges",
|
||||
"coreCharges" => "Core Charges",
|
||||
"currency" => "Currency",
|
||||
"faction" => "Faction",
|
||||
"exp" => "EXP Reward",
|
||||
"see" => "See Also",
|
||||
_ => string.Concat(key.Select((c, i) => i > 0 && char.IsUpper(c) ? " " + c : c.ToString())),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -171,119 +171,45 @@
|
||||
}
|
||||
|
||||
.doc-header h1 {
|
||||
margin: 0 0 0.75rem;
|
||||
margin: 0;
|
||||
font-size: 1.8rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.doc-description {
|
||||
.doc-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.doc-field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.doc-field-key {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.doc-field-val {
|
||||
font-size: 0.95rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.doc-field-desc {
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.doc-body {
|
||||
line-height: 1.7;
|
||||
font-size: 1rem;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.doc-body p {
|
||||
margin: 0 0 0.6rem;
|
||||
}
|
||||
|
||||
.doc-body p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.doc-label {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.doc-list-items {
|
||||
margin: 0 0 0.8rem;
|
||||
padding-left: 1.5rem;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.doc-list-items li {
|
||||
position: relative;
|
||||
padding: 0.2rem 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.doc-list-items li::before {
|
||||
content: "▸";
|
||||
position: absolute;
|
||||
left: -1.2rem;
|
||||
color: var(--accent);
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.doc-extra {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.doc-extra h3 {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.75rem;
|
||||
color: var(--text-muted);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.doc-frontmatter {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.4rem 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
background: var(--bg-elevated);
|
||||
border-radius: var(--radius);
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.fm-item {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.fm-key {
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
font-size: 0.85rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fm-value {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.doc-link-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: 600;
|
||||
color: var(--accent);
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
text-decoration-color: rgba(108, 99, 255, 0.3);
|
||||
transition: color var(--transition), text-decoration-color var(--transition);
|
||||
}
|
||||
|
||||
.doc-link-btn:hover {
|
||||
color: #7b73ff;
|
||||
text-decoration-color: #7b73ff;
|
||||
border-left: 3px solid var(--accent);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
|
||||
Reference in New Issue
Block a user