Skip to content

fix(ui,walletconnect): detect iPadOS desktop-mode as mobile (#16)#91

Open
Sanka-D wants to merge 3 commits into
XRPL-Commons:developfrom
Sanka-D:fix/issue-16-mobile-detection
Open

fix(ui,walletconnect): detect iPadOS desktop-mode as mobile (#16)#91
Sanka-D wants to merge 3 commits into
XRPL-Commons:developfrom
Sanka-D:fix/issue-16-mobile-detection

Conversation

@Sanka-D

@Sanka-D Sanka-D commented Jun 29, 2026

Copy link
Copy Markdown

Problem

Relates to #16 ("wallet connect flow might not work on mobile").

isMobile() relied purely on a user-agent sniff. iPadOS 13+ defaults to a "desktop" user-agent (Macintosh), so iPads were classified as desktop and routed to the QR-code flow instead of the mobile deep-link / WalletConnect-modal flow — a concrete, reproducible way the connect flow misbehaves on a common mobile device.

This was the most defensible, device-independent sub-issue of #16 (verifiable by mocking navigator). The broader mobile flow (popup user-gesture timing, approval() timeout, deep-link handoff) still warrants on-device testing and is left for follow-up.

Fix

Pair the UA check with a touch probe: a Macintosh UA with navigator.maxTouchPoints > 1 is an iPad (desktop Safari reports 0). Applied consistently to:

  • packages/ui/src/utils.ts (isMobile) + new BROWSER_PATTERNS.MAC in constants.ts — this is the helper WalletService uses to choose the modal vs QR path.
  • packages/adapters/walletconnect/src/walletconnect-adapter.ts (its own isMobile) — gates the modalMode: 'mobile-only' default.

Both are also guarded for non-DOM (typeof navigator === 'undefined').

Tests

Adds packages/ui/tests/utils.test.ts (6 cases): iPhone, Android, desktop Mac (no touch), desktop Windows, iPad desktop-mode (Macintosh UA + touch) → mobile, and Mac UA with maxTouchPoints <= 1 → not mobile. Full build + test + lint green.

🤖 Generated with Claude Code

Sanka and others added 3 commits June 29, 2026 18:33
…mons#16)

iPadOS 13+ defaults to a "desktop" user-agent (`Macintosh`), so the user-agent
sniff in `isMobile()` classified iPads as desktop and routed them to the QR flow
instead of the mobile deep-link / WalletConnect-modal flow.

Pair the UA check with a touch probe — a `Macintosh` UA with
`navigator.maxTouchPoints > 1` is an iPad, not a Mac (desktop Safari reports 0).
Applied consistently to the UI helper (`packages/ui/src/utils.ts`, plus a new
`BROWSER_PATTERNS.MAC`) and the WalletConnect adapter's own `isMobile()`, and
guarded both for non-DOM environments. Adds `packages/ui/tests/utils.test.ts`
covering phone/tablet/desktop detection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ect/core

The iPadOS desktop-mode mobile detection was duplicated in packages/ui and
the WalletConnect adapter, so the two copies could drift. Move the single
implementation to @xrpl-connect/core, re-export it from @xrpl-connect/ui
(preserving the UI public surface), and have the WalletConnect adapter import
it from core.

- Drop the now-unused BROWSER_PATTERNS.MOBILE/.MAC from packages/ui (SAFARI kept).
- Relocate the exhaustive detection test matrix to core (incl. SSR/non-DOM),
  leaving a focused jsdom smoke test of the re-export in ui.
- Require @xrpl-connect/core ^0.8.3 from ui's peerDependencies, since the
  re-exported isMobile is new in that release; the previous ^0.8.0 range would
  let a partial upgrade resolve isMobile to undefined at runtime.

@RomThpt RomThpt 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.

lgtm

@RomThpt

RomThpt commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Review: fix(ui,walletconnect): detect iPadOS desktop-mode as mobile (#16)

Verdict: approve_with_nits — CI green (test-and-build + docs-build)

Points positifs

  • Detection correcte : Macintosh UA + maxTouchPoints > 1 = mobile. Evite le faux positif Windows touch laptop.
  • 7 tests device.test.ts couvrent iPhone, Android, desktop Mac/Windows, iPad desktop-mode, maxTouchPoints<=1 boundary, SSR.
  • jsdom smoke test ui re-export dans utils.test.ts.

Nits

  • peerDependency ^0.8.3 inexistant (ui/package.json:50) : core est encore 0.8.2 -> warnings pnpm install unmet-peer.
  • BROWSER_PATTERNS.MOBILE supprime (constants.ts:101) : breaking change public API non documente dans CHANGELOG.
  • CHANGELOG entry manquante : CONTRIBUTING.md requiert une entry Unreleased pour les changements user-visible.

Tests

Manquent : modalMode==='mobile-only' routing dans WalletService et WalletConnect adapter tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants