@jacques_gordon/expo-mapbox-navigation 2.1.2 → 2.1.3

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.
@@ -4,19 +4,25 @@ import android.annotation.SuppressLint
4
4
  import android.content.Context
5
5
  import android.content.res.Resources
6
6
  import android.graphics.Color
7
+ import android.graphics.drawable.GradientDrawable
7
8
  import android.util.Log
8
9
  import android.view.Gravity
9
10
  import android.view.View
10
11
  import android.widget.FrameLayout
12
+ import android.widget.ImageView
11
13
  import android.widget.LinearLayout
12
14
  import android.widget.TextView
13
15
  import com.mapbox.api.directions.v5.models.RouteOptions
14
16
  import com.mapbox.common.location.Location
15
17
  import com.mapbox.geojson.Point
16
18
  import com.mapbox.maps.EdgeInsets
19
+ import com.mapbox.maps.ImageHolder
17
20
  import com.mapbox.maps.MapView
21
+ import com.mapbox.maps.plugin.LocationPuck2D
18
22
  import com.mapbox.maps.plugin.animation.camera
19
23
  import com.mapbox.maps.plugin.locationcomponent.location
24
+ import com.mapbox.maps.plugin.locationcomponent.OnIndicatorBearingChangedListener
25
+ import com.mapbox.maps.plugin.locationcomponent.OnIndicatorPositionChangedListener
20
26
  import com.mapbox.navigation.base.TimeFormat
21
27
  import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions
22
28
  import com.mapbox.navigation.base.formatter.DistanceFormatterOptions
@@ -84,6 +90,12 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
84
90
  private var tvDistance: TextView? = null
85
91
  private var etaBar: LinearLayout? = null
86
92
 
93
+ // ── Side action buttons (mute, overview, recenter) ────────────────────────
94
+ private var btnMute: TextView? = null
95
+ private var btnOverview: TextView? = null
96
+ private var btnRecenter: TextView? = null
97
+ private var sideButtons: LinearLayout? = null
98
+
87
99
  // ── Navigation APIs ───────────────────────────────────────────────────────
88
100
  private lateinit var navigationCamera: NavigationCamera
89
101
  private lateinit var viewportDataSource: MapboxNavigationViewportDataSource
@@ -96,28 +108,34 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
96
108
  private lateinit var routeArrowView: MapboxRouteArrowView
97
109
  private val navigationLocationProvider = NavigationLocationProvider()
98
110
  private var mapboxNavigation: MapboxNavigation? = null
99
- private var isNightMode = false
100
111
 
101
- // ── FIX: Track whether first location has been received ───────────────────
102
- // Without this, camera never enters following mode on first GPS fix
112
+ // ── State ─────────────────────────────────────────────────────────────────
113
+ private var isNightMode = false
114
+ private var isMuted = false
115
+ private var isOverviewMode = false
103
116
  private var firstLocationReceived = false
104
117
 
105
- // ── Viewport padding (from official TurnByTurnExperienceActivity) ─────────
106
- private val pixelDensity = Resources.getSystem().displayMetrics.density
118
+ // ── Pixel density ─────────────────────────────────────────────────────────
119
+ private val dp = context.resources.displayMetrics.density
120
+
121
+ // ── Viewport padding (Waze-style: vehicle at ~30% from bottom) ────────────
122
+ // top=180dp → room for maneuver banner
123
+ // bottom=300dp → pushes vehicle UP toward 30% from bottom (Waze style)
124
+ // Without large bottom padding, vehicle sits at screen center
107
125
  private val followingPadding by lazy {
108
126
  EdgeInsets(
109
- 180.0 * pixelDensity, // top — room for maneuver banner
110
- 40.0 * pixelDensity,
111
- 150.0 * pixelDensity, // bottom — room for ETA bar
112
- 40.0 * pixelDensity
127
+ 180.0 * dp, // top (maneuver banner height)
128
+ 40.0 * dp, // left
129
+ 300.0 * dp, // bottom — large value pushes vehicle up like Waze
130
+ 40.0 * dp // right
113
131
  )
114
132
  }
115
133
  private val overviewPadding by lazy {
116
134
  EdgeInsets(
117
- 140.0 * pixelDensity,
118
- 40.0 * pixelDensity,
119
- 120.0 * pixelDensity,
120
- 40.0 * pixelDensity
135
+ 120.0 * dp,
136
+ 40.0 * dp,
137
+ 120.0 * dp,
138
+ 40.0 * dp
121
139
  )
122
140
  }
123
141
 
@@ -143,22 +161,20 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
143
161
  }
144
162
 
145
163
  // ─────────────────────────────────────────────────────────────────────────
146
- // Build UI
164
+ // Build Waze-style UI
147
165
  // ─────────────────────────────────────────────────────────────────────────
148
166
  private fun buildUI() {
149
- val dp = context.resources.displayMetrics.density
150
167
  val root = FrameLayout(context).apply {
151
168
  layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
152
169
  }
153
170
 
154
- // Full screen map
171
+ // Full-screen map
155
172
  root.addView(mapView, FrameLayout.LayoutParams(
156
173
  FrameLayout.LayoutParams.MATCH_PARENT,
157
174
  FrameLayout.LayoutParams.MATCH_PARENT
158
175
  ))
159
176
 
160
177
  // ── ManeuverView — top banner ──────────────────────────────────────────
161
- // extends ConstraintLayout → must cast to View for addView()
162
178
  val mv = MapboxManeuverView(context)
163
179
  root.addView(mv as View, FrameLayout.LayoutParams(
164
180
  FrameLayout.LayoutParams.MATCH_PARENT,
@@ -167,24 +183,60 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
167
183
  mv.visibility = View.INVISIBLE
168
184
  maneuverView = mv
169
185
 
170
- // ── SpeedInfoView — bottom-left ────────────────────────────────────────
171
- // Shows posted speed limit + current vehicle speed
186
+ // ── SpeedInfoView — bottom-left, above ETA bar ────────────────────────
172
187
  val siv = MapboxSpeedInfoView(context)
173
188
  root.addView(siv as View, FrameLayout.LayoutParams(
174
- FrameLayout.LayoutParams.WRAP_CONTENT,
175
- FrameLayout.LayoutParams.WRAP_CONTENT
189
+ (72 * dp).toInt(),
190
+ (72 * dp).toInt()
176
191
  ).also {
177
192
  it.gravity = Gravity.BOTTOM or Gravity.START
178
- // Position above the ETA bar (80dp) + margin
179
- it.setMargins((16 * dp).toInt(), 0, 0, (96 * dp).toInt())
193
+ it.setMargins((12 * dp).toInt(), 0, 0, (88 * dp).toInt())
180
194
  })
181
195
  siv.visibility = View.GONE
182
196
  speedInfoView = siv
183
197
 
198
+ // ── Side action buttons (right side, Waze-style) ──────────────────────
199
+ val sideCol = LinearLayout(context).apply {
200
+ orientation = LinearLayout.VERTICAL
201
+ gravity = Gravity.CENTER_HORIZONTAL
202
+ visibility = View.INVISIBLE
203
+ }
204
+ root.addView(sideCol, FrameLayout.LayoutParams(
205
+ FrameLayout.LayoutParams.WRAP_CONTENT,
206
+ FrameLayout.LayoutParams.WRAP_CONTENT
207
+ ).also {
208
+ it.gravity = Gravity.END or Gravity.BOTTOM
209
+ it.setMargins(0, 0, (12 * dp).toInt(), (96 * dp).toInt())
210
+ })
211
+ sideButtons = sideCol
212
+
213
+ // Mute button
214
+ val muteBtn = makeCircleButton("🔊")
215
+ muteBtn.setOnClickListener { toggleMute() }
216
+ sideCol.addView(muteBtn, circleButtonParams())
217
+ btnMute = muteBtn
218
+
219
+ sideCol.addView(View(context), LinearLayout.LayoutParams(1, (10 * dp).toInt()))
220
+
221
+ // Overview button
222
+ val overviewBtn = makeCircleButton("⊕")
223
+ overviewBtn.setOnClickListener { toggleOverview() }
224
+ sideCol.addView(overviewBtn, circleButtonParams())
225
+ btnOverview = overviewBtn
226
+
227
+ sideCol.addView(View(context), LinearLayout.LayoutParams(1, (10 * dp).toInt()))
228
+
229
+ // Recenter button (shown only in overview mode)
230
+ val recenterBtn = makeCircleButton("◎")
231
+ recenterBtn.setOnClickListener { recenterCamera() }
232
+ recenterBtn.visibility = View.GONE
233
+ sideCol.addView(recenterBtn, circleButtonParams())
234
+ btnRecenter = recenterBtn
235
+
184
236
  // ── ETA bottom bar ─────────────────────────────────────────────────────
185
237
  val bar = LinearLayout(context).apply {
186
238
  orientation = LinearLayout.HORIZONTAL
187
- setBackgroundColor(Color.parseColor("#1E2433")) // dark nav style
239
+ setBackgroundColor(Color.parseColor("#1E2433"))
188
240
  elevation = 8 * dp
189
241
  visibility = View.INVISIBLE
190
242
  gravity = Gravity.CENTER_VERTICAL
@@ -204,9 +256,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
204
256
  setTextColor(Color.WHITE)
205
257
  typeface = android.graphics.Typeface.DEFAULT_BOLD
206
258
  }
207
- bar.addView(etaTime, LinearLayout.LayoutParams(
208
- 0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f
209
- ))
259
+ bar.addView(etaTime, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f))
210
260
  tvEtaTime = etaTime
211
261
 
212
262
  // Duration + distance (center)
@@ -227,9 +277,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
227
277
  }
228
278
  center.addView(dur)
229
279
  center.addView(dist)
230
- bar.addView(center, LinearLayout.LayoutParams(
231
- 0, LinearLayout.LayoutParams.WRAP_CONTENT, 2f
232
- ))
280
+ bar.addView(center, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 2f))
233
281
  tvDuration = dur
234
282
  tvDistance = dist
235
283
 
@@ -241,21 +289,39 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
241
289
  gravity = Gravity.END or Gravity.CENTER_VERTICAL
242
290
  setOnClickListener { cancelNavigation() }
243
291
  }
244
- bar.addView(cancelBtn, LinearLayout.LayoutParams(
245
- 0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f
246
- ))
292
+ bar.addView(cancelBtn, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f))
247
293
  etaBar = bar
248
294
 
249
- // ── TripProgressView — hidden native view (used for render() API) ──────
250
- // FIX: was created but never added to root — now added but invisible
295
+ // TripProgressView — 1×1 hidden (required for render() API)
251
296
  val tpv = MapboxTripProgressView(context)
252
- root.addView(tpv as View, FrameLayout.LayoutParams(1, 1)) // 1x1 hidden
297
+ root.addView(tpv as View, FrameLayout.LayoutParams(1, 1))
253
298
  tpv.visibility = View.GONE
254
299
  tripProgressView = tpv
255
300
 
256
301
  addView(root)
257
302
  }
258
303
 
304
+ // Helper: creates a white circle button (Waze style)
305
+ private fun makeCircleButton(text: String): TextView {
306
+ return TextView(context).apply {
307
+ this.text = text
308
+ textSize = 20f
309
+ gravity = Gravity.CENTER
310
+ setTextColor(Color.BLACK)
311
+ background = GradientDrawable().apply {
312
+ shape = GradientDrawable.OVAL
313
+ setColor(Color.WHITE)
314
+ // Drop shadow via elevation
315
+ }
316
+ elevation = 6 * dp
317
+ }
318
+ }
319
+
320
+ private fun circleButtonParams(): LinearLayout.LayoutParams {
321
+ val size = (52 * dp).toInt()
322
+ return LinearLayout.LayoutParams(size, size)
323
+ }
324
+
259
325
  // ─────────────────────────────────────────────────────────────────────────
260
326
  // Init APIs
261
327
  // ─────────────────────────────────────────────────────────────────────────
@@ -297,11 +363,8 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
297
363
  mapView.mapboxMap.loadStyle(mapStyle ?: getAutoStyle()) { style ->
298
364
  routeLineView.initializeLayers(style)
299
365
 
300
- // Camera viewport data source
366
+ // Camera viewport
301
367
  viewportDataSource = MapboxNavigationViewportDataSource(mapView.mapboxMap)
302
-
303
- // FIX: Set padding BEFORE creating NavigationCamera
304
- // Without this, the camera doesn't account for the maneuver banner and ETA bar
305
368
  viewportDataSource.followingPadding = followingPadding
306
369
  viewportDataSource.overviewPadding = overviewPadding
307
370
 
@@ -311,10 +374,24 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
311
374
  viewportDataSource
312
375
  )
313
376
 
314
- // Location puck
377
+ // ── Location puck — Waze-style arrow ─────────────────────────────
378
+ // FIX: use mapbox_navigation_puck_icon (built-in arrow)
379
+ // + PuckBearing.COURSE to orient it in direction of travel
315
380
  mapView.location.apply {
316
381
  setLocationProvider(navigationLocationProvider)
317
- enabled = true
382
+ updateSettings {
383
+ // Built-in navigation arrow (chevron) from Nav SDK
384
+ locationPuck = LocationPuck2D(
385
+ bearingImage = ImageHolder.from(
386
+ com.mapbox.navigation.R.drawable.mapbox_navigation_puck_icon
387
+ )
388
+ )
389
+ // COURSE = direction of movement (not compass heading)
390
+ puckBearingEnabled = true
391
+ enabled = true
392
+ }
393
+ // Must set puckBearing separately — confirmed from migration guide
394
+ puckBearing = com.mapbox.maps.plugin.PuckBearing.COURSE
318
395
  }
319
396
 
320
397
  registerObservers()
@@ -327,7 +404,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
327
404
  private fun registerObservers() {
328
405
  val nav = mapboxNavigation ?: return
329
406
 
330
- // ── Routes observer ───────────────────────────────────────────────────
407
+ // Routes observer
331
408
  nav.registerRoutesObserver(object : RoutesObserver {
332
409
  override fun onRoutesChanged(result: RoutesUpdatedResult) {
333
410
  if (result.navigationRoutes.isNotEmpty()) {
@@ -338,12 +415,9 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
338
415
  }
339
416
  viewportDataSource.onRouteChanged(result.navigationRoutes.first())
340
417
  viewportDataSource.evaluate()
341
-
342
- // FIX: transition to following mode when route is set
343
- // This triggers the camera to zoom/pitch/center correctly
418
+ isOverviewMode = false
344
419
  safeCameraFollowing()
345
420
  showUI()
346
-
347
421
  onRoutesReady(mapOf(
348
422
  "routeCount" to result.navigationRoutes.size,
349
423
  "distanceMeters" to (result.navigationRoutes.first().directionsRoute.distance() ?: 0.0),
@@ -363,13 +437,12 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
363
437
  }
364
438
  })
365
439
 
366
- // ── Route progress observer ───────────────────────────────────────────
440
+ // Route progress observer
367
441
  nav.registerRouteProgressObserver(RouteProgressObserver { routeProgress ->
368
- // Update viewport with progress (camera follows route progress)
369
442
  viewportDataSource.onRouteProgressChanged(routeProgress)
370
443
  viewportDataSource.evaluate()
371
444
 
372
- // Draw maneuver arrow
445
+ // Maneuver arrow on map
373
446
  mapView.mapboxMap.style?.let { style ->
374
447
  val arrowResult = routeArrowApi.addUpcomingManeuverArrow(routeProgress)
375
448
  routeArrowView.renderManeuverUpdate(style, arrowResult)
@@ -378,10 +451,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
378
451
  // Maneuver banner
379
452
  val maneuvers = maneuverApi.getManeuvers(routeProgress)
380
453
  maneuvers.fold(
381
- { error ->
382
- Log.w(TAG, "Maneuver error: ${error.errorMessage}")
383
- Unit
384
- },
454
+ { error -> Log.w(TAG, "Maneuver error: ${error.errorMessage}"); Unit },
385
455
  { _ ->
386
456
  maneuverView?.visibility = View.VISIBLE
387
457
  maneuverView?.renderManeuvers(maneuvers)
@@ -409,32 +479,27 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
409
479
  ))
410
480
  })
411
481
 
412
- // ── Location observer ─────────────────────────────────────────────────
482
+ // Location observer
413
483
  nav.registerLocationObserver(object : LocationObserver {
414
484
  override fun onNewRawLocation(rawLocation: Location) {}
415
-
416
485
  override fun onNewLocationMatcherResult(result: LocationMatcherResult) {
417
486
  val loc = result.enhancedLocation
418
487
 
419
- // Update location puck position
420
488
  navigationLocationProvider.changePosition(
421
489
  location = loc,
422
490
  keyPoints = result.keyPoints,
423
491
  )
424
492
 
425
- // FIX: Update viewport data source with location AND bearing
426
- // This is what drives the camera to follow the vehicle's direction
427
493
  viewportDataSource.onLocationChanged(loc)
428
494
  viewportDataSource.evaluate()
429
495
 
430
- // FIX: On first location fix, immediately enter following mode
431
- // This ensures the camera centers on the user as soon as GPS is available
496
+ // First GPS fix enter following mode
432
497
  if (!firstLocationReceived) {
433
498
  firstLocationReceived = true
434
499
  safeCameraFollowing()
435
500
  }
436
501
 
437
- // ── Speed limit display ────────────────────────────────────────
502
+ // Speed limit display
438
503
  val fmtOptions = DistanceFormatterOptions.Builder(context).build()
439
504
  val speedInfo = speedInfoApi.updatePostedAndCurrentSpeed(result, fmtOptions)
440
505
  if (speedInfo != null) {
@@ -450,11 +515,45 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
450
515
  }
451
516
 
452
517
  // ─────────────────────────────────────────────────────────────────────────
453
- // ETA bar update
454
- // Fields confirmed from TripProgressUpdateValue docs:
455
- // estimatedTimeToArrival: Long — Unix timestamp ms
456
- // totalTimeRemaining: Double seconds
457
- // distanceRemaining: Double metres
518
+ // Button actions
519
+ // ─────────────────────────────────────────────────────────────────────────
520
+
521
+ // Toggle mute voice guidance
522
+ private fun toggleMute() {
523
+ isMuted = !isMuted
524
+ btnMute?.text = if (isMuted) "🔇" else "🔊"
525
+ btnMute?.setTextColor(if (isMuted) Color.parseColor("#FF4444") else Color.BLACK)
526
+ // Actual audio muting handled by the voice instruction observer in the app
527
+ // We expose the state via event so the RN layer can mute TTS
528
+ onNavigationCancelled(mapOf("type" to "mute", "muted" to isMuted))
529
+ }
530
+
531
+ // Toggle overview / following mode
532
+ private fun toggleOverview() {
533
+ if (isOverviewMode) {
534
+ recenterCamera()
535
+ } else {
536
+ isOverviewMode = true
537
+ btnOverview?.text = "◉"
538
+ btnRecenter?.visibility = View.VISIBLE
539
+ try {
540
+ navigationCamera.requestNavigationCameraToOverview()
541
+ } catch (e: Exception) {
542
+ Log.e(TAG, "Camera overview error: ${e.message}")
543
+ }
544
+ }
545
+ }
546
+
547
+ // Recenter camera to vehicle (following mode)
548
+ private fun recenterCamera() {
549
+ isOverviewMode = false
550
+ btnOverview?.text = "⊕"
551
+ btnRecenter?.visibility = View.GONE
552
+ safeCameraFollowing()
553
+ }
554
+
555
+ // ─────────────────────────────────────────────────────────────────────────
556
+ // ETA bar
458
557
  // ─────────────────────────────────────────────────────────────────────────
459
558
  private fun updateEtaBar(
460
559
  estimatedTimeToArrivalMs: Long,
@@ -483,7 +582,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
483
582
  }
484
583
 
485
584
  // ─────────────────────────────────────────────────────────────────────────
486
- // Day / Night auto switch
585
+ // Day / Night
487
586
  // ─────────────────────────────────────────────────────────────────────────
488
587
  private fun getAutoStyle(): String {
489
588
  val hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
@@ -509,8 +608,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
509
608
  }
510
609
 
511
610
  // ─────────────────────────────────────────────────────────────────────────
512
- // Camera following — safe wrapper (issue #43)
513
- // FIX: maxDuration(0) = instant transition, no animation delay
611
+ // Camera following — issue #43 safe wrapper
514
612
  // ─────────────────────────────────────────────────────────────────────────
515
613
  private fun safeCameraFollowing() {
516
614
  try {
@@ -525,12 +623,13 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
525
623
  }
526
624
 
527
625
  // ─────────────────────────────────────────────────────────────────────────
528
- // Cancel navigation — also stops foreground service (fixes notification crash)
626
+ // Cancel navigation
529
627
  // ─────────────────────────────────────────────────────────────────────────
530
628
  private fun cancelNavigation() {
531
629
  mapboxNavigation?.setNavigationRoutes(listOf())
532
630
  mapboxNavigation?.stopTripSession()
533
631
  firstLocationReceived = false
632
+ isOverviewMode = false
534
633
  hideUI()
535
634
  onNavigationCancelled(mapOf<String, Any>())
536
635
  }
@@ -538,12 +637,14 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
538
637
  private fun showUI() {
539
638
  maneuverView?.visibility = View.VISIBLE
540
639
  etaBar?.visibility = View.VISIBLE
640
+ sideButtons?.visibility = View.VISIBLE
541
641
  }
542
642
 
543
643
  private fun hideUI() {
544
644
  maneuverView?.visibility = View.INVISIBLE
545
645
  speedInfoView?.visibility = View.GONE
546
646
  etaBar?.visibility = View.INVISIBLE
647
+ sideButtons?.visibility = View.INVISIBLE
547
648
  }
548
649
 
549
650
  // ─────────────────────────────────────────────────────────────────────────
@@ -578,8 +679,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
578
679
  .language(locale.toLanguageTag())
579
680
  .voiceUnits(resolveVoiceUnits())
580
681
  .coordinatesList(points)
581
- // maxspeed annotation required for speed limit display
582
- .annotations("maxspeed,congestion,duration")
682
+ .annotations("maxspeed,congestion,duration,speed")
583
683
 
584
684
  waypointIndices?.let { builder.waypointIndicesList(it) }
585
685
  navigationProfile?.let {
@@ -602,8 +702,6 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
602
702
  }
603
703
  nav.setNavigationRoutes(routes)
604
704
  nav.startTripSession()
605
- // Camera will follow automatically via onNewLocationMatcherResult
606
- // + onRoutesChanged observer
607
705
  }
608
706
 
609
707
  override fun onFailure(reasons: List<RouterFailure>, routeOptions: RouteOptions) {
@@ -632,7 +730,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
632
730
  fun setNavigationProfile(p: String?) { navigationProfile = p }
633
731
  fun setExcludeTypes(t: List<String>?) { excludeTypes = t }
634
732
  fun setMapStyle(s: String?) { mapStyle = s }
635
- fun setMute(m: Boolean) { mute = m }
733
+ fun setMute(m: Boolean) { mute = m; if (m != isMuted) toggleMute() }
636
734
  fun setMaxHeight(h: Double?) { maxHeight = h }
637
735
  fun setMaxWidth(w: Double?) { maxWidth = w }
638
736
  fun setUseMapMatching(u: Boolean) { useMapMatching = u }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacques_gordon/expo-mapbox-navigation",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
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",