Add deck analysis panel with mana production/consumption bars and oracle text search
Threads a new produced_mana/produces_colorless field through the whole card read path (ingest, library, filters, decks, search) so the deck view can show what colors a deck's manabase actually produces, alongside its existing color identity. Also adds a mana consumption bar (colored casting costs of nonland spells) and stacks the mana curve histogram by color. Adds an oracle-text substring filter to the library search, mirroring the existing location filter. Rearranges the deck sidebar list into two rows (name, then format chip + actions) so long names and action buttons no longer collide, and removes the drop shadows from the commander hero panel/image. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
59
src/App.tsx
59
src/App.tsx
@@ -2,7 +2,14 @@ import { useEffect, useRef, useState, useCallback, ReactNode } from "react";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { open, save } from "@tauri-apps/plugin-dialog";
|
||||
import { api, IngestProgress, IngestStageInfo, LibraryStats, Status } from "./api";
|
||||
import { HoverPreviewProvider, IconButton, Icons, usePersistedState } from "./components";
|
||||
import {
|
||||
ColorDistributionBar,
|
||||
HoverPreviewProvider,
|
||||
IconButton,
|
||||
Icons,
|
||||
StatTile,
|
||||
usePersistedState,
|
||||
} from "./components";
|
||||
import { CardEntry } from "./views/CardEntry";
|
||||
import { LibraryBrowser } from "./views/LibraryBrowser";
|
||||
import { DeckView } from "./views/DeckView";
|
||||
@@ -284,49 +291,15 @@ export default function App() {
|
||||
<div className="lib-stats-loading">Loading…</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="lib-stats-numbers">
|
||||
<div className="lib-stat">
|
||||
<span className="lib-stat-value">
|
||||
{libStats.unique_cards.toLocaleString()}
|
||||
</span>
|
||||
<span className="lib-stat-label">unique</span>
|
||||
</div>
|
||||
<div className="lib-stat">
|
||||
<span className="lib-stat-value">
|
||||
{libStats.total_copies.toLocaleString()}
|
||||
</span>
|
||||
<span className="lib-stat-label">copies</span>
|
||||
</div>
|
||||
<div className="lib-stat">
|
||||
<span className="lib-stat-value">
|
||||
{libStats.deck_count.toLocaleString()}
|
||||
</span>
|
||||
<span className="lib-stat-label">decks</span>
|
||||
</div>
|
||||
<div className="stat-tiles-row">
|
||||
<StatTile value={libStats.unique_cards.toLocaleString()} label="unique" />
|
||||
<StatTile value={libStats.total_copies.toLocaleString()} label="copies" />
|
||||
<StatTile value={libStats.deck_count.toLocaleString()} label="decks" />
|
||||
</div>
|
||||
{libStats.total_copies > 0 && (
|
||||
<div className="lib-color-bar">
|
||||
{(
|
||||
[
|
||||
["W", libStats.color_counts[0]],
|
||||
["U", libStats.color_counts[1]],
|
||||
["B", libStats.color_counts[2]],
|
||||
["R", libStats.color_counts[3]],
|
||||
["G", libStats.color_counts[4]],
|
||||
["C", libStats.colorless_count],
|
||||
] as [string, number][]
|
||||
).map(([code, count]) =>
|
||||
count > 0 ? (
|
||||
<span
|
||||
key={code}
|
||||
className={`lib-color-seg ${code}`}
|
||||
style={{ flexGrow: count }}
|
||||
title={`${code === "C" ? "Colorless" : code}: ${count.toLocaleString()} copies`}
|
||||
/>
|
||||
) : null,
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<ColorDistributionBar
|
||||
colorCounts={libStats.color_counts}
|
||||
colorlessCount={libStats.colorless_count}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<div className="lib-stats-sub">
|
||||
|
||||
Reference in New Issue
Block a user