Redesign customize player page: two-pane layout + accurate commander tracking#66
Merged
Conversation
…ll list Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two-pane player sheet, accurate commander-damage tracking via typed second card (partner vs background), device-local recents/favorites, and removal of per-seat rotation to fix the upside-down keyboard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Plan A: data foundation & accuracy (Commander.keywords, Player.background, commanderPairingFor, save path). Plan B: device-local recents/favorites via shared_preferences. Plan C: two-pane UI redesign + rotation removal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… flex The left pane wraps PlayerIdentityPanel in a SingleChildScrollView, which gives unbounded height. The panel's Column used a Spacer (flex child), which can't expand under unbounded height — triggering a RenderFlex assertion that cascaded into "not laid out" errors. Replace the Spacer with fixed spacing and shrink-wrap the Column (mainAxisSize.min). Add a widget regression test that pumps the panel inside an unbounded-height scroll view. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
9b718a0 to
330ff15
Compare
Scryfall's image CDN (cards.scryfall.io) now returns HTTP 400 for the
default Dart User-Agent ("Dart/<version> (dart:io)") that Flutter's
Image.network sends — breaking every commander image app-wide. Install a
global HttpOverrides at startup that gives dart:io's HttpClient (used by
NetworkImage) a descriptive User-Agent. Web-safe via conditional import
(no-op; the browser supplies its own UA). Verified: curl shows the Dart
agent -> 400 and a custom agent -> 200.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…est-tereshkova-b73eb3
CommanderSearchBar now searches automatically once the query reaches 3 characters, debounced 350ms after the last keystroke so we don't fire a request per character (and trip Scryfall rate limits). The search button and the keyboard's search action still trigger an immediate query. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The trigger was a bug: on the customize-player page the soft keyboard appeared upside-down for players 3 & 4. Root cause — the whole page was wrapped in
RotatedBox(quarterTurns: 2), but the OS keyboard can't be rotated. Rather than patch around an impossible constraint, we redesigned the screen around its real job: accurately capturing each player's commander setup so in-game commander-damage and color-identity tracking are trustworthy.Design + plans live in
docs/superpowers/.What changed
Keyboard / orientation
Accurate tracking (the north star)
Player.background— a non-attacking second card (Background enchantment): contributes to color identity but never a commander-damage clock. Kept strictly separate fromPlayer.partner(an attacking second commander = its own 21-damage clock).commanderPairingFor(Commander)auto-detects pairing from Scryfall keywords/oracle text →none | partner | background. NewCommander.keywordsfield (mapped from Scryfall) powers it.Reuse (regular-group friendly)
shared_preferences+CommanderLibraryRepository(device-local): recents (cap 20, dedup byoracleId) and favorites (star toggle). Interface is extensible to per-friend Firebase lists for the planned friends auto-sync.Two-pane UI
Testing
flutter analyze: no new issues (pre-existingapp_ui/galleryerrors untouched).player_repository17/17 — incl. pairing detection, model round-trips/backward-compat, recents/favorites storage, bloc behavior, and the background-vs-partner clock regression.[]/null.Follow-ups (non-blocking, noted in final review)
🤖 Generated with Claude Code