Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 42 additions & 15 deletions repositories/d-sports-engage-native.mdx
Original file line number Diff line number Diff line change
@@ -1,50 +1,72 @@
---
title: "d-sports-engage-native"
description: "Native iOS and Android app for D-Sports Engage. Expo 54, React Native, Clerk, RevenueCat, Thirdweb."
description: "Native iOS and Android app for D-Sports Engage. Expo 55, React Native 0.83, Clerk, RevenueCat, Thirdweb."
icon: "smartphone"
---

## Overview

**d-sports-engage-native** (package name: `engage-native`) is the native mobile app for D-Sports. It mirrors the core PWA experience on iOS and Android: wallet, shop, leaderboard, locker room, and profile.
**d-sports-engage-native** (package name: `engage-native`, version 1.18.1) is the native mobile app for D-Sports. It mirrors the core PWA experience on iOS and Android: wallet, shop, leaderboard, locker room, and profile.

- **Run:** `bunx expo start` or `bun run start` — then press `a` for Android or `i` for iOS, or scan the QR code with Expo Go.

## Tech stack

| Category | Technology |
| ---------- | ------------------------- |
| Framework | Expo 54, React Native 0.81, React 19 |
| Framework | Expo 55, React Native 0.83, React 19 |
| Auth | Clerk (Expo) |
| Payments | RevenueCat (react-native-purchases) |
| Web3 | Thirdweb |
| State | Zustand |
| Storage | MMKV |
| State | Zustand 5 |
| Storage | MMKV 4 |
| Animations | Reanimated 4 |
| UI | Lucide React Native |
| Navigation | Expo Router |
| Push | OneSignal |
| Monitoring | Sentry |
| Package | Bun |

## Features

- **Wallet** — Tokens, holdings, pack opening, crypto checkout (via PWA backend)
- **Shop** — Collectibles, cart, coin bundles, checkout
- **Leaderboard** — Rankings and filters
- **Locker room** — Social feed and engagement
- **Profile** — User profile and settings
- **Locker room** — Social feed, daily pick 'em, spin wheel, guess-the-player games
- **Profile** — User profile, achievements, milestone avatars, and settings
- **Widgets** — iOS widgets and Live Activities, Android home-screen widgets
- **Theme** — Dark/light mode (default dark)

## What changed since last docs sync

- Team-aware experiences were expanded to align with backend team/favorites behavior.
- Quest and rewards surfaces were updated to support per-team progression and pass-aware eligibility.
- Pack opening and odds disclosure UX were upgraded with safer interactions and clearer status/error handling.
- Settings and account flows were expanded, including in-app account deletion and richer support/data controls.
- **Expo 55 upgrade** — Expo SDK bumped from 54 to 55, React Native from 0.81 to 0.83.4, Expo Router to ~55.0.12.
- **iOS native tab bar** — iOS now uses `NativeTabs` (`expo-router/unstable-native-tabs`) with Liquid Glass dark material and gold accent. Android and web continue using the custom `PillTabBar` overlay.
- **Widgets and Live Activities** — iOS widgets (`RankOrPointsWidget`, `LiveStatusActivity`) and Android widgets added via `expo-widgets` and `react-native-android-widget`.
- **OneSignal push notifications** — OneSignal Expo plugin configured for production with app group support.
- **Sentry error tracking** — `@sentry/react-native` integrated with EAS builds.
- **EAS CI workflow** — GitHub Actions workflow for `eas update` on push.
- **Kotlin 2.1.20** — Android build properties updated for Expo 55 compatibility.

## Environment variables

The app uses `EXPO_PUBLIC_*` keys accessible at runtime. You need the following in your `.env`:

| Variable | Purpose |
| -------- | ------- |
| `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY` | Clerk authentication |
| `EXPO_PUBLIC_API_URL` | Backend API base URL (e.g. `https://api.d-sports.org`) |
| `EXPO_PUBLIC_TW_CLIENT_ID` | Thirdweb client ID for Web3 |
| `EXPO_PUBLIC_REVENUECAT_API_KEY` | RevenueCat API key |
| `EXPO_PUBLIC_REVENUECAT_APPSTORE_ID` | RevenueCat App Store ID |
| `EXPO_PUBLIC_REVENUECAT_ENTITLEMENT` | RevenueCat entitlement identifier |
| `EXPO_PUBLIC_SUPABASE_URL` | Supabase project URL |
| `EXPO_PUBLIC_SUPABASE_KEY` | Supabase publishable key |

## Backend integration surfaces

- Primary API source: `d-sports-api` under `/api/*`.
- Native app consumes team, league, quest, reward, wallet, commerce, and social endpoints.
- Retry/caching logic and auth token injection are centralized in app API client modules.
- Retry/caching logic and auth token injection are centralized in `lib/api/client.ts` with MMKV cache fallback.

## Quest and pass UX integration

Expand All @@ -65,9 +87,14 @@ icon: "smartphone"
## Getting started

1. Clone the repository and run `bun install`.
2. Configure environment (Clerk, RevenueCat, Thirdweb, API base URL) per repo README.
3. Run `bunx expo start`.
4. For development builds: `bun run build:dev` (EAS) or run with Expo dev client.
2. Copy `.env.example` to `.env` and fill in the required keys (see [environment variables](#environment-variables) above).
3. Run `bunx expo start` — press `a` for Android, `i` for iOS, or scan the QR code.
4. For native development builds: `bun run build:dev` (EAS) or run locally with `expo run:ios` / `expo run:android`.
5. For OTA updates: `bun run update` (production) or `bun run update:preview` (preview channel).

<Note>
iOS builds require `expo prebuild --platform ios` to generate the native project. See the repo README for Sentry and Xcode sandboxing notes.
</Note>

The app targets both native and web (responsive) and uses the same backend (d-sports-api) as the PWA for API and checkout flows.

Expand Down
37 changes: 27 additions & 10 deletions repositories/d-sports-engage-native/architecture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,41 @@ description: "Architecture overview for d-sports-engage-native application layer

The native app is structured around Expo Router screens, feature-oriented components, shared hooks, and API modules.

- Routing: `app/*` with grouped routes for tabs/auth/onboarding/settings.
- Feature logic: extracted hooks for wallet, shop, locker room, and settings.
- Shared contexts: user, collectibles, accessibility, and UI visibility/state controls.
- **Routing:** `app/*` with grouped routes for `(tabs)`, `(auth)`, `(onboarding)`, and `settings/`.
- **Feature logic:** extracted hooks for wallet (`use-wallet-screen.ts`), shop (`use-shop-screen.ts`), feed (`use-feed-section.ts`), and settings.
- **Shared contexts:** user, collectibles, accessibility, navbar visibility, and create-action controls.
- **Screen pattern:** screen files contain only JSX — all state, effects, and handlers live in dedicated hooks.

## Tab bar architecture

The tab bar uses platform-specific implementations:

- **iOS:** `app/(tabs)/_layout.ios.tsx` uses `NativeTabs` from `expo-router/unstable-native-tabs` with system Liquid Glass dark material and gold selection accent (`#FFD700`).
- **Android and web:** `app/(tabs)/_layout.tsx` uses Expo Router `Tabs` with a hidden default bar and a custom `PillTabBar` overlay using `expo-blur`.
- **Shared config:** `components/navigation/tab-config.ts` defines tab order, SF Symbol pairs (iOS), and active-tab pathname rules.

## State and context boundaries

- Local/ephemeral UI state lives near feature hooks and components.
- Cross-screen state is managed with context providers and persisted storage where required.
- User/session-sensitive state is coordinated with backend auth and profile sync endpoints.
- Cross-screen state is managed with context providers (user, collectibles, navbar visibility) and Zustand with MMKV persistence.
- User/session-sensitive state is coordinated with backend auth and profile sync endpoints via Clerk.

## API client and retry behavior

- All network calls route through `lib/api/*` modules.
- Client wrappers handle auth token propagation, error normalization, and retry strategy.
- All network calls route through `lib/api/*` modules with a base HTTP client in `lib/api/client.ts`.
- Client wrappers handle auth token propagation (Clerk), error normalization, and retry strategy.
- `lib/api/cache.ts` provides MMKV-backed cache-first fetching for offline resilience.
- Quest/reward/team flows should consume backend eligibility as source of truth.

## Platform-specific behavior

- iOS/Android platform differences are handled in native-specific components and runtime checks.
- Web-target support exists but mobile behavior is primary for interaction and performance design.
- Haptics, modal controls, and animation handling are implemented with platform-safe fallbacks.
- **iOS:** native tab bar, Apple Sign In, widgets (home screen + Live Activities), haptics via `expo-haptics`.
- **Android:** custom pill tab bar with blur, Android widgets via `react-native-android-widget`, adaptive icons.
- **Web:** responsive layout with `maxWidth: 480px` container, hover states via `WebHoverWrapper`, PWA manifest (`display: standalone`).
- Haptics, modal controls, and animation handling are implemented with platform-safe fallbacks using Reanimated 4.

## Widgets and Live Activities

- **iOS widgets:** `RankOrPointsWidget` (small/medium) and `LiveStatusActivity` (rectangular/inline) configured via `expo-widgets`.
- **Android widgets:** `RankOrPointsWidget` via `react-native-android-widget` with 30-minute update interval.
- Widget data is sourced from `lib/widget-data.ts`.
14 changes: 14 additions & 0 deletions repositories/d-sports-engage-native/feature-mapping.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ description: "Native feature coverage and parity mapping against backend/PWA beh

- Wallet screens consume balances, token data, and secure key/pin flows from backend APIs.
- Pack browsing, purchase, and open flows use backend-driven states and inventory refresh behavior.
- Crypto checkout supports Arbitrum (default), Ethereum, and Polygon via Thirdweb SDK.
- Odds-disclosure surfaces read backend-provided probability payloads.

## Quest, rewards, and pass surfaces
Expand All @@ -24,3 +25,16 @@ description: "Native feature coverage and parity mapping against backend/PWA beh
- Teams and leagues metadata are consumed from backend `/api/teams` and `/api/leagues`.
- Leaderboard displays and team-scoped ranking views align with backend leaderboard contracts.
- Favorite-team interactions influence quest and leaderboard context where backend eligibility requires it.

## Locker room games

- **Daily pick 'em** — daily prediction game with team-scoped picks via `lib/api/games-api.ts`.
- **Spin wheel** — daily spin wheel game with reward distribution.
- **Guess the player** — player identification game with image-based clues.
- Games are surfaced in a featured carousel on the locker room screen.

## Widgets and Live Activities

- **iOS home-screen widgets** display rank or wallet points (small and medium sizes).
- **iOS Live Activities** show live score/status updates on the lock screen and Dynamic Island.
- **Android home-screen widgets** display rank or wallet points with 30-minute auto-refresh.