Upgrade @maplibre/maplibre-react-native from 10 to 11
v11 is a breaking API rework (renamed components, restructured props, event payloads on nativeEvent) and requires React Native's new architecture. Doing it as a manual migration instead of taking dependabot's #268 because the renames need code changes. Changes in apps/mobile: - RouteMap.tsx — switch to named imports; rename MapView→Map, ShapeSource→GeoJSONSource (with shape→data), LineLayer→Layer (with type="line" and paint instead of style), MarkerView→ ViewAnnotation (with coordinate→lngLat); Camera uses initialViewState with bounds as [w,s,e,n] and a separate padding object; onLongPress reads lngLat from event.nativeEvent. - app.config.ts — set `newArchEnabled: true`. MapLibre RN v11 supports only the new architecture, so Fabric/TurboModules must be on for the Expo prebuild. Cast the config type since Expo SDK 55's ExpoConfig typings don't yet include the field (the runtime does). - package.json — `^10.4.2` → `^11.0.0`. Supersedes dependabot #268; it'll auto-close once this merges. Runtime verification requires an EAS dev build (native deps changed + new arch flipped). JS-only surface typechecks + lints + unit tests clean locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c3d9514f4d
commit
7e302b1fbe
4 changed files with 104 additions and 53 deletions
|
|
@ -1,11 +1,16 @@
|
|||
import { ExpoConfig, ConfigContext } from "expo/config";
|
||||
|
||||
export default ({ config }: ConfigContext): ExpoConfig => ({
|
||||
// `newArchEnabled` isn't in the Expo SDK 55 typings yet but is an
|
||||
// accepted runtime flag. MapLibre RN v11 requires the new architecture.
|
||||
type ExpoConfigWithNewArch = ExpoConfig & { newArchEnabled?: boolean };
|
||||
|
||||
export default ({ config }: ConfigContext): ExpoConfigWithNewArch => ({
|
||||
...config,
|
||||
name: "trails.cool",
|
||||
slug: "mobile",
|
||||
version: "0.0.1",
|
||||
scheme: "trailscool",
|
||||
newArchEnabled: true,
|
||||
orientation: "portrait",
|
||||
icon: "./assets/icon.png",
|
||||
userInterfaceStyle: "light",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import { useRef, useCallback } from "react";
|
||||
import { StyleSheet, View, Text } from "react-native";
|
||||
import MapLibreGL from "@maplibre/maplibre-react-native";
|
||||
import {
|
||||
Camera,
|
||||
GeoJSONSource,
|
||||
Layer,
|
||||
Map,
|
||||
ViewAnnotation,
|
||||
type CameraRef,
|
||||
} from "@maplibre/maplibre-react-native";
|
||||
import type { Waypoint } from "@trails-cool/types";
|
||||
import type { RouteSegment } from "./use-route-editor";
|
||||
|
||||
|
|
@ -40,7 +47,10 @@ export function RouteMap({
|
|||
onWaypointDragEnd: _onWaypointDragEnd,
|
||||
onWaypointPress,
|
||||
}: RouteMapProps) {
|
||||
if (!MapLibreGL) {
|
||||
// `Map` is undefined when the native module isn't linked (e.g. running
|
||||
// in Expo Go). Same safety net as before the v11 upgrade, just against
|
||||
// a named import instead of the removed default export.
|
||||
if (!Map) {
|
||||
return (
|
||||
<View style={styles.fallback}>
|
||||
<Text style={styles.fallbackText}>Map</Text>
|
||||
|
|
@ -64,15 +74,16 @@ function RouteMapInner({
|
|||
onWaypointDragEnd: _onWaypointDragEnd,
|
||||
onWaypointPress,
|
||||
}: RouteMapProps) {
|
||||
const ML = MapLibreGL!;
|
||||
const cameraRef = useRef<MapLibreGL.CameraRef>(null);
|
||||
const cameraRef = useRef<CameraRef>(null);
|
||||
|
||||
const handleLongPress = useCallback(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(event: any) => {
|
||||
const coords = event?.geometry?.coordinates;
|
||||
if (Array.isArray(coords) && coords.length >= 2) {
|
||||
onLongPress(coords[1] as number, coords[0] as number);
|
||||
// v11 event shape: payload lives on `event.nativeEvent.lngLat`
|
||||
// (the old `event.geometry.coordinates` is gone).
|
||||
const lngLat = event?.nativeEvent?.lngLat;
|
||||
if (Array.isArray(lngLat) && lngLat.length >= 2) {
|
||||
onLongPress(lngLat[1] as number, lngLat[0] as number);
|
||||
}
|
||||
},
|
||||
[onLongPress],
|
||||
|
|
@ -96,64 +107,59 @@ function RouteMapInner({
|
|||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ML.MapView
|
||||
<Map
|
||||
style={styles.map}
|
||||
mapStyle={OSM_STYLE}
|
||||
onLongPress={handleLongPress}
|
||||
attributionEnabled={false}
|
||||
logoEnabled={false}
|
||||
attribution={false}
|
||||
logo={false}
|
||||
>
|
||||
{bounds && (
|
||||
<ML.Camera
|
||||
<Camera
|
||||
ref={cameraRef}
|
||||
defaultSettings={{
|
||||
bounds: {
|
||||
ne: bounds.ne,
|
||||
sw: bounds.sw,
|
||||
paddingTop: 40,
|
||||
paddingBottom: 40,
|
||||
paddingLeft: 40,
|
||||
paddingRight: 40,
|
||||
},
|
||||
initialViewState={{
|
||||
bounds: [bounds.sw[0], bounds.sw[1], bounds.ne[0], bounds.ne[1]],
|
||||
padding: { top: 40, right: 40, bottom: 40, left: 40 },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!bounds && (
|
||||
<ML.Camera
|
||||
defaultSettings={{
|
||||
centerCoordinate: [10.0, 50.1],
|
||||
zoomLevel: 6,
|
||||
<Camera
|
||||
initialViewState={{
|
||||
center: [10.0, 50.1],
|
||||
zoom: 6,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Route line */}
|
||||
<ML.ShapeSource id="route" shape={routeGeojson}>
|
||||
<ML.LineLayer
|
||||
<GeoJSONSource id="route" data={routeGeojson}>
|
||||
<Layer
|
||||
id="route-line"
|
||||
style={{
|
||||
lineColor: "#2563eb",
|
||||
lineWidth: 4,
|
||||
lineOpacity: computing ? 0.4 : 1,
|
||||
type="line"
|
||||
paint={{
|
||||
"line-color": "#2563eb",
|
||||
"line-width": 4,
|
||||
"line-opacity": computing ? 0.4 : 1,
|
||||
}}
|
||||
/>
|
||||
</ML.ShapeSource>
|
||||
</GeoJSONSource>
|
||||
|
||||
{/* Waypoint markers */}
|
||||
{waypoints.map((wp, i) => (
|
||||
<ML.MarkerView
|
||||
<ViewAnnotation
|
||||
key={`wp-${i}`}
|
||||
coordinate={[wp.lon, wp.lat]}
|
||||
lngLat={[wp.lon, wp.lat]}
|
||||
>
|
||||
<WaypointMarker
|
||||
index={i}
|
||||
isDayBreak={wp.isDayBreak}
|
||||
onPress={() => onWaypointPress(i)}
|
||||
/>
|
||||
</ML.MarkerView>
|
||||
</ViewAnnotation>
|
||||
))}
|
||||
</ML.MapView>
|
||||
</Map>
|
||||
|
||||
{computing && (
|
||||
<View style={styles.computingBanner}>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"dependencies": {
|
||||
"@expo/metro-runtime": "^55.0.9",
|
||||
"@gorhom/bottom-sheet": "^5.2.9",
|
||||
"@maplibre/maplibre-react-native": "^10.4.2",
|
||||
"@maplibre/maplibre-react-native": "^11.0.0",
|
||||
"@sentry/cli": "^3.3.5",
|
||||
"@sentry/react-native": "~7.11.0",
|
||||
"@trails-cool/api": "workspace:*",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue