Skip to content

Bring the mobile client to parity with the web app - #77

Merged
aichannode merged 102 commits into
mainfrom
feat/mobile-frontend-parity
Aug 16, 2026
Merged

Bring the mobile client to parity with the web app#77
aichannode merged 102 commits into
mainfrom
feat/mobile-frontend-parity

Conversation

@mobuild4u

@mobuild4u mobuild4u commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

What this does

On main, mobile/ is a wallet shell: connect a wallet, switch an EVM network, see a list of
pets, mint one. Thirteen of the game's screens have no mobile equivalent, and the package has
one test file.

This branch brings it to parity with the web client. Every action a player can take in
frontend/ is now available on device, on both chains, against the same backend.

Screens added

area screens
Pets Gallery, LevelUp, Train, Rename, Equip, Inventory
Play Battle, Breed, Defense, Leaderboard
Social Marriage, Chat
Entry Landing

Supporting parts: ActionScreenLayout, ScreenActionBar, BattleScene, BattleStage,
BattleSplash, SpeechBubble, MarriageCard.

How it is put together

Controller hooks where there is a state machine, direct composition where there is not.
This follows the rule in CLAUDE.md, applied with the same test the frontend panels use: does
the player sit and watch intermediate states? useBattlePanel, useBreedPanel,
useMarriagePanel, useLeaderboardPanel, useChatPanel and usePetGallery are headless and
their screens hold no state of their own. LevelUp, Train, Rename and Defense compose
the shared hooks directly, because one action over one selection has nothing worth modelling.

Core Animated only. react-native-reanimated and react-native-gesture-handler are
deliberately absent, and the reason is recorded in the source rather than left implicit: they
are native modules on a bare RN 0.82 app, one needs a Babel plugin ordered last, and the
target emulator image has 16 KB pages where an unaligned native library will not load at all.
The edge-swipe drawer, the battle animations and the splash are all built on Animated and
PanResponder because of this. react-native-svg was removed for the same reason after it
turned out to be 16 MB of native dependency imported nowhere.

Chain-blind through the shared adapter. Screens talk to @shared/core hooks, which talk to
ChainAdapter. Nothing under mobile/src/screens tests for a chain except where the flow
genuinely differs (the EVM entropy settle lifecycle).

Changes outside mobile/

Five commits touch shared/, and shared/ is consumed by frontend/ as well, so these
change web behaviour too. They are bugs mobile surfaced, not mobile features:

commit fix
22decfd0 read entropy and settle events from the request block, not the head
d120e826 keep pet ids aligned with pet reads (multicall allowFailure misalignment)
c9439999 treat a published battle as settled
c3ff4ac9 stop racing the settle keeper
6a657213 expose signInError on AuthContext, so a failed sign-in is reportable

The last one is additive: a new context field plus a mobile consumer
(SignInErrorReporter). Nothing existing reads it, so the frontend is unaffected by that one.
The other four change behaviour the web app shares, and each landed with tests in
shared/tests/ (useEvmEntropySettleFlow, useIncomingProposals, useMarriage,
usePetsContract are new files).

No changes at all to frontend/, backend/, contracts/, services/, proto/, protocol/
or verifier/. No golden vector was touched and no combat port was edited, so the parity
rules in AGENTS.md are not in play.

Testing

package before after
mobile 1 file (App.test.tsx) 39 suites + 1 shared harness, 513 tests
@shared/core 81 files 83 files, 608 tests

pnpm lint passes with --max-warnings 0.

Two conventions the suites follow, both of which caught real regressions during the work:

  • Every test is proved by breaking the code it covers. Several tests were deleted or
    rewritten after they passed against a deliberate defect. One example: a stat tile reading
    attack where it should read defense passed 75 tests, because the fixture happened to give
    both stats the same value.
  • Controls are found by label or testID, never by index. grep -rE 'findAllByType\(TouchableOpacity\)\[[0-9]' mobile/__tests__ returns nothing. The worst case
    found was networkGate.test.tsx, where which button [1] meant depended on whether the
    target chain was already approved, so two tests pressing [1] were pressing different
    controls and both passed.
Screenshot 2026-08-16 153027 Screenshot 2026-08-16 153052

@mobuild4u
mobuild4u requested a review from aichannode August 16, 2026 19:59
@mobuild4u mobuild4u self-assigned this Aug 16, 2026
@github-actions

Copy link
Copy Markdown

🧪 Coverage

Package Statements Branches Functions Lines Overall
backend 83.60% (2677/3202) 77.44% (1380/1782) 82.38% (505/613) 83.96% (2540/3025) 82.37% (7102/8622)
frontend 70.17% (1654/2357) 71.37% (1441/2019) 69.10% (434/628) 71.01% (1509/2125) 70.67% (5038/7129)
shared 61.03% (1801/2951) 62.35% (1168/1873) 61.12% (382/625) 62.16% (1622/2609) 61.72% (4973/8058)

@vercel

vercel Bot commented Aug 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
do-not-stop-frontend Ready Ready Preview Aug 16, 2026 9:39pm
do-not-stop-website Ready Ready Preview Aug 16, 2026 9:39pm

@aichannode aichannode left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! Thank you 👍

@aichannode
aichannode merged commit 5cb415a into main Aug 16, 2026
9 checks passed
@aichannode
aichannode deleted the feat/mobile-frontend-parity branch August 16, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants