diff --git a/app/app.json b/app/app.json index 3660e48..cc059ed 100644 --- a/app/app.json +++ b/app/app.json @@ -44,6 +44,7 @@ "extra": { "psEnvironment": "prodv2", "mapStyleUrl": "https://tiles.openfreemap.org/styles/liberty", + "mapStyleUrlDark": "https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json", "unifiedPushDefaultDistributor": "io.heckel.ntfy", "debugHttp": true } diff --git a/app/src/screens/MapScreen.tsx b/app/src/screens/MapScreen.tsx index 0603f95..84014d1 100644 --- a/app/src/screens/MapScreen.tsx +++ b/app/src/screens/MapScreen.tsx @@ -10,14 +10,18 @@ import { 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 = +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 }; @@ -25,9 +29,23 @@ 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