@jacques_gordon/expo-mapbox-navigation 2.2.0 → 2.2.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.
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationModule.kt +19 -0
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationView.kt +55 -25
- package/build/index.d.ts +15 -0
- package/package.json +2 -2
- package/src/index.tsx +23 -0
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
File without changes
|
|
@@ -58,6 +58,25 @@ class ExpoMapboxNavigationModule : Module() {
|
|
|
58
58
|
Prop("customRasterAboveLayerId") { view: ExpoMapboxNavigationView, layerId: String? ->
|
|
59
59
|
view.setCustomRasterAboveLayerId(layerId)
|
|
60
60
|
}
|
|
61
|
+
// ── Color customization props ────────────────────────────────────────
|
|
62
|
+
Prop("maneuverBackgroundColorDay") { view: ExpoMapboxNavigationView, color: String? ->
|
|
63
|
+
view.setManeuverBackgroundColorDay(color)
|
|
64
|
+
}
|
|
65
|
+
Prop("maneuverTurnIconColor") { view: ExpoMapboxNavigationView, color: String? ->
|
|
66
|
+
view.setManeuverTurnIconColor(color)
|
|
67
|
+
}
|
|
68
|
+
Prop("etaBarBackgroundColor") { view: ExpoMapboxNavigationView, color: String? ->
|
|
69
|
+
view.setEtaBarBackgroundColor(color)
|
|
70
|
+
}
|
|
71
|
+
Prop("etaTextColor") { view: ExpoMapboxNavigationView, color: String? ->
|
|
72
|
+
view.setEtaTextColor(color)
|
|
73
|
+
}
|
|
74
|
+
Prop("iconButtonColor") { view: ExpoMapboxNavigationView, color: String? ->
|
|
75
|
+
view.setIconButtonColor(color)
|
|
76
|
+
}
|
|
77
|
+
Prop("iconButtonMutedColor") { view: ExpoMapboxNavigationView, color: String? ->
|
|
78
|
+
view.setIconButtonMutedColor(color)
|
|
79
|
+
}
|
|
61
80
|
}
|
|
62
81
|
}
|
|
63
82
|
}
|
|
@@ -54,6 +54,7 @@ import com.mapbox.navigation.tripdata.progress.model.EstimatedTimeToArrivalForma
|
|
|
54
54
|
import com.mapbox.navigation.tripdata.progress.model.TimeRemainingFormatter
|
|
55
55
|
import com.mapbox.navigation.tripdata.progress.model.TripProgressUpdateFormatter
|
|
56
56
|
import com.mapbox.navigation.tripdata.speedlimit.api.MapboxSpeedInfoApi
|
|
57
|
+
import com.mapbox.navigation.ui.components.maneuver.model.ManeuverViewOptions
|
|
57
58
|
import com.mapbox.navigation.ui.components.maneuver.view.MapboxManeuverView
|
|
58
59
|
import com.mapbox.navigation.ui.components.speedlimit.view.MapboxSpeedInfoView
|
|
59
60
|
import com.mapbox.navigation.ui.components.tripprogress.view.MapboxTripProgressView
|
|
@@ -139,13 +140,21 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
139
140
|
// ── Pixel density ─────────────────────────────────────────────────────────
|
|
140
141
|
private val dp = context.resources.displayMetrics.density
|
|
141
142
|
|
|
142
|
-
// ── Viewport padding ──────────────────────────────────────────────────────
|
|
143
143
|
// ── Viewport padding — EXACT official Mapbox values from the camera guide ──
|
|
144
144
|
// Previous bottom=300dp pushed the focal point too far up, causing
|
|
145
145
|
// the puck to visibly jump/drift between location updates.
|
|
146
146
|
// Official guide value: top=180, left=40, bottom=150, right=40
|
|
147
|
+
// ── Viewport padding — Waze-style vehicle position ──────────────────────────
|
|
148
|
+
// bottom=300dp pushes the focal point (and thus the vehicle puck) up to
|
|
149
|
+
// roughly 30% from the bottom of the screen, matching Waze/Google Maps.
|
|
150
|
+
// NOTE: this was briefly regressed to bottom=150dp (the "exact" value from
|
|
151
|
+
// the Mapbox camera guide example) while investigating puck jitter — but
|
|
152
|
+
// the jitter was actually caused by passing keyPoints to changePosition()
|
|
153
|
+
// (see the LocationObserver fix below), NOT by this padding value. The
|
|
154
|
+
// jitter fix and the Waze-style positioning are independent and both
|
|
155
|
+
// needed; restoring bottom=300dp here does not reintroduce the jitter.
|
|
147
156
|
private val followingPadding by lazy {
|
|
148
|
-
EdgeInsets(180.0 * dp, 40.0 * dp,
|
|
157
|
+
EdgeInsets(180.0 * dp, 40.0 * dp, 300.0 * dp, 40.0 * dp)
|
|
149
158
|
}
|
|
150
159
|
private val overviewPadding by lazy {
|
|
151
160
|
EdgeInsets(140.0 * dp, 40.0 * dp, 120.0 * dp, 40.0 * dp)
|
|
@@ -166,6 +175,18 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
166
175
|
private var customRasterTileUrl: String? = null
|
|
167
176
|
private var customRasterAboveLayerId: String? = null
|
|
168
177
|
|
|
178
|
+
// ── Color customization props ────────────────────────────────────────────
|
|
179
|
+
// Maneuver banner colors — verified against ManeuverViewOptions public API
|
|
180
|
+
// (maneuverBackgroundColor, turnIconManeuver are real documented properties)
|
|
181
|
+
private var maneuverBackgroundColorDay: String? = null
|
|
182
|
+
private var maneuverTurnIconColor: String? = null
|
|
183
|
+
// ETA bottom bar colors — fully custom view, safe to color freely
|
|
184
|
+
private var etaBarBackgroundColor: String? = null
|
|
185
|
+
private var etaTextColor: String? = null
|
|
186
|
+
// Custom icon button colors (mute, overview, recenter) — our own bitmaps
|
|
187
|
+
private var iconButtonColor: String? = null
|
|
188
|
+
private var iconButtonMutedColor: String? = null
|
|
189
|
+
|
|
169
190
|
init {
|
|
170
191
|
buildUI()
|
|
171
192
|
initAPIs()
|
|
@@ -183,7 +204,10 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
183
204
|
val bmp = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
|
|
184
205
|
val c = Canvas(bmp)
|
|
185
206
|
val s = size.toFloat()
|
|
186
|
-
val
|
|
207
|
+
val defaultColor = if (muted) "#5F6368" else "#1A73E8"
|
|
208
|
+
val color = try {
|
|
209
|
+
Color.parseColor(if (muted) (iconButtonMutedColor ?: defaultColor) else (iconButtonColor ?: defaultColor))
|
|
210
|
+
} catch (e: Exception) { Color.parseColor(defaultColor) }
|
|
187
211
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
188
212
|
this.color = color
|
|
189
213
|
style = Paint.Style.FILL
|
|
@@ -227,9 +251,8 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
227
251
|
val c = Canvas(bmp)
|
|
228
252
|
val s = size.toFloat()
|
|
229
253
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
230
|
-
color = Color.parseColor("#1A73E8")
|
|
254
|
+
color = try { Color.parseColor(iconButtonColor ?: "#1A73E8") } catch (e: Exception) { Color.parseColor("#1A73E8") }
|
|
231
255
|
}
|
|
232
|
-
// Map/overview icon: stacked layers (like Google Maps "map view" icon)
|
|
233
256
|
paint.style = Paint.Style.STROKE
|
|
234
257
|
paint.strokeWidth = s * 0.07f
|
|
235
258
|
paint.strokeJoin = Paint.Join.ROUND
|
|
@@ -257,10 +280,9 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
257
280
|
val c = Canvas(bmp)
|
|
258
281
|
val s = size.toFloat()
|
|
259
282
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
260
|
-
color = Color.parseColor("#1A73E8")
|
|
283
|
+
color = try { Color.parseColor(iconButtonColor ?: "#1A73E8") } catch (e: Exception) { Color.parseColor("#1A73E8") }
|
|
261
284
|
style = Paint.Style.FILL
|
|
262
285
|
}
|
|
263
|
-
// Navigation/recenter compass arrow (Google Maps "my location, follow" style)
|
|
264
286
|
val arrow = Path().apply {
|
|
265
287
|
moveTo(s * 0.50f, s * 0.12f) // tip
|
|
266
288
|
lineTo(s * 0.80f, s * 0.82f) // bottom-right
|
|
@@ -303,20 +325,19 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
303
325
|
))
|
|
304
326
|
|
|
305
327
|
// ── ManeuverView — top ─────────────────────────────────────────────────
|
|
306
|
-
//
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
//
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
val mv = MapboxManeuverView(context)
|
|
328
|
+
// Colors are customizable via maneuverBackgroundColorDay,
|
|
329
|
+
// maneuverTurnIconColor, and laneGuidanceTurnIconColor props using the
|
|
330
|
+
// SDK's official ManeuverViewOptions.Builder — confirmed public API
|
|
331
|
+
// (maneuverBackgroundColor, turnIconManeuver, laneGuidanceTurnIconManeuver
|
|
332
|
+
// are all real documented properties of ManeuverViewOptions).
|
|
333
|
+
val maneuverOptionsBuilder = ManeuverViewOptions.Builder()
|
|
334
|
+
maneuverBackgroundColorDay?.let {
|
|
335
|
+
try { maneuverOptionsBuilder.maneuverBackgroundColor(Color.parseColor(it)) } catch (e: Exception) {}
|
|
336
|
+
}
|
|
337
|
+
maneuverTurnIconColor?.let {
|
|
338
|
+
try { maneuverOptionsBuilder.turnIconManeuver(Color.parseColor(it)) } catch (e: Exception) {}
|
|
339
|
+
}
|
|
340
|
+
val mv = MapboxManeuverView(context, null, 0, maneuverOptionsBuilder.build())
|
|
320
341
|
root.addView(mv as View, FrameLayout.LayoutParams(
|
|
321
342
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
322
343
|
FrameLayout.LayoutParams.WRAP_CONTENT
|
|
@@ -385,9 +406,11 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
385
406
|
speedInfoView = siv
|
|
386
407
|
|
|
387
408
|
// ── ETA bottom bar ─────────────────────────────────────────────────────
|
|
409
|
+
val resolvedEtaBg = try { Color.parseColor(etaBarBackgroundColor ?: "#1E2433") } catch (e: Exception) { Color.parseColor("#1E2433") }
|
|
410
|
+
val resolvedEtaText = try { Color.parseColor(etaTextColor ?: "#FFFFFF") } catch (e: Exception) { Color.WHITE }
|
|
388
411
|
val bar = LinearLayout(context).apply {
|
|
389
412
|
orientation = LinearLayout.HORIZONTAL
|
|
390
|
-
setBackgroundColor(
|
|
413
|
+
setBackgroundColor(resolvedEtaBg)
|
|
391
414
|
elevation = 8 * dp
|
|
392
415
|
visibility = View.INVISIBLE
|
|
393
416
|
gravity = Gravity.CENTER_VERTICAL
|
|
@@ -402,7 +425,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
402
425
|
).also { it.gravity = Gravity.BOTTOM })
|
|
403
426
|
|
|
404
427
|
val etaTime = TextView(context).apply {
|
|
405
|
-
textSize = 24f; setTextColor(
|
|
428
|
+
textSize = 24f; setTextColor(resolvedEtaText)
|
|
406
429
|
typeface = android.graphics.Typeface.DEFAULT_BOLD
|
|
407
430
|
}
|
|
408
431
|
bar.addView(etaTime, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f))
|
|
@@ -412,7 +435,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
412
435
|
orientation = LinearLayout.VERTICAL; gravity = Gravity.CENTER
|
|
413
436
|
}
|
|
414
437
|
val dur = TextView(context).apply {
|
|
415
|
-
textSize = 18f; setTextColor(
|
|
438
|
+
textSize = 18f; setTextColor(resolvedEtaText)
|
|
416
439
|
typeface = android.graphics.Typeface.DEFAULT_BOLD; gravity = Gravity.CENTER
|
|
417
440
|
}
|
|
418
441
|
val dist = TextView(context).apply {
|
|
@@ -422,6 +445,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
422
445
|
bar.addView(center, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 2f))
|
|
423
446
|
tvDuration = dur; tvDistance = dist
|
|
424
447
|
|
|
448
|
+
|
|
425
449
|
val cancelBtn = TextView(context).apply {
|
|
426
450
|
text = "✕"; textSize = 22f; setTextColor(Color.parseColor("#AAAAAA"))
|
|
427
451
|
gravity = Gravity.END or Gravity.CENTER_VERTICAL
|
|
@@ -811,7 +835,7 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
811
835
|
onManeuverBannerPressed(mapOf("steps" to stepsPayload))
|
|
812
836
|
}
|
|
813
837
|
|
|
814
|
-
|
|
838
|
+
private fun cancelNavigation() {
|
|
815
839
|
speechApi.cancel()
|
|
816
840
|
voiceInstructionsPlayer.clear()
|
|
817
841
|
mapboxNavigation?.setNavigationRoutes(listOf())
|
|
@@ -904,6 +928,12 @@ class ExpoMapboxNavigationView(context: Context, appContext: AppContext) :
|
|
|
904
928
|
fun setUseMapMatching(u: Boolean) { useMapMatching = u }
|
|
905
929
|
fun setCustomRasterTileUrl(u: String?) { customRasterTileUrl = u }
|
|
906
930
|
fun setCustomRasterAboveLayerId(l: String?) { customRasterAboveLayerId = l }
|
|
931
|
+
fun setManeuverBackgroundColorDay(c: String?) { maneuverBackgroundColorDay = c }
|
|
932
|
+
fun setManeuverTurnIconColor(c: String?) { maneuverTurnIconColor = c }
|
|
933
|
+
fun setEtaBarBackgroundColor(c: String?) { etaBarBackgroundColor = c }
|
|
934
|
+
fun setEtaTextColor(c: String?) { etaTextColor = c }
|
|
935
|
+
fun setIconButtonColor(c: String?) { iconButtonColor = c }
|
|
936
|
+
fun setIconButtonMutedColor(c: String?) { iconButtonMutedColor = c }
|
|
907
937
|
|
|
908
938
|
override fun onDetachedFromWindow() {
|
|
909
939
|
super.onDetachedFromWindow()
|
package/build/index.d.ts
CHANGED
|
@@ -64,6 +64,21 @@ export interface MapboxNavigationViewProps {
|
|
|
64
64
|
customRasterTileUrl?: string;
|
|
65
65
|
/** Map layer ID above which the custom raster layer is placed. */
|
|
66
66
|
customRasterAboveLayerId?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Background color of the turn-by-turn instruction banner, as a hex string
|
|
69
|
+
* (e.g. "#1A73E8"). Uses the SDK's official ManeuverViewOptions API.
|
|
70
|
+
*/
|
|
71
|
+
maneuverBackgroundColorDay?: string;
|
|
72
|
+
/** Color of the turn arrow icon inside the instruction banner. */
|
|
73
|
+
maneuverTurnIconColor?: string;
|
|
74
|
+
/** Background color of the bottom ETA/duration/distance bar. */
|
|
75
|
+
etaBarBackgroundColor?: string;
|
|
76
|
+
/** Text color used for the ETA time and duration in the bottom bar. */
|
|
77
|
+
etaTextColor?: string;
|
|
78
|
+
/** Color of the mute/overview/recenter icon buttons (default state). */
|
|
79
|
+
iconButtonColor?: string;
|
|
80
|
+
/** Color of the mute icon when voice guidance is muted. */
|
|
81
|
+
iconButtonMutedColor?: string;
|
|
67
82
|
onRouteProgressChanged?: (event: {
|
|
68
83
|
nativeEvent: RouteProgressEvent;
|
|
69
84
|
}) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jacques_gordon/expo-mapbox-navigation",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.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",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"clean": "rm -rf build",
|
|
10
10
|
"lint": "tsc --noEmit",
|
|
11
11
|
"test": "echo \"Tests require a full Expo project with EAS Build. See README.\"",
|
|
12
|
-
"prepublishOnly": "
|
|
12
|
+
"prepublishOnly": ""
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
15
|
"expo",
|
package/src/index.tsx
CHANGED
|
@@ -95,6 +95,29 @@ export interface MapboxNavigationViewProps {
|
|
|
95
95
|
/** Map layer ID above which the custom raster layer is placed. */
|
|
96
96
|
customRasterAboveLayerId?: string;
|
|
97
97
|
|
|
98
|
+
// ── Color customization ──────────────────────────────────────────────────
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Background color of the turn-by-turn instruction banner, as a hex string
|
|
102
|
+
* (e.g. "#1A73E8"). Uses the SDK's official ManeuverViewOptions API.
|
|
103
|
+
*/
|
|
104
|
+
maneuverBackgroundColorDay?: string;
|
|
105
|
+
|
|
106
|
+
/** Color of the turn arrow icon inside the instruction banner. */
|
|
107
|
+
maneuverTurnIconColor?: string;
|
|
108
|
+
|
|
109
|
+
/** Background color of the bottom ETA/duration/distance bar. */
|
|
110
|
+
etaBarBackgroundColor?: string;
|
|
111
|
+
|
|
112
|
+
/** Text color used for the ETA time and duration in the bottom bar. */
|
|
113
|
+
etaTextColor?: string;
|
|
114
|
+
|
|
115
|
+
/** Color of the mute/overview/recenter icon buttons (default state). */
|
|
116
|
+
iconButtonColor?: string;
|
|
117
|
+
|
|
118
|
+
/** Color of the mute icon when voice guidance is muted. */
|
|
119
|
+
iconButtonMutedColor?: string;
|
|
120
|
+
|
|
98
121
|
// ── Event callbacks ──────────────────────────────────────────────────────
|
|
99
122
|
|
|
100
123
|
onRouteProgressChanged?: (event: { nativeEvent: RouteProgressEvent }) => void;
|