Repository navigation
chore: sync fork with upstream (shop egg cards stay visible during the egg stage) - #45
Merged
Merged
Conversation
…d buy button (chattymin#261) During the egg stage the shop dropped all three egg cards, which read as "the shop doesn't sell eggs" rather than "you can't buy one right now". The purchase gate itself is intended and unchanged: a shop egg always means "release the current Pokemon and reroll", so there is nothing to reroll while incubating (canBuyEgg still requires an active Pokemon). - shopEntries no longer filters eggs by hasActive; price-ascending merge order is unchanged. - EggCard shows a disabled Buy button during the egg stage with a one-line reason underneath, localized in all seven languages. The state reason takes priority over the insufficient-balance label. - The "eggs omitted when no active" test is replaced by one pinning the new contract: eggs stay visible, canBuyEgg/buyEgg stay blocked for every tier, and a blocked attempt does not touch the wallet. Co-authored-by: p <p@local> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit 56a3547)
…enough tokens" Upstream chattymin#261 keeps the three shop egg cards visible during the egg stage and disables only the buy button. The fork's phone mirror inherited the visibility but not the reason: `PhoneShopEntry.canAfford` was fed `canBuyEgg`, which folds `hasActive` into the balance check, so the phone received a bare `false` and rendered "Not enough tokens" on a wallet that covers the price. - `canAfford` now reports affordability only; a new optional `lockedReason` carries the pre-localized one-line state reason (`eggShopLockedHint`), nil when nothing blocks it. - The iOS shop card shows that reason under a dimmed CTA and gives it priority over the balance label, matching the Mac's EggCard. - `lockedReason` is optional so payloads from older Macs still decode; a non-optional field would throw and drop the whole `shop` section. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012t7yGH4SM3icrTq2eGYG2R
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.
Sync
Catches the fork up with
chattymin/PokeTokenBar@main(now at56a3547).Only one upstream commit was genuinely new — everything else in
main..upstream/mainwas already applied by the squash-merged sync in #43, which breaks ancestry and makes those commits keep reappearing as "not merged". Verified by diffing content rather than trusting the commit list: the remaining upstream-only lines are all fork divergence (the iOS companion, the Antigravity refresh-token work from #44,statusText).56a3547— feat: keep shop egg cards visible during the egg stage with a disabled buy button (upstream feat: keep shop egg cards visible during the egg stage with a disabled buy button chattymin/PokeTokenBar#261), cherry-picked cleanly.Fork follow-up
Upstream's change alters a display contract that this fork mirrors onto the phone, and the mirror does not break at compile time.
phoneShopEntriesfedPhoneShopEntry.canAffordfromcanBuyEgg, which foldshasActiveinto the balance check — so once eggs stayed in the list during the egg stage, the phone got a barefalseand drew "Not enough tokens" on a wallet that covers the price.canAffordnow reports affordability only. A new optionallockedReasoncarries the pre-localized one-line state reason (eggShopLockedHint),nilwhen nothing blocks the purchase.EggCard.lockedReasonis optional so payloads from older Macs still decode. A non-optional field would throw during element decoding and drop the entireshopsection to[].docs/reference/defect-log.mdrecords both classes: mirror payload fields must carry only what their name promises (a composite gate leaves the phone unable to pick a reason), and new phone payload fields need an optional + a legacy-decode test.Verification
./scripts/test-gate.sh— 1034 tests, 0 failures; logic-core line coverage 92.05% ≥ 75%.xcodebuild -scheme PokeTokenBariOS— BUILD SUCCEEDED (the edited SwiftUI is outsideswift build).canAfford: companion.canBuyEgg(tier)fails it on all three tiers for both the affordability and the reason assertion.🤖 Generated with Claude Code
https://claude.ai/code/session_012t7yGH4SM3icrTq2eGYG2R