import React, { useCallback, useEffect, useRef, useState } from 'react'; import { ActivityIndicator, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import Constants from 'expo-constants'; import { MapView, Camera, MarkerView, UserLocation, } from '@maplibre/maplibre-react-native'; import { useNavigation } from '@react-navigation/native'; import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useTheme } from '@/theme/ThemeContext'; import { ps } from '@/api/client'; import { useLocation, getLastKnownSavedLocation, type Coords } from '@/features/location/useLocation'; import type { RootStackParamList } from '@/navigation/RootNavigator'; import type { Zone } from 'parksmarter-client'; const MAP_STYLE_LIGHT = (Constants.expoConfig?.extra?.mapStyleUrl as string) ?? 'https://tiles.openfreemap.org/styles/liberty'; const MAP_STYLE_DARK = (Constants.expoConfig?.extra?.mapStyleUrlDark as string) ?? 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json'; // Fallback view when we have no GPS and no cached location (continental US). const DEFAULT_CENTER: Coords = { latitude: 39.5, longitude: -98.35 }; const DEFAULT_ZOOM = 4; type Nav = NativeStackNavigationProp; /** Coerce the server's zone color (hex string, color name, or numeric) into a usable color. */ function normalizeColor(v: unknown): string | null { if (typeof v === 'number') return '#' + (v & 0xffffff).toString(16).padStart(6, '0'); if (typeof v === 'string') { const s = v.trim(); if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(s)) return s; if (/^\d+$/.test(s)) return '#' + (Number(s) & 0xffffff).toString(16).padStart(6, '0'); if (/^[a-z]+$/i.test(s)) return s; // named color } return null; } export function MapScreen() { const navigation = useNavigation