Vibe link and card meta data fixes
This commit is contained in:
@@ -235,7 +235,7 @@
|
||||
text-decoration-color: #7b73ff;
|
||||
}
|
||||
|
||||
@
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.detail-layout {
|
||||
flex-direction: column;
|
||||
|
||||
@@ -26,11 +26,15 @@
|
||||
@onclick='@(() => SetCategory("Immortalized"))'>
|
||||
<i class="bi bi-person-fill"></i> Immortalized
|
||||
</button>
|
||||
<!-- //Todo make agent being linked to immortal for side by side sorting
|
||||
<button class="tab agent @(agentLink ? "active" : "")" @onclick='@(() => ToggleAgentLink())'>
|
||||
<i class="bi bi-person-fill"></i> Link
|
||||
</button>
|
||||
-->
|
||||
|
||||
<div class="tab link-toggle @(agentLink ? "active" : "")" @onclick="ToggleAgentLink" title="Link Agents and Immortalized cards">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
<span>Linked</span>
|
||||
<span class="toggle-switch @(agentLink ? "on" : "off")"></span>
|
||||
</div>
|
||||
|
||||
<div class="category-divider"></div>
|
||||
|
||||
<button class="tab spell @(categoryFilter == "Spell" ? "active" : "")" @onclick='@(() => SetCategory("Spell"))'>
|
||||
<i class="bi bi-wand"></i> Spells
|
||||
</button>
|
||||
@@ -206,21 +210,70 @@
|
||||
|
||||
private IEnumerable<CardData> ApplyFilters()
|
||||
{
|
||||
var filtered = allCards.Where(c =>
|
||||
var primarySet = allCards.Where(c =>
|
||||
c.MatchesSearch(search) &&
|
||||
(categoryFilter == "" || c.Category == categoryFilter) &&
|
||||
(factionFilter == "" || c.Faction == factionFilter) &&
|
||||
(costFilter == "" || c.Cost?.ToString() == costFilter)
|
||||
);
|
||||
|
||||
return sortBy switch
|
||||
var sortedPrimary = sortBy switch
|
||||
{
|
||||
"Cost" => sortDescending ? filtered.OrderByDescending(c => c.Cost) : filtered.OrderBy(c => c.Cost),
|
||||
"Efficiency" => sortDescending ? filtered.OrderByDescending(c => c.StatEfficiency) : filtered.OrderBy(c => c.StatEfficiency),
|
||||
"Attack" => sortDescending ? filtered.OrderByDescending(c => c.Attack) : filtered.OrderBy(c => c.Attack),
|
||||
"Health" => sortDescending ? filtered.OrderByDescending(c => c.Health) : filtered.OrderBy(c => c.Health),
|
||||
_ => sortDescending ? filtered.OrderByDescending(c => c.Name) : filtered.OrderBy(c => c.Name)
|
||||
"Cost" => sortDescending ? primarySet.OrderByDescending(c => c.Cost) : primarySet.OrderBy(c => c.Cost),
|
||||
"Efficiency" => sortDescending ? primarySet.OrderByDescending(c => c.StatEfficiency) : primarySet.OrderBy(c => c.StatEfficiency),
|
||||
"Attack" => sortDescending ? primarySet.OrderByDescending(c => c.Attack) : primarySet.OrderBy(c => c.Attack),
|
||||
"Health" => sortDescending ? primarySet.OrderByDescending(c => c.Health) : primarySet.OrderBy(c => c.Health),
|
||||
_ => sortDescending ? primarySet.OrderByDescending(c => c.Name) : primarySet.OrderBy(c => c.Name)
|
||||
};
|
||||
|
||||
if (!agentLink)
|
||||
{
|
||||
return sortedPrimary;
|
||||
}
|
||||
|
||||
var result = new List<CardData>();
|
||||
var seen = new HashSet<string>();
|
||||
foreach (var card in sortedPrimary)
|
||||
{
|
||||
if (seen.Contains(card.Name)) continue;
|
||||
|
||||
// Determine the "Chain Head" (the Agent)
|
||||
var head = card;
|
||||
if (card.Category == "Immortalized" && card.ImmortalizeFrom != null)
|
||||
{
|
||||
var source = allCards.FirstOrDefault(c => c.Name == card.ImmortalizeFrom);
|
||||
if (source != null) head = source;
|
||||
}
|
||||
|
||||
// Add the chain starting from head
|
||||
if (!seen.Contains(head.Name))
|
||||
{
|
||||
result.Add(head);
|
||||
seen.Add(head.Name);
|
||||
}
|
||||
|
||||
if (head.ImmortalizeTo != null)
|
||||
{
|
||||
foreach (var targetName in head.ImmortalizeTo)
|
||||
{
|
||||
if (seen.Contains(targetName)) continue;
|
||||
var linked = allCards.FirstOrDefault(c => c.Name == targetName);
|
||||
if (linked != null)
|
||||
{
|
||||
result.Add(linked);
|
||||
seen.Add(linked.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the original card is added if it was somehow not part of the head's chain
|
||||
if (!seen.Contains(card.Name))
|
||||
{
|
||||
result.Add(card);
|
||||
seen.Add(card.Name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void SetImmortal(string imm)
|
||||
@@ -253,6 +306,12 @@
|
||||
private void ToggleAgentLink()
|
||||
{
|
||||
agentLink = !agentLink;
|
||||
OnToggleAgentLink();
|
||||
}
|
||||
|
||||
private void OnToggleAgentLink()
|
||||
{
|
||||
_ = AnalyticsService.TrackEvent("toggle_agent_link", new { enabled = agentLink });
|
||||
}
|
||||
|
||||
private void ClearCostFilter()
|
||||
|
||||
@@ -74,6 +74,62 @@
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.category-divider {
|
||||
width: 1px;
|
||||
height: 1.5rem;
|
||||
background: var(--border);
|
||||
margin: 0 0.6rem;
|
||||
align-self: center;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.tab.link-toggle {
|
||||
border-style: dashed;
|
||||
gap: 0.6rem;
|
||||
user-select: none;
|
||||
padding-right: 0.8rem;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
|
||||
.tab.link-toggle.active {
|
||||
border-style: solid;
|
||||
background: rgba(108, 99, 255, 0.1);
|
||||
border-color: var(--accent);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
background: var(--bg-hover);
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
transition: all 0.2s;
|
||||
border: 1px solid var(--border);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.toggle-switch.on {
|
||||
background: var(--accent);
|
||||
border-color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.toggle-switch::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.toggle-switch.on::after {
|
||||
transform: translateX(12px);
|
||||
}
|
||||
|
||||
/* ── Filter Bar ── */
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
|
||||
Vendored
+10
-10
@@ -13,12 +13,12 @@
|
||||
"state": {
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "Deck/Overflowing Security.md",
|
||||
"file": "Agent/[[Phasetide]]/Stern Arbiter.md",
|
||||
"mode": "source",
|
||||
"source": false
|
||||
},
|
||||
"icon": "lucide-file",
|
||||
"title": "Overflowing Security"
|
||||
"title": "Stern Arbiter"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -53,7 +53,7 @@
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "The Ripper",
|
||||
"query": "...",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
@@ -74,12 +74,12 @@
|
||||
"title": "Bookmarks"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"currentTab": 1
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 331.5,
|
||||
"collapsed": true
|
||||
"width": 331.5
|
||||
},
|
||||
"right": {
|
||||
"id": "47f3bcd7aed212ab",
|
||||
@@ -186,8 +186,11 @@
|
||||
},
|
||||
"active": "852a1aaf6b54ec43",
|
||||
"lastOpenFiles": [
|
||||
"Deck/Big Energy.md",
|
||||
"Immortalized/[[Sungrace]]/Time Devourer Soval.md",
|
||||
"Spell/[[Phasetide]]/By the Numbers.md",
|
||||
"Immortalized/[[Splintergleam]]/Boatswain Corvus.md",
|
||||
"Deck/Overflowing Security.md",
|
||||
"Deck/Big Energy.md",
|
||||
"Agent/[[Lifeblood]]/Aardvark Precinct Captain.md",
|
||||
"Agent/[[Lifeblood]]/Egg Tender.md",
|
||||
"Quest/Daily Wins.md",
|
||||
@@ -212,9 +215,6 @@
|
||||
"Rule/Fast.md",
|
||||
"_Store.base",
|
||||
"_Timeline.base",
|
||||
"Store/Core Set Packs x1.md",
|
||||
"Store/Core Set Packs x5.md",
|
||||
"Store/Core Set Packs x10.md",
|
||||
"_Quests.base",
|
||||
"Quest",
|
||||
"Store",
|
||||
|
||||
@@ -6,8 +6,8 @@ rarity: Lost
|
||||
cost: 7
|
||||
attack: 5
|
||||
health: 5
|
||||
description: "[[Play]]: Return an Action from your Graveyard to your hand. It costs 3 less and has \"If I would be put into a Graveyard, instead [[Erase]] me.\"."
|
||||
immortalizeWhen: "I've seen you play 3+ cards wi..."
|
||||
description: '[[Play]]: Return an Action from your Graveyard to your hand. It costs 3 less and has "If I would be put into a Graveyard, instead [[Erase]] me.".'
|
||||
immortalizeWhen: I've seen you play 3+ cards with reduced cost.
|
||||
immortalizeTo:
|
||||
- "[[Grand Judge Dhael]]"
|
||||
immortalizeFrom: N/A
|
||||
|
||||
@@ -6,7 +6,7 @@ rarity: Lost
|
||||
cost: 7
|
||||
attack: 6
|
||||
health: 10
|
||||
description: "[[Overpower]]. Round Start: Deal 1 to the enemy Core twice. When you deal non-combat damage to the enemy Core, grant the weakest enemy Exposed. [[Core Strike]]: Deal 3 to all enemies and t..."
|
||||
description: "[[Overpower]]. Round Start: Deal 1 to the enemy Core twice. When you deal non-combat damage to the enemy Core, grant the weakest enemy Exposed. [[Core Strike]]: Deal 3 to all enemies and the enemy Core.]]"
|
||||
immortalizeWhen: N/A
|
||||
immortalizeTo:
|
||||
- N/A
|
||||
|
||||
@@ -6,7 +6,7 @@ rarity: Lost
|
||||
cost: 10
|
||||
attack: 12
|
||||
health: 12
|
||||
description: "For each Timeline in the Timeline Stack, I gain a random positive keyword. The first time each round I would be destroyed, instead heal me to my maximum durability and destroy the..."
|
||||
description: For each Timeline in the Timeline Stack, I gain a random positive keyword. The first time each round I would be destroyed, instead heal me to my maximum durability and destroy the current Timeline.
|
||||
immortalizeWhen: N/A
|
||||
immortalizeTo:
|
||||
- N/A
|
||||
|
||||
@@ -4,7 +4,7 @@ category: Spell
|
||||
artist: Bi Pi
|
||||
rarity: Common
|
||||
cost: 2
|
||||
description: "Reveal the top card of both decks. Create a copy of the card with the higher cost in hand, then shuffle both cards into their respective decks. In a tie, create a copy of both card..."
|
||||
description: Reveal the top card of both decks. Create a copy of the card with the higher cost in hand, then shuffle both cards into their respective decks. In a tie, create a copy of both cards.
|
||||
faction: "[[Phasetide]]"
|
||||
set: "[[Core Set]]"
|
||||
speed: "[[Immediate]]"
|
||||
|
||||
Reference in New Issue
Block a user