@jacques_gordon/expo-mapbox-navigation 2.0.5 → 2.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,20 +5,17 @@ import android.util.Log
5
5
  import com.mapbox.api.directions.v5.models.RouteOptions
6
6
  import com.mapbox.geojson.Point
7
7
  import com.mapbox.maps.MapView
8
- import com.mapbox.maps.MapboxMap
9
8
  import com.mapbox.maps.Style
10
- import com.mapbox.maps.plugin.animation.camera
11
9
  import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
12
- import com.mapbox.navigation.base.formatter.UnitType
13
10
  import com.mapbox.navigation.base.options.NavigationOptions
14
11
  import com.mapbox.navigation.base.route.NavigationRoute
15
12
  import com.mapbox.navigation.base.route.NavigationRouterCallback
16
13
  import com.mapbox.navigation.base.route.RouterFailure
14
+ import com.mapbox.navigation.base.route.RouterOrigin
17
15
  import com.mapbox.navigation.core.MapboxNavigation
18
16
  import com.mapbox.navigation.core.MapboxNavigationProvider
19
17
  import com.mapbox.navigation.core.directions.session.RoutesObserver
20
18
  import com.mapbox.navigation.core.directions.session.RoutesUpdatedResult
21
- import com.mapbox.navigation.core.lifecycle.MapboxNavigationApp
22
19
  import com.mapbox.navigation.core.trip.session.RouteProgressObserver
23
20
  import com.mapbox.navigation.ui.maps.camera.NavigationCamera
24
21
  import com.mapbox.navigation.ui.maps.camera.data.MapboxNavigationViewportDataSource
@@ -36,17 +33,14 @@ private const val TAG = "ExpoMapboxNavigation"
36
33
  class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
37
34
  ExpoView(context, appContext) {
38
35
 
39
- // ── UI ───────────────────────────────────────────────────────────────────
40
36
  private val mapView: MapView = MapView(context)
41
37
  private var navigationCamera: NavigationCamera? = null
42
38
  private var viewportDataSource: MapboxNavigationViewportDataSource? = null
43
39
  private var routeLineApi: MapboxRouteLineApi? = null
44
40
  private var routeLineView: MapboxRouteLineView? = null
45
-
46
- // ── Navigation ───────────────────────────────────────────────────────────
47
41
  private var mapboxNavigation: MapboxNavigation? = null
48
42
 
49
- // ── Props ────────────────────────────────────────────────────────────────
43
+ // Props
50
44
  private var coordinates: List<Map<String, Double>> = emptyList()
51
45
  private var waypointIndices: List<Int>? = null
52
46
  private var language: String? = null
@@ -67,51 +61,27 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
67
61
  setupNavigation()
68
62
  }
69
63
 
70
- // ─────────────────────────────────────────────────────────────────────────
71
- // Setup
72
- // ─────────────────────────────────────────────────────────────────────────
73
-
74
64
  private fun setupNavigation() {
75
- val accessToken = getAccessToken() ?: run {
76
- Log.e(TAG, "Mapbox access token not found.")
77
- return
78
- }
79
-
80
- // Create MapboxNavigation instance (Nav SDK v3 API)
81
- val navigationOptions = NavigationOptions.Builder(context)
82
- .build()
83
-
65
+ val navigationOptions = NavigationOptions.Builder(context).build()
84
66
  mapboxNavigation = MapboxNavigationProvider.create(navigationOptions)
85
67
 
86
- // Setup map style + route line + camera once map is loaded
87
- mapView.getMapboxMap().loadStyle(
88
- mapStyle ?: Style.MAPBOX_STREETS
89
- ) { style ->
90
- setupRouteLineComponents(style)
91
- setupCamera()
68
+ mapView.getMapboxMap().loadStyle(mapStyle ?: Style.MAPBOX_STREETS) { style ->
69
+ routeLineApi = MapboxRouteLineApi(MapboxRouteLineApiOptions.Builder().build())
70
+ routeLineView = MapboxRouteLineView(MapboxRouteLineViewOptions.Builder(context).build())
71
+
72
+ viewportDataSource = MapboxNavigationViewportDataSource(mapView.getMapboxMap())
73
+ navigationCamera = NavigationCamera(
74
+ mapView.getMapboxMap(),
75
+ mapView.camera,
76
+ viewportDataSource!!
77
+ )
92
78
  registerObservers()
93
79
  }
94
80
  }
95
81
 
96
- private fun setupRouteLineComponents(style: Style) {
97
- routeLineApi = MapboxRouteLineApi(MapboxRouteLineApiOptions.Builder().build())
98
- routeLineView = MapboxRouteLineView(MapboxRouteLineViewOptions.Builder(context).build())
99
- }
100
-
101
- private fun setupCamera() {
102
- val mapboxMap = mapView.getMapboxMap()
103
- viewportDataSource = MapboxNavigationViewportDataSource(mapboxMap)
104
- navigationCamera = NavigationCamera(
105
- mapboxMap,
106
- mapView.camera,
107
- viewportDataSource!!
108
- )
109
- }
110
-
111
82
  private fun registerObservers() {
112
83
  val nav = mapboxNavigation ?: return
113
84
 
114
- // Routes observer — updates route line on map
115
85
  nav.registerRoutesObserver(object : RoutesObserver {
116
86
  override fun onRoutesChanged(result: RoutesUpdatedResult) {
117
87
  val routes = result.navigationRoutes
@@ -121,10 +91,8 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
121
91
  routeLineView?.renderRouteDrawData(style, value)
122
92
  }
123
93
  }
124
- // Issue #43 fix: safe camera transition to following
125
94
  safeCameraFollowing()
126
-
127
- sendEvent("onRoutesReady", mapOf(
95
+ emit("onRoutesReady", mapOf(
128
96
  "routeCount" to routes.size,
129
97
  "distanceMeters" to (routes.firstOrNull()?.directionsRoute?.distance() ?: 0.0),
130
98
  "durationSeconds" to (routes.firstOrNull()?.directionsRoute?.duration() ?: 0.0)
@@ -133,21 +101,19 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
133
101
  }
134
102
  })
135
103
 
136
- // Route progress observer
137
104
  nav.registerRouteProgressObserver(RouteProgressObserver { progress ->
138
- sendEvent("onRouteProgressChanged", mapOf(
105
+ emit("onRouteProgressChanged", mapOf(
139
106
  "distanceRemaining" to progress.distanceRemaining,
140
107
  "durationRemaining" to progress.durationRemaining,
141
108
  "distanceTraveled" to progress.distanceTraveled,
142
109
  "fractionTraveled" to progress.fractionTraveled,
143
- "currentStepDistanceRemaining" to (progress.currentLegProgress?.currentStepProgress?.distanceRemaining ?: 0f)
110
+ "currentStepDistanceRemaining" to
111
+ (progress.currentLegProgress?.currentStepProgress?.distanceRemaining ?: 0f)
144
112
  ))
145
113
  })
146
114
  }
147
115
 
148
- // ─────────────────────────────────────────────────────────────────────────
149
- // Issue #43 fix: safe camera transition
150
- // ─────────────────────────────────────────────────────────────────────────
116
+ // ── Issue #43: safe camera transition ────────────────────────────────────
151
117
  private fun safeCameraFollowing() {
152
118
  try {
153
119
  navigationCamera?.requestNavigationCameraToFollowing(
@@ -160,9 +126,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
160
126
  }
161
127
  }
162
128
 
163
- // ─────────────────────────────────────────────────────────────────────────
164
- // Issue #31 fix: voice units
165
- // ─────────────────────────────────────────────────────────────────────────
129
+ // ── Issue #31: voice units ────────────────────────────────────────────────
166
130
  private fun resolveUnitType(): String {
167
131
  return when (voiceUnits?.lowercase()) {
168
132
  "metric" -> "metric"
@@ -175,9 +139,6 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
175
139
  }
176
140
  }
177
141
 
178
- // ─────────────────────────────────────────────────────────────────────────
179
- // Route request
180
- // ─────────────────────────────────────────────────────────────────────────
181
142
  private fun fetchRoutes() {
182
143
  val nav = mapboxNavigation ?: return
183
144
  if (coordinates.size < 2) return
@@ -187,37 +148,31 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
187
148
  }
188
149
 
189
150
  val locale = language?.let { Locale.forLanguageTag(it) } ?: Locale.getDefault()
190
- val unitType = resolveUnitType()
191
151
 
192
152
  val builder = RouteOptions.builder()
193
153
  .applyDefaultNavigationOptions()
194
154
  .language(locale.toLanguageTag())
195
- .voiceUnits(unitType) // Issue #31 fix
155
+ .voiceUnits(resolveUnitType())
196
156
  .coordinatesList(points)
197
157
 
198
158
  waypointIndices?.let { builder.waypointIndicesList(it) }
199
-
200
159
  navigationProfile?.let {
201
- val profile = if (it.startsWith("mapbox/")) it else "mapbox/$it"
202
- builder.profile(profile)
203
- }
204
-
205
- excludeTypes?.takeIf { it.isNotEmpty() }?.let {
206
- builder.exclude(it.joinToString(","))
160
+ builder.profile(if (it.startsWith("mapbox/")) it else "mapbox/$it")
207
161
  }
208
-
162
+ excludeTypes?.takeIf { it.isNotEmpty() }?.let { builder.exclude(it.joinToString(",")) }
209
163
  maxHeight?.let { builder.maxHeight(it) }
210
164
  maxWidth?.let { builder.maxWidth(it) }
211
165
 
166
+ // Nav SDK v3: NavigationRouterCallback uses @RouterOrigin String (not enum)
212
167
  nav.requestRoutes(
213
168
  builder.build(),
214
169
  object : NavigationRouterCallback {
215
170
  override fun onRoutesReady(
216
171
  routes: List<NavigationRoute>,
217
- routerOrigin: com.mapbox.navigation.base.route.RouterOrigin
172
+ @RouterOrigin routerOrigin: String
218
173
  ) {
219
174
  if (routes.isEmpty()) {
220
- sendEvent("onRoutesFailed", mapOf("message" to "No routes returned"))
175
+ emit("onRoutesFailed", mapOf("message" to "No routes returned"))
221
176
  return
222
177
  }
223
178
  nav.setNavigationRoutes(routes)
@@ -230,12 +185,12 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
230
185
  ) {
231
186
  val msg = reasons.firstOrNull()?.message ?: "Unknown error"
232
187
  Log.e(TAG, "Route request failed: $msg")
233
- sendEvent("onRoutesFailed", mapOf("message" to msg))
188
+ emit("onRoutesFailed", mapOf("message" to msg))
234
189
  }
235
190
 
236
191
  override fun onCanceled(
237
192
  routeOptions: RouteOptions,
238
- routerOrigin: com.mapbox.navigation.base.route.RouterOrigin
193
+ @RouterOrigin routerOrigin: String
239
194
  ) {
240
195
  Log.d(TAG, "Route request cancelled")
241
196
  }
@@ -243,15 +198,11 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
243
198
  )
244
199
  }
245
200
 
246
- // ─────────────────────────────────────────────────────────────────────────
247
- // Prop setters
248
- // ─────────────────────────────────────────────────────────────────────────
249
-
201
+ // ── Prop setters ──────────────────────────────────────────────────────────
250
202
  fun setCoordinates(coords: List<Map<String, Double>>) {
251
203
  coordinates = coords
252
204
  if (coords.size >= 2) fetchRoutes()
253
205
  }
254
-
255
206
  fun setWaypointIndices(indices: List<Int>?) { waypointIndices = indices }
256
207
  fun setLanguage(lang: String?) { language = lang }
257
208
  fun setVoiceUnits(units: String?) { voiceUnits = units }
@@ -265,10 +216,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
265
216
  fun setCustomRasterTileUrl(url: String?) { customRasterTileUrl = url }
266
217
  fun setCustomRasterAboveLayerId(layerId: String?) { customRasterAboveLayerId = layerId }
267
218
 
268
- // ─────────────────────────────────────────────────────────────────────────
269
- // Helpers
270
- // ─────────────────────────────────────────────────────────────────────────
271
-
219
+ // ── Helpers ───────────────────────────────────────────────────────────────
272
220
  private fun getAccessToken(): String? {
273
221
  return try {
274
222
  val resId = context.resources.getIdentifier(
@@ -278,8 +226,13 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
278
226
  } catch (e: Exception) { null }
279
227
  }
280
228
 
281
- private fun sendEvent(name: String, data: Map<String, Any>) {
282
- appContext.eventEmitter?.emit(name, data)
229
+ // Correct Expo SDK v53 event emitter API
230
+ private fun emit(name: String, data: Map<String, Any>) {
231
+ try {
232
+ appContext.eventEmitter?.emit(name, data)
233
+ } catch (e: Exception) {
234
+ Log.e(TAG, "Failed to emit event $name: ${e.message}")
235
+ }
283
236
  }
284
237
 
285
238
  override fun onDetachedFromWindow() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacques_gordon/expo-mapbox-navigation",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "Expo module for Mapbox Navigation SDK with 16KB page size support, NDK27, and Mapbox Maps v11.11.0+",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",