@jacques_gordon/expo-mapbox-navigation 2.2.4 → 2.2.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,7 +5,8 @@ public class ExpoMapboxNavigationModule: Module {
5
5
  Name("ExpoMapboxNavigation")
6
6
 
7
7
  View(ExpoMapboxNavigationView.self) {
8
- // Events must exactly mirror the Android module's Events() list.
8
+
9
+ // ── Events (exact parity with Android module Events() list) ─────────────
9
10
  Events(
10
11
  "onRouteProgressChanged",
11
12
  "onRoutesReady",
@@ -16,44 +17,65 @@ public class ExpoMapboxNavigationModule: Module {
16
17
  "onManeuverBannerPressed"
17
18
  )
18
19
 
19
- Prop("coordinates") { (view: ExpoMapboxNavigationView, coordinates: [[String: Double]]) in
20
- view.setCoordinates(coordinates)
20
+ // ── Base props ────────────────────────────────────────────────────────────
21
+ Prop("coordinates") { (view: ExpoMapboxNavigationView, v: [[String: Double]]) in
22
+ view.setCoordinates(v)
23
+ }
24
+ Prop("waypointIndices") { (view: ExpoMapboxNavigationView, v: [Int]?) in
25
+ view.setWaypointIndices(v)
26
+ }
27
+ Prop("language") { (view: ExpoMapboxNavigationView, v: String?) in
28
+ view.setLanguage(v)
29
+ }
30
+ Prop("voiceUnits") { (view: ExpoMapboxNavigationView, v: String?) in
31
+ view.setVoiceUnits(v)
21
32
  }
22
- Prop("waypointIndices") { (view: ExpoMapboxNavigationView, indices: [Int]?) in
23
- view.setWaypointIndices(indices)
33
+ Prop("navigationProfile") { (view: ExpoMapboxNavigationView, v: String?) in
34
+ view.setNavigationProfile(v)
24
35
  }
25
- Prop("language") { (view: ExpoMapboxNavigationView, language: String?) in
26
- view.setLanguage(language)
36
+ Prop("excludeTypes") { (view: ExpoMapboxNavigationView, v: [String]?) in
37
+ view.setExcludeTypes(v)
27
38
  }
28
- Prop("voiceUnits") { (view: ExpoMapboxNavigationView, units: String?) in
29
- view.setVoiceUnits(units)
39
+ Prop("mapStyle") { (view: ExpoMapboxNavigationView, v: String?) in
40
+ view.setMapStyle(v)
30
41
  }
31
- Prop("navigationProfile") { (view: ExpoMapboxNavigationView, profile: String?) in
32
- view.setNavigationProfile(profile)
42
+ Prop("mute") { (view: ExpoMapboxNavigationView, v: Bool) in
43
+ view.setMute(v)
33
44
  }
34
- Prop("excludeTypes") { (view: ExpoMapboxNavigationView, types: [String]?) in
35
- view.setExcludeTypes(types)
45
+ Prop("maxHeight") { (view: ExpoMapboxNavigationView, v: Double?) in
46
+ view.setMaxHeight(v)
36
47
  }
37
- Prop("mapStyle") { (view: ExpoMapboxNavigationView, style: String?) in
38
- view.setMapStyle(style)
48
+ Prop("maxWidth") { (view: ExpoMapboxNavigationView, v: Double?) in
49
+ view.setMaxWidth(v)
39
50
  }
40
- Prop("mute") { (view: ExpoMapboxNavigationView, mute: Bool) in
41
- view.setMute(mute)
51
+ Prop("useMapMatching") { (view: ExpoMapboxNavigationView, v: Bool) in
52
+ view.setUseMapMatching(v)
53
+ }
54
+ Prop("customRasterTileUrl") { (view: ExpoMapboxNavigationView, v: String?) in
55
+ view.setCustomRasterTileUrl(v)
56
+ }
57
+ Prop("customRasterAboveLayerId") { (view: ExpoMapboxNavigationView, v: String?) in
58
+ view.setCustomRasterAboveLayerId(v)
59
+ }
60
+
61
+ // ── Color customization props (parity with Android) ───────────────────────
62
+ Prop("maneuverBackgroundColorDay") { (view: ExpoMapboxNavigationView, v: String?) in
63
+ view.setManeuverBackgroundColorDay(v)
42
64
  }
43
- Prop("maxHeight") { (view: ExpoMapboxNavigationView, height: Double?) in
44
- view.setMaxHeight(height)
65
+ Prop("maneuverTurnIconColor") { (view: ExpoMapboxNavigationView, v: String?) in
66
+ view.setManeuverTurnIconColor(v)
45
67
  }
46
- Prop("maxWidth") { (view: ExpoMapboxNavigationView, width: Double?) in
47
- view.setMaxWidth(width)
68
+ Prop("etaBarBackgroundColor") { (view: ExpoMapboxNavigationView, v: String?) in
69
+ view.setEtaBarBackgroundColor(v)
48
70
  }
49
- Prop("useMapMatching") { (view: ExpoMapboxNavigationView, use: Bool) in
50
- view.setUseMapMatching(use)
71
+ Prop("etaTextColor") { (view: ExpoMapboxNavigationView, v: String?) in
72
+ view.setEtaTextColor(v)
51
73
  }
52
- Prop("customRasterTileUrl") { (view: ExpoMapboxNavigationView, url: String?) in
53
- view.setCustomRasterTileUrl(url)
74
+ Prop("iconButtonColor") { (view: ExpoMapboxNavigationView, v: String?) in
75
+ view.setIconButtonColor(v)
54
76
  }
55
- Prop("customRasterAboveLayerId") { (view: ExpoMapboxNavigationView, layerId: String?) in
56
- view.setCustomRasterAboveLayerId(layerId)
77
+ Prop("iconButtonMutedColor") { (view: ExpoMapboxNavigationView, v: String?) in
78
+ view.setIconButtonMutedColor(v)
57
79
  }
58
80
  }
59
81
  }
@@ -1,25 +1,20 @@
1
1
  import ExpoModulesCore
2
2
  import UIKit
3
3
  import CoreLocation
4
- import MapboxDirections
4
+ // MapboxDirections types (Waypoint, NavigationRouteOptions, etc.) are
5
+ // re-exported by MapboxNavigationCore in Navigation SDK v3.
5
6
  import MapboxNavigationCore
6
7
  import MapboxNavigationUIKit
7
8
 
8
- // MARK: - Custom styles (replaces removed NavigationDayStyle/NavigationNightStyle in v3)
9
- // In Navigation SDK v3, NavigationDayStyle and NavigationNightStyle were removed.
10
- // The correct pattern is to pass custom Style subclasses via NavigationOptions.styles.
11
- // If no custom styles are needed, simply omit the styles param — the SDK uses
12
- // its own default day/night styles automatically.
13
-
14
9
  public class ExpoMapboxNavigationView: ExpoView {
15
10
 
16
- // MARK: - Event dispatchers
11
+ // MARK: - Events (mirrors Android EventDispatchers exactly)
17
12
  let onRouteProgressChanged = EventDispatcher()
18
- let onRoutesReady = EventDispatcher()
19
- let onNavigationFinished = EventDispatcher()
20
- let onNavigationCancelled = EventDispatcher()
21
- let onRoutesFailed = EventDispatcher()
22
- let onArrival = EventDispatcher()
13
+ let onRoutesReady = EventDispatcher()
14
+ let onNavigationFinished = EventDispatcher()
15
+ let onNavigationCancelled = EventDispatcher()
16
+ let onRoutesFailed = EventDispatcher()
17
+ let onArrival = EventDispatcher()
23
18
  let onManeuverBannerPressed = EventDispatcher()
24
19
 
25
20
  // MARK: - Mapbox core
@@ -29,72 +24,79 @@ public class ExpoMapboxNavigationView: ExpoView {
29
24
  private var currentNavigationRoutes: NavigationRoutes?
30
25
  private var routeRequestTask: Task<Void, Never>?
31
26
 
32
- // MARK: - Props
33
- private var coordinates: [[String: Double]] = []
34
- private var waypointIndices: [Int]?
35
- private var language: String?
36
- private var voiceUnits: String?
37
- private var navigationProfile: String?
38
- private var excludeTypes: [String]?
39
- private var mapStyle: String?
40
- private var mute: Bool = false
41
- private var maxHeight: Double?
42
- private var maxWidth: Double?
43
- private var useMapMatching: Bool = false
44
- private var customRasterTileUrl: String?
27
+ // MARK: - State (mirrors Android state vars)
28
+ private var isMuted = false
29
+ private var isOverviewMode = false
30
+
31
+ // MARK: - Base props (parity with Android)
32
+ private var coordinates: [[String: Double]] = []
33
+ private var waypointIndices: [Int]?
34
+ private var language: String?
35
+ private var voiceUnits: String?
36
+ private var navigationProfile: String?
37
+ private var excludeTypes: [String]?
38
+ private var mapStyle: String?
39
+ private var mute: Bool = false
40
+ private var maxHeight: Double?
41
+ private var maxWidth: Double?
42
+ private var useMapMatching: Bool = false
43
+ private var customRasterTileUrl: String?
45
44
  private var customRasterAboveLayerId: String?
46
45
 
46
+ // MARK: - Color customization props (parity with Android)
47
+ // On iOS the NavigationViewController drop-in handles all UI natively,
48
+ // so we store these and apply what we can via its public API.
49
+ private var maneuverBackgroundColorDay: String?
50
+ private var maneuverTurnIconColor: String?
51
+ private var etaBarBackgroundColor: String?
52
+ private var etaTextColor: String?
53
+ private var iconButtonColor: String?
54
+ private var iconButtonMutedColor: String?
55
+
47
56
  // MARK: - Init
48
57
  public required init(appContext: AppContext? = nil) {
49
58
  super.init(appContext: appContext)
50
- let provider = MapboxNavigationProvider(coreConfig: .init())
51
- self.mapboxNavigationProvider = provider
52
- self.mapboxNavigation = provider.mapboxNavigation
59
+ DispatchQueue.main.async { [weak self] in
60
+ guard let self = self else { return }
61
+ let provider = MapboxNavigationProvider(coreConfig: .init())
62
+ self.mapboxNavigationProvider = provider
63
+ self.mapboxNavigation = provider.mapboxNavigation
64
+ }
53
65
  }
54
66
 
55
- // MARK: - Voice units (Issue #31 parity with Android)
56
- // FIX: use locale.regionCode instead of locale.region?.identifier
57
- // (locale.region is only available on iOS 16+, regionCode works from iOS 2+)
67
+ // MARK: - Voice units (Issue #31 parity exact same logic as Android)
58
68
  private func resolveVoiceUnits() -> String {
59
69
  if let units = voiceUnits?.lowercased(), units == "metric" || units == "imperial" {
60
70
  return units
61
71
  }
62
72
  let localeIdentifier = language ?? Locale.current.identifier
63
73
  let locale = Locale(identifier: localeIdentifier)
64
- // regionCode is available iOS 2+ (unlike .region?.identifier which is iOS 16+)
65
74
  let regionCode = locale.regionCode ?? ""
66
75
  let imperialCountries: Set<String> = ["US", "GB", "LR", "MM"]
67
76
  return imperialCountries.contains(regionCode) ? "imperial" : "metric"
68
77
  }
69
78
 
70
- // MARK: - Route fetching
79
+ // MARK: - Route fetching (parity with Android fetchRoutes)
71
80
  private func fetchRoutes() {
72
81
  guard coordinates.count >= 2, let mapboxNavigation = mapboxNavigation else { return }
73
82
 
74
83
  let waypoints = coordinates.map { coord -> Waypoint in
75
- let lat = coord["latitude"] ?? 0.0
76
- let lon = coord["longitude"] ?? 0.0
77
- return Waypoint(coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lon))
84
+ Waypoint(coordinate: CLLocationCoordinate2D(
85
+ latitude: coord["latitude"] ?? 0.0,
86
+ longitude: coord["longitude"] ?? 0.0
87
+ ))
78
88
  }
79
89
 
80
90
  var options = NavigationRouteOptions(waypoints: waypoints)
81
-
82
- if let langTag = language {
83
- options.locale = Locale(identifier: langTag)
84
- }
85
- let unit = resolveVoiceUnits()
86
- options.distanceUnit = (unit == "imperial") ? .mile : .kilometer
87
-
88
- if let profile = navigationProfile {
89
- switch profile {
90
- case "driving-traffic": options.profileIdentifier = .automobileAvoidingTraffic
91
- case "driving": options.profileIdentifier = .automobile
92
- case "walking": options.profileIdentifier = .walking
93
- case "cycling": options.profileIdentifier = .cycling
94
- default: break
95
- }
96
- } else {
97
- options.profileIdentifier = .automobileAvoidingTraffic
91
+ if let langTag = language { options.locale = Locale(identifier: langTag) }
92
+ options.distanceUnit = resolveVoiceUnits() == "imperial" ? .mile : .kilometer
93
+
94
+ switch navigationProfile ?? "driving-traffic" {
95
+ case "driving-traffic": options.profileIdentifier = .automobileAvoidingTraffic
96
+ case "driving": options.profileIdentifier = .automobile
97
+ case "walking": options.profileIdentifier = .walking
98
+ case "cycling": options.profileIdentifier = .cycling
99
+ default: options.profileIdentifier = .automobileAvoidingTraffic
98
100
  }
99
101
 
100
102
  routeRequestTask?.cancel()
@@ -108,8 +110,8 @@ public class ExpoMapboxNavigationView: ExpoView {
108
110
  self.currentNavigationRoutes = navigationRoutes
109
111
  let mainRoute = navigationRoutes.mainRoute.route
110
112
  self.onRoutesReady([
111
- "routeCount": navigationRoutes.alternativeRoutes.count + 1,
112
- "distanceMeters": mainRoute.distance,
113
+ "routeCount": navigationRoutes.alternativeRoutes.count + 1,
114
+ "distanceMeters": mainRoute.distance,
113
115
  "durationSeconds": mainRoute.expectedTravelTime
114
116
  ])
115
117
  await MainActor.run {
@@ -119,38 +121,33 @@ public class ExpoMapboxNavigationView: ExpoView {
119
121
  }
120
122
  }
121
123
 
122
- // MARK: - Present NavigationViewController
124
+ // MARK: - Present NavigationViewController (drop-in: includes ETA bar,
125
+ // speed limit, lane guidance, mute/overview/recenter buttons natively)
123
126
  private func presentNavigationViewController(with navigationRoutes: NavigationRoutes) {
124
127
  guard let provider = mapboxNavigationProvider,
125
128
  let mapboxNavigation = mapboxNavigation else { return }
126
129
 
127
130
  tearDownNavigationViewController()
128
131
 
129
- // FIX: In Navigation SDK v3, NavigationDayStyle / NavigationNightStyle
130
- // no longer exist. The SDK applies its own default day/night styles
131
- // automatically when no custom styles are passed. Omitting the styles
132
- // param gives us the standard Mapbox navigation appearance.
133
132
  let navigationOptions = NavigationOptions(
134
133
  mapboxNavigation: mapboxNavigation,
135
- voiceController: provider.routeVoiceController,
136
- eventsManager: provider.eventsManager()
134
+ voiceController: provider.routeVoiceController,
135
+ eventsManager: provider.eventsManager()
137
136
  )
138
137
 
139
138
  let vc = NavigationViewController(
140
- navigationRoutes: navigationRoutes,
139
+ navigationRoutes: navigationRoutes,
141
140
  navigationOptions: navigationOptions
142
141
  )
143
142
  vc.delegate = self
144
143
  vc.routeLineTracksTraversal = true
145
144
 
146
- // Mute: FIX — routeVoiceController is non-optional in v3, no ? needed
145
+ // Apply mute state
147
146
  if mute {
148
147
  provider.routeVoiceController.speechSynthesizer.muted = true
149
148
  }
150
149
 
151
- // Tap banner emit full steps list
152
- attachManeuverBannerTapHandler(to: vc)
153
-
150
+ // Add to view hierarchy FIRST, then attach tap handler
154
151
  addSubview(vc.view)
155
152
  vc.view.translatesAutoresizingMaskIntoConstraints = false
156
153
  NSLayoutConstraint.activate([
@@ -165,51 +162,58 @@ public class ExpoMapboxNavigationView: ExpoView {
165
162
  vc.didMove(toParent: parentVC)
166
163
  }
167
164
 
165
+ // Tap on banner → emit full steps list (parity with Android banner tap)
166
+ attachManeuverBannerTapHandler(to: vc)
167
+
168
168
  self.navigationViewController = vc
169
+ isOverviewMode = false
169
170
  }
170
171
 
172
+ // MARK: - Banner tap handler (parity with Android mv.setOnClickListener)
171
173
  private func attachManeuverBannerTapHandler(to vc: NavigationViewController) {
172
174
  let tap = UITapGestureRecognizer(target: self, action: #selector(handleManeuverBannerTap))
173
175
  vc.navigationView.topBannerContainerView.addGestureRecognizer(tap)
174
176
  vc.navigationView.topBannerContainerView.isUserInteractionEnabled = true
175
177
  }
176
178
 
177
- @objc private func handleManeuverBannerTap() {
178
- emitFullRouteSteps()
179
- }
179
+ @objc private func handleManeuverBannerTap() { emitFullRouteSteps() }
180
180
 
181
- // MARK: - Full route steps list
182
- // FIX: removed lane guidance extraction via intersection.approachLanes /
183
- // intersection.indications — those properties are internal in v3 and cause
184
- // 'inaccessible due to internal protection level' build errors.
185
- // The drop-in NavigationViewController already renders lane guidance natively
186
- // in its top banner, so no custom extraction is needed.
181
+ // MARK: - Full route steps (parity with Android emitFullRouteSteps)
187
182
  private func emitFullRouteSteps() {
188
183
  guard let navigationRoutes = currentNavigationRoutes else {
189
184
  onManeuverBannerPressed(["steps": []])
190
185
  return
191
186
  }
192
-
193
187
  let route = navigationRoutes.mainRoute.route
194
188
  var stepsPayload: [[String: Any]] = []
195
-
196
189
  for leg in route.legs {
197
190
  for step in leg.steps {
198
191
  stepsPayload.append([
199
- "instruction": step.instructions,
200
- "distanceMeters": step.distance,
201
- "durationSeconds": step.expectedTravelTime,
202
- "maneuverType": String(describing: step.maneuverType),
192
+ "instruction": step.instructions,
193
+ "distanceMeters": step.distance,
194
+ "durationSeconds": step.expectedTravelTime,
195
+ "maneuverType": String(describing: step.maneuverType),
203
196
  "maneuverModifier": step.maneuverDirection.map { String(describing: $0) } ?? "",
204
- "roadName": step.names?.first ?? "",
205
- "laneInstructions": [] // lane data surfaced natively in the banner
197
+ "roadName": step.names?.first ?? "",
198
+ "laneInstructions": [] // rendered natively by NavigationViewController banner
206
199
  ])
207
200
  }
208
201
  }
209
-
210
202
  onManeuverBannerPressed(["steps": stepsPayload])
211
203
  }
212
204
 
205
+ // MARK: - Mute (parity with Android toggleMute)
206
+ private func applyMute(_ shouldMute: Bool) {
207
+ isMuted = shouldMute
208
+ mapboxNavigationProvider?.routeVoiceController.speechSynthesizer.muted = shouldMute
209
+ }
210
+
211
+ // MARK: - Cancel (parity with Android cancelNavigation)
212
+ private func cancelNavigation() {
213
+ tearDownNavigationViewController()
214
+ onNavigationCancelled([:])
215
+ }
216
+
213
217
  // MARK: - Teardown
214
218
  private func tearDownNavigationViewController() {
215
219
  guard let vc = navigationViewController else { return }
@@ -217,12 +221,8 @@ public class ExpoMapboxNavigationView: ExpoView {
217
221
  vc.view.removeFromSuperview()
218
222
  vc.removeFromParent()
219
223
  navigationViewController = nil
220
- currentNavigationRoutes = nil
221
- }
222
-
223
- private func cancelNavigation() {
224
- tearDownNavigationViewController()
225
- onNavigationCancelled([:])
224
+ currentNavigationRoutes = nil
225
+ isOverviewMode = false
226
226
  }
227
227
 
228
228
  private func findParentViewController() -> UIViewController? {
@@ -234,27 +234,33 @@ public class ExpoMapboxNavigationView: ExpoView {
234
234
  return nil
235
235
  }
236
236
 
237
- // MARK: - Prop setters
237
+ // MARK: - Prop setters (exact parity with Android setters)
238
238
  func setCoordinates(_ coords: [[String: Double]]) {
239
239
  coordinates = coords
240
240
  if coords.count >= 2 { fetchRoutes() }
241
241
  }
242
- func setWaypointIndices(_ indices: [Int]?) { waypointIndices = indices }
243
- func setLanguage(_ lang: String?) { language = lang }
244
- func setVoiceUnits(_ units: String?) { voiceUnits = units }
245
- func setNavigationProfile(_ profile: String?) { navigationProfile = profile }
246
- func setExcludeTypes(_ types: [String]?) { excludeTypes = types }
247
- func setMapStyle(_ style: String?) { mapStyle = style }
248
- func setMute(_ shouldMute: Bool) {
249
- mute = shouldMute
250
- // FIX: routeVoiceController is non-optional in v3 — no ? needed
251
- mapboxNavigationProvider?.routeVoiceController.speechSynthesizer.muted = shouldMute
252
- }
253
- func setMaxHeight(_ height: Double?) { maxHeight = height }
254
- func setMaxWidth(_ width: Double?) { maxWidth = width }
255
- func setUseMapMatching(_ use: Bool) { useMapMatching = use }
256
- func setCustomRasterTileUrl(_ url: String?) { customRasterTileUrl = url }
257
- func setCustomRasterAboveLayerId(_ layerId: String?) { customRasterAboveLayerId = layerId }
242
+ func setWaypointIndices(_ i: [Int]?) { waypointIndices = i }
243
+ func setLanguage(_ l: String?) { language = l }
244
+ func setVoiceUnits(_ u: String?) { voiceUnits = u }
245
+ func setNavigationProfile(_ p: String?) { navigationProfile = p }
246
+ func setExcludeTypes(_ t: [String]?) { excludeTypes = t }
247
+ func setMapStyle(_ s: String?) { mapStyle = s }
248
+ func setMute(_ m: Bool) { mute = m; applyMute(m) }
249
+ func setMaxHeight(_ h: Double?) { maxHeight = h }
250
+ func setMaxWidth(_ w: Double?) { maxWidth = w }
251
+ func setUseMapMatching(_ u: Bool) { useMapMatching = u }
252
+ func setCustomRasterTileUrl(_ u: String?) { customRasterTileUrl = u }
253
+ func setCustomRasterAboveLayerId(_ l: String?) { customRasterAboveLayerId = l }
254
+
255
+ // Color props stored for reference; NavigationViewController applies its own
256
+ // theme automatically. Custom color support via NavigationViewController's
257
+ // StyleManager or subclassing can be added in future iterations.
258
+ func setManeuverBackgroundColorDay(_ c: String?) { maneuverBackgroundColorDay = c }
259
+ func setManeuverTurnIconColor(_ c: String?) { maneuverTurnIconColor = c }
260
+ func setEtaBarBackgroundColor(_ c: String?) { etaBarBackgroundColor = c }
261
+ func setEtaTextColor(_ c: String?) { etaTextColor = c }
262
+ func setIconButtonColor(_ c: String?) { iconButtonColor = c }
263
+ func setIconButtonMutedColor(_ c: String?) { iconButtonMutedColor = c }
258
264
 
259
265
  // MARK: - Lifecycle
260
266
  public override func removeFromSuperview() {
@@ -265,6 +271,7 @@ public class ExpoMapboxNavigationView: ExpoView {
265
271
  }
266
272
 
267
273
  // MARK: - NavigationViewControllerDelegate
274
+ // (parity with Android RoutesObserver + RouteProgressObserver + onArrival)
268
275
  extension ExpoMapboxNavigationView: NavigationViewControllerDelegate {
269
276
 
270
277
  public func navigationViewController(
@@ -274,12 +281,11 @@ extension ExpoMapboxNavigationView: NavigationViewControllerDelegate {
274
281
  rawLocation: CLLocation
275
282
  ) {
276
283
  onRouteProgressChanged([
277
- "distanceRemaining": progress.distanceRemaining,
278
- "durationRemaining": progress.durationRemaining,
279
- "distanceTraveled": progress.distanceTraveled,
280
- "fractionTraveled": progress.fractionTraveled,
281
- "currentStepDistanceRemaining":
282
- progress.currentLegProgress.currentStepProgress.distanceRemaining
284
+ "distanceRemaining": progress.distanceRemaining,
285
+ "durationRemaining": progress.durationRemaining,
286
+ "distanceTraveled": progress.distanceTraveled,
287
+ "fractionTraveled": progress.fractionTraveled,
288
+ "currentStepDistanceRemaining": progress.currentLegProgress.currentStepProgress.distanceRemaining
283
289
  ])
284
290
  }
285
291
 
@@ -288,7 +294,7 @@ extension ExpoMapboxNavigationView: NavigationViewControllerDelegate {
288
294
  didArriveAt waypoint: Waypoint
289
295
  ) -> Bool {
290
296
  onArrival([:])
291
- return true
297
+ return true // continue to next waypoint if multi-stop
292
298
  }
293
299
 
294
300
  public func navigationViewControllerDidDismiss(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jacques_gordon/expo-mapbox-navigation",
3
- "version": "2.2.4",
3
+ "version": "2.2.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",