React Native + Expo, TypeScript, expo-router. 17 custom hooks, 3 tab screens, context-driven walk sessions.
Three main tabs plus modal screens for walk mode and quest detail.
Quest deck, compass ring, location prompt. Entry point for starting a walk or browsing quests.
Active walk mode: compass navigation, snap camera, quest progress bar, map with POI pins.
Walk history, snap gallery, and sub-tabs: QUESTS (quest log), BADGES (earned badges), PROFILE (taste notes + stats).
17 hooks in hooks/. Each encapsulates one concern.
| Hook | Purpose |
|---|---|
useLocation | GPS tracking with foreground/background permissions and distance accumulation |
useSnap | Camera capture flow + AI validation for wander/collect quests. Compresses, uploads, and validates against quest detection themes. |
useQuest | Quest lifecycle: accept, track progress, complete, abandon. Manages active quest state. |
useQuestLog | Fetch and display completed/abandoned quest history for the LOG tab |
useQuestProximity | 80m auto-check for visit quest locations via GPS proximity |
usePOIs | Fetch and filter 372 curated POIs for map pins and quest targets |
useProximityAlert | Haptic + visual alert when user walks near a POI or quest location |
useWalkTracker | Walk session state: start/end, distance, duration, route polyline recording |
useMapCamera | Map camera position, zoom, and follow-user behaviour |
useWeather | Current weather for quest generation context and weather-aware nudges |
useDiary | Walk diary data fetching for the LOG tab |
useBadges | Badge state: earned badges, progress toward next badge, celebration triggers |
useBloomData | Seasonal bloom data for Barcelona trees and flowers. Fetches bloom spots and provides local bloom images by species. |
usePublicMap | Public discovery map: fetch public snaps, publish/unpublish, bookmark |
useUploadQueue | Offline-resilient photo upload queue with retry logic |
useWatchSync | Apple Watch connectivity: sync compass bearing, walk state, and haptic triggers |
useNotifications | Push notification registration, permission handling, and token management |
Shared walk session state across all screens. Provides: active walk ID, quest data, snap count, distance, duration, compass bearing, and walk status (idle / walking / paused). Used by walk screen, quest bar, and diary.
| File | Purpose |
|---|---|
utils/compress.ts | Photo compression before upload (reduces file size for mobile upload) |
utils/geo.ts | Haversine distance, bearing calculation, coordinate helpers |
utils/time.ts | Time-of-day detection, duration formatting, date helpers |
utils/deviceId.ts | Persistent device UUID (AsyncStorage) used as user_id |
| File | Purpose |
|---|---|
config/theme.ts | Palette tokens (charcoal, coral, sage, mustard, cream), typography, shadow definitions. Single source of truth for all colours. |
config/api.ts | API base URL and endpoint path constants |
config/mapStyle.json | Custom Google Maps style (muted palette matching the app theme) |
Files in api/ wrap fetch calls to the backend. Each file corresponds to a domain (quests, photos, taste, etc.) and handles request building, error handling, and response parsing.