@jacques_gordon/expo-mapbox-navigation 1.0.7 → 2.0.1
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/ExpoMapboxNavigation.podspec +39 -0
- package/LICENSE +21 -0
- package/README.md +103 -209
- package/android/build.gradle +101 -39
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationModule.kt +81 -77
- package/android/src/main/java/expo/modules/mapboxnavigation/ExpoMapboxNavigationView.kt +260 -142
- package/app.plugin.js +216 -1
- package/build/index.d.ts +121 -2
- package/build/index.js +34 -3
- package/build/src/index.d.ts +121 -0
- package/build/src/index.js +39 -0
- package/package.json +37 -37
- package/plugin/src/index.js +216 -0
- package/src/index.tsx +162 -0
- 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/9.2.0/checksums/checksums.lock +0 -0
- package/android/.gradle/9.2.0/fileChanges/last-build.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/9.2.0/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/9.2.0/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/build/MapboxNavigation.types.d.ts +0 -132
- package/build/MapboxNavigation.types.js +0 -2
- package/build/MapboxNavigationView.d.ts +0 -30
- package/build/MapboxNavigationView.js +0 -41
- package/expo-module.config.json +0 -9
- package/ios/ExpoMapboxNavigation.podspec +0 -25
- package/ios/ExpoMapboxNavigationModule.swift +0 -81
- package/ios/ExpoMapboxNavigationView.swift +0 -236
- package/plugin/index.js +0 -167
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import ExpoModulesCore
|
|
2
|
-
|
|
3
|
-
public class ExpoMapboxNavigationModule: Module {
|
|
4
|
-
public func definition() -> ModuleDefinition {
|
|
5
|
-
Name("ExpoMapboxNavigation")
|
|
6
|
-
|
|
7
|
-
View(ExpoMapboxNavigationView.self) {
|
|
8
|
-
|
|
9
|
-
// ─── Props ────────────────────────────────────────────────────────
|
|
10
|
-
|
|
11
|
-
Prop("coordinates") { (view: ExpoMapboxNavigationView, value: [[String: Double]]) in
|
|
12
|
-
view.coordinates = value
|
|
13
|
-
view.startNavigationIfReady()
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
Prop("waypointIndices") { (view: ExpoMapboxNavigationView, value: [Int]) in
|
|
17
|
-
view.waypointIndices = value
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
Prop("useRouteMatchingApi") { (view: ExpoMapboxNavigationView, value: Bool) in
|
|
21
|
-
view.useRouteMatchingApi = value
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
Prop("locale") { (view: ExpoMapboxNavigationView, value: String) in
|
|
25
|
-
view.locale = value
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
Prop("routeProfile") { (view: ExpoMapboxNavigationView, value: String) in
|
|
29
|
-
view.routeProfile = value
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
Prop("routeExcludeList") { (view: ExpoMapboxNavigationView, value: [String]) in
|
|
33
|
-
view.routeExcludeList = value
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
Prop("mapStyle") { (view: ExpoMapboxNavigationView, value: String) in
|
|
37
|
-
view.mapStyle = value
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
Prop("mute") { (view: ExpoMapboxNavigationView, value: Bool) in
|
|
41
|
-
view.mute = value
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
Prop("vehicleMaxHeight") { (view: ExpoMapboxNavigationView, value: Double) in
|
|
45
|
-
view.vehicleMaxHeight = value
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
Prop("vehicleMaxWidth") { (view: ExpoMapboxNavigationView, value: Double) in
|
|
49
|
-
view.vehicleMaxWidth = value
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
Prop("customRasterSourceUrl") { (view: ExpoMapboxNavigationView, value: String) in
|
|
53
|
-
view.customRasterSourceUrl = value
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
Prop("placeCustomRasterLayerAbove") { (view: ExpoMapboxNavigationView, value: String) in
|
|
57
|
-
view.placeCustomRasterLayerAbove = value
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
Prop("disableAlternativeRoutes") { (view: ExpoMapboxNavigationView, value: Bool) in
|
|
61
|
-
view.disableAlternativeRoutes = value
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
Prop("showsEndOfRouteFeedback") { (view: ExpoMapboxNavigationView, value: Bool) in
|
|
65
|
-
view.showsEndOfRouteFeedback = value
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// ─── Events ───────────────────────────────────────────────────────
|
|
69
|
-
|
|
70
|
-
Events(
|
|
71
|
-
"onRouteProgressChanged",
|
|
72
|
-
"onWaypointArrival",
|
|
73
|
-
"onFinalDestinationArrival",
|
|
74
|
-
"onCancelNavigation",
|
|
75
|
-
"onRouteChanged",
|
|
76
|
-
"onUserOffRoute",
|
|
77
|
-
"onRoutesLoaded"
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import ExpoModulesCore
|
|
2
|
-
import MapboxNavigationCore
|
|
3
|
-
import MapboxNavigationUIKit
|
|
4
|
-
import MapboxMaps
|
|
5
|
-
import MapboxDirections
|
|
6
|
-
|
|
7
|
-
class ExpoMapboxNavigationView: ExpoView {
|
|
8
|
-
|
|
9
|
-
// ─── Props ──────────────────────────────────────────────────────────────
|
|
10
|
-
var coordinates: [[String: Double]] = []
|
|
11
|
-
var waypointIndices: [Int] = []
|
|
12
|
-
var useRouteMatchingApi: Bool = false
|
|
13
|
-
var locale: String = ""
|
|
14
|
-
var routeProfile: String = "mapbox/driving-traffic"
|
|
15
|
-
var routeExcludeList: [String] = []
|
|
16
|
-
var mapStyle: String? = nil
|
|
17
|
-
var mute: Bool = false
|
|
18
|
-
var vehicleMaxHeight: Double? = nil
|
|
19
|
-
var vehicleMaxWidth: Double? = nil
|
|
20
|
-
var customRasterSourceUrl: String? = nil
|
|
21
|
-
var placeCustomRasterLayerAbove: String? = nil
|
|
22
|
-
var disableAlternativeRoutes: Bool = false
|
|
23
|
-
var showsEndOfRouteFeedback: Bool = false
|
|
24
|
-
|
|
25
|
-
// ─── Events ─────────────────────────────────────────────────────────────
|
|
26
|
-
let onRouteProgressChanged = EventDispatcher()
|
|
27
|
-
let onWaypointArrival = EventDispatcher()
|
|
28
|
-
let onFinalDestinationArrival = EventDispatcher()
|
|
29
|
-
let onCancelNavigation = EventDispatcher()
|
|
30
|
-
let onRouteChanged = EventDispatcher()
|
|
31
|
-
let onUserOffRoute = EventDispatcher()
|
|
32
|
-
let onRoutesLoaded = EventDispatcher()
|
|
33
|
-
|
|
34
|
-
// ─── Internal ───────────────────────────────────────────────────────────
|
|
35
|
-
private var navigationViewController: NavigationViewController?
|
|
36
|
-
private var isNavigationStarted = false
|
|
37
|
-
private var currentWaypointIndex = 0
|
|
38
|
-
private var totalWaypoints = 0
|
|
39
|
-
|
|
40
|
-
required init(appContext: AppContext? = nil) {
|
|
41
|
-
super.init(appContext: appContext)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
func startNavigationIfReady() {
|
|
45
|
-
guard coordinates.count >= 2, !isNavigationStarted else { return }
|
|
46
|
-
isNavigationStarted = true
|
|
47
|
-
setupNavigation()
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
override func layoutSubviews() {
|
|
51
|
-
super.layoutSubviews()
|
|
52
|
-
startNavigationIfReady()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// ─── Navigation Setup ───────────────────────────────────────────────────
|
|
56
|
-
|
|
57
|
-
private func setupNavigation() {
|
|
58
|
-
// Construire les waypoints
|
|
59
|
-
var allWaypoints: [Waypoint] = []
|
|
60
|
-
|
|
61
|
-
for (index, coord) in coordinates.enumerated() {
|
|
62
|
-
guard let lat = coord["latitude"], let lng = coord["longitude"] else { continue }
|
|
63
|
-
let location = CLLocationCoordinate2D(latitude: lat, longitude: lng)
|
|
64
|
-
let wp = Waypoint(coordinate: location)
|
|
65
|
-
|
|
66
|
-
// Marquer les waypoints intermédiaires vs simples pass-through
|
|
67
|
-
if !waypointIndices.isEmpty {
|
|
68
|
-
wp.separatesLegs = waypointIndices.contains(index)
|
|
69
|
-
} else {
|
|
70
|
-
wp.separatesLegs = true
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
allWaypoints.append(wp)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
totalWaypoints = allWaypoints.filter { $0.separatesLegs }.count
|
|
77
|
-
|
|
78
|
-
// Choisir le profil de routing
|
|
79
|
-
let profile: ProfileIdentifier
|
|
80
|
-
switch routeProfile {
|
|
81
|
-
case "mapbox/driving": profile = .automobile
|
|
82
|
-
case "mapbox/walking": profile = .walking
|
|
83
|
-
case "mapbox/cycling": profile = .cycling
|
|
84
|
-
default: profile = .automobileAvoidingTraffic
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Options de route
|
|
88
|
-
let routeOptions = NavigationRouteOptions(waypoints: allWaypoints, profileIdentifier: profile)
|
|
89
|
-
|
|
90
|
-
let resolvedLocale = locale.isEmpty ? Locale.current.identifier : locale
|
|
91
|
-
routeOptions.locale = Locale(identifier: resolvedLocale)
|
|
92
|
-
routeOptions.includesSpokenInstructions = true
|
|
93
|
-
routeOptions.includesVisualInstructions = true
|
|
94
|
-
|
|
95
|
-
// Exclusions
|
|
96
|
-
if !routeExcludeList.isEmpty {
|
|
97
|
-
routeOptions.roadClassesToAvoid = buildRoadClassesToAvoid(routeExcludeList)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Restrictions de véhicule
|
|
101
|
-
if let maxH = vehicleMaxHeight {
|
|
102
|
-
routeOptions.maximumHeight = Measurement(value: maxH, unit: .meters)
|
|
103
|
-
}
|
|
104
|
-
if let maxW = vehicleMaxWidth {
|
|
105
|
-
routeOptions.maximumWidth = Measurement(value: maxW, unit: .meters)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if disableAlternativeRoutes {
|
|
109
|
-
routeOptions.includesAlternativeRoutes = false
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Calcul de la route
|
|
113
|
-
Directions.shared.calculate(routeOptions) { [weak self] (_, result) in
|
|
114
|
-
guard let self = self else { return }
|
|
115
|
-
switch result {
|
|
116
|
-
case .failure(let error):
|
|
117
|
-
print("[ExpoMapboxNavigation] Erreur calcul route: \(error.localizedDescription)")
|
|
118
|
-
case .success(let response):
|
|
119
|
-
guard let routes = response.routes, !routes.isEmpty else { return }
|
|
120
|
-
self.onRoutesLoaded([:])
|
|
121
|
-
self.presentNavigationUI(routes: routes, options: routeOptions)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private func presentNavigationUI(routes: [Route], options: NavigationRouteOptions) {
|
|
127
|
-
DispatchQueue.main.async { [weak self] in
|
|
128
|
-
guard let self = self else { return }
|
|
129
|
-
|
|
130
|
-
let navigationService = MapboxNavigationService(
|
|
131
|
-
routes: routes,
|
|
132
|
-
customRoutingProvider: NavigationSettings.shared.directions,
|
|
133
|
-
credentials: NavigationSettings.shared.directions.credentials,
|
|
134
|
-
simulating: .onPoorGPS
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
let navigationOptions = NavigationOptions(navigationService: navigationService)
|
|
138
|
-
let navVC = NavigationViewController(
|
|
139
|
-
for: routes,
|
|
140
|
-
routeIndex: 0,
|
|
141
|
-
routeOptions: options,
|
|
142
|
-
navigationOptions: navigationOptions
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
navVC.delegate = self
|
|
146
|
-
navVC.showsEndOfRouteFeedback = self.showsEndOfRouteFeedback
|
|
147
|
-
navVC.showsReportFeedback = false
|
|
148
|
-
|
|
149
|
-
if self.mute {
|
|
150
|
-
navVC.navigationService.router.reroutesProactively = false
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
self.navigationViewController = navVC
|
|
154
|
-
|
|
155
|
-
guard let parentVC = self.parentViewController else { return }
|
|
156
|
-
parentVC.addChild(navVC)
|
|
157
|
-
navVC.view.frame = self.bounds
|
|
158
|
-
navVC.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
159
|
-
self.addSubview(navVC.view)
|
|
160
|
-
navVC.didMove(toParent: parentVC)
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
private func buildRoadClassesToAvoid(_ list: [String]) -> RoadClasses {
|
|
165
|
-
var classes = RoadClasses()
|
|
166
|
-
for item in list {
|
|
167
|
-
switch item {
|
|
168
|
-
case "toll": classes.insert(.toll)
|
|
169
|
-
case "ferry": classes.insert(.ferry)
|
|
170
|
-
case "motorway": classes.insert(.motorway)
|
|
171
|
-
default: break
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return classes
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private var parentViewController: UIViewController? {
|
|
178
|
-
var responder: UIResponder? = self
|
|
179
|
-
while let r = responder {
|
|
180
|
-
if let vc = r as? UIViewController { return vc }
|
|
181
|
-
responder = r.next
|
|
182
|
-
}
|
|
183
|
-
return nil
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// ─── NavigationViewControllerDelegate ───────────────────────────────────────
|
|
188
|
-
|
|
189
|
-
extension ExpoMapboxNavigationView: NavigationViewControllerDelegate {
|
|
190
|
-
|
|
191
|
-
func navigationViewController(
|
|
192
|
-
_ vc: NavigationViewController,
|
|
193
|
-
didUpdate progress: RouteProgress,
|
|
194
|
-
with location: CLLocation,
|
|
195
|
-
rawLocation: CLLocation
|
|
196
|
-
) {
|
|
197
|
-
onRouteProgressChanged([
|
|
198
|
-
"distanceRemaining": progress.currentLegProgress.distanceRemaining,
|
|
199
|
-
"distanceTraveled": progress.distanceTraveled,
|
|
200
|
-
"durationRemaining": progress.durationRemaining,
|
|
201
|
-
"fractionTraveled": progress.fractionTraveled
|
|
202
|
-
])
|
|
203
|
-
|
|
204
|
-
// Détection hors route
|
|
205
|
-
if progress.currentLegProgress.userHasArrivedAtWaypoint {
|
|
206
|
-
currentWaypointIndex += 1
|
|
207
|
-
if currentWaypointIndex < totalWaypoints - 1 {
|
|
208
|
-
onWaypointArrival([
|
|
209
|
-
"distanceRemaining": progress.currentLegProgress.distanceRemaining,
|
|
210
|
-
"distanceTraveled": progress.distanceTraveled,
|
|
211
|
-
"durationRemaining": progress.durationRemaining,
|
|
212
|
-
"fractionTraveled": progress.fractionTraveled
|
|
213
|
-
])
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
func navigationViewControllerDidFinishRouting(_ vc: NavigationViewController) {
|
|
219
|
-
onFinalDestinationArrival([:])
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
func navigationViewControllerDidDismiss(_ vc: NavigationViewController, byCanceling canceled: Bool) {
|
|
223
|
-
if canceled {
|
|
224
|
-
onCancelNavigation([:])
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
func navigationViewController(_ vc: NavigationViewController, didRerouteAlong route: Route) {
|
|
229
|
-
onRouteChanged([:])
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
func navigationViewController(_ vc: NavigationViewController, shouldRerouteFrom location: CLLocation) -> Bool {
|
|
233
|
-
onUserOffRoute([:])
|
|
234
|
-
return true
|
|
235
|
-
}
|
|
236
|
-
}
|
package/plugin/index.js
DELETED
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
withInfoPlist,
|
|
3
|
-
withAppBuildGradle,
|
|
4
|
-
withProjectBuildGradle,
|
|
5
|
-
withAndroidManifest,
|
|
6
|
-
createRunOncePlugin,
|
|
7
|
-
} = require("@expo/config-plugins");
|
|
8
|
-
|
|
9
|
-
const withExpoMapboxNavigation = (config, options) => {
|
|
10
|
-
const {
|
|
11
|
-
accessToken,
|
|
12
|
-
mapboxMapsVersion = "11.11.0",
|
|
13
|
-
androidColorOverrides = {},
|
|
14
|
-
} = options || {};
|
|
15
|
-
|
|
16
|
-
if (!accessToken) {
|
|
17
|
-
throw new Error(
|
|
18
|
-
"[expo-mapbox-navigation] accessToken est requis dans la configuration du plugin."
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ── iOS ──
|
|
23
|
-
config = withInfoPlist(config, (cfg) => {
|
|
24
|
-
cfg.modResults["MBXAccessToken"] = accessToken;
|
|
25
|
-
|
|
26
|
-
cfg.modResults["NSLocationWhenInUseUsageDescription"] =
|
|
27
|
-
cfg.modResults["NSLocationWhenInUseUsageDescription"] ??
|
|
28
|
-
"Cette application utilise votre position pour la navigation GPS.";
|
|
29
|
-
|
|
30
|
-
cfg.modResults["NSLocationAlwaysAndWhenInUseUsageDescription"] =
|
|
31
|
-
cfg.modResults["NSLocationAlwaysAndWhenInUseUsageDescription"] ??
|
|
32
|
-
"Cette application utilise votre position en arrière-plan pour la navigation GPS.";
|
|
33
|
-
|
|
34
|
-
cfg.modResults["NSMotionUsageDescription"] =
|
|
35
|
-
cfg.modResults["NSMotionUsageDescription"] ??
|
|
36
|
-
"Cette application utilise le capteur de mouvement pour améliorer la navigation.";
|
|
37
|
-
|
|
38
|
-
const uiBackgroundModes = cfg.modResults["UIBackgroundModes"] ?? [];
|
|
39
|
-
if (!uiBackgroundModes.includes("audio")) uiBackgroundModes.push("audio");
|
|
40
|
-
if (!uiBackgroundModes.includes("location"))
|
|
41
|
-
uiBackgroundModes.push("location");
|
|
42
|
-
cfg.modResults["UIBackgroundModes"] = uiBackgroundModes;
|
|
43
|
-
|
|
44
|
-
return cfg;
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// ── Android project build.gradle ──
|
|
48
|
-
config = withProjectBuildGradle(config, (cfg) => {
|
|
49
|
-
if (!cfg.modResults.contents.includes("api.mapbox.com/downloads")) {
|
|
50
|
-
cfg.modResults.contents = cfg.modResults.contents.replace(
|
|
51
|
-
/allprojects\s*\{([\s\S]*?)repositories\s*\{/,
|
|
52
|
-
`allprojects {$1repositories {
|
|
53
|
-
maven {
|
|
54
|
-
url 'https://api.mapbox.com/downloads/v2/releases/maven'
|
|
55
|
-
authentication { basic(BasicAuthentication) }
|
|
56
|
-
credentials {
|
|
57
|
-
username = "mapbox"
|
|
58
|
-
password = project.properties['MAPBOX_DOWNLOADS_TOKEN'] ?: System.getenv("MAPBOX_DOWNLOADS_TOKEN") ?: ""
|
|
59
|
-
}
|
|
60
|
-
}`
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return cfg;
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// ── Android app build.gradle ──
|
|
67
|
-
config = withAppBuildGradle(config, (cfg) => {
|
|
68
|
-
if (!cfg.modResults.contents.includes("mapbox_access_token")) {
|
|
69
|
-
cfg.modResults.contents = cfg.modResults.contents.replace(
|
|
70
|
-
/defaultConfig\s*\{/,
|
|
71
|
-
`defaultConfig {
|
|
72
|
-
resValue "string", "mapbox_access_token", "${accessToken}"`
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (
|
|
77
|
-
mapboxMapsVersion &&
|
|
78
|
-
!cfg.modResults.contents.includes("RNMapboxMapsVersion")
|
|
79
|
-
) {
|
|
80
|
-
cfg.modResults.contents = cfg.modResults.contents.replace(
|
|
81
|
-
/ext\s*\{/,
|
|
82
|
-
`ext {
|
|
83
|
-
RNMapboxMapsVersion = "${mapboxMapsVersion}"`
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
if (!cfg.modResults.contents.includes("RNMapboxMapsVersion")) {
|
|
87
|
-
cfg.modResults.contents = cfg.modResults.contents.replace(
|
|
88
|
-
/^(buildscript\s*\{)/m,
|
|
89
|
-
`ext {
|
|
90
|
-
RNMapboxMapsVersion = "${mapboxMapsVersion}"
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
$1`
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (Object.keys(androidColorOverrides).length > 0) {
|
|
99
|
-
const colorResources = Object.entries(androidColorOverrides)
|
|
100
|
-
.map(([name, value]) => ` resValue "color", "${name}", "${value}"`)
|
|
101
|
-
.join("\n");
|
|
102
|
-
|
|
103
|
-
if (!cfg.modResults.contents.includes("androidColorOverrides_injected")) {
|
|
104
|
-
cfg.modResults.contents = cfg.modResults.contents.replace(
|
|
105
|
-
/defaultConfig\s*\{/,
|
|
106
|
-
`defaultConfig {
|
|
107
|
-
${colorResources}
|
|
108
|
-
// androidColorOverrides_injected`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return cfg;
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// ── Android Manifest ──
|
|
117
|
-
config = withAndroidManifest(config, (cfg) => {
|
|
118
|
-
const manifest = cfg.modResults.manifest;
|
|
119
|
-
const permissions = manifest["uses-permission"] ?? [];
|
|
120
|
-
|
|
121
|
-
const addPermission = (name) => {
|
|
122
|
-
if (!permissions.some((p) => p.$?.["android:name"] === name)) {
|
|
123
|
-
permissions.push({ $: { "android:name": name } });
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
addPermission("android.permission.ACCESS_FINE_LOCATION");
|
|
128
|
-
addPermission("android.permission.ACCESS_COARSE_LOCATION");
|
|
129
|
-
addPermission("android.permission.FOREGROUND_SERVICE");
|
|
130
|
-
addPermission("android.permission.FOREGROUND_SERVICE_LOCATION");
|
|
131
|
-
|
|
132
|
-
manifest["uses-permission"] = permissions;
|
|
133
|
-
|
|
134
|
-
const application = manifest.application?.[0];
|
|
135
|
-
if (application) {
|
|
136
|
-
const metaData = application["meta-data"] ?? [];
|
|
137
|
-
|
|
138
|
-
const existingToken = metaData.find(
|
|
139
|
-
(m) => m.$?.["android:name"] === "com.mapbox.token"
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
if (!existingToken) {
|
|
143
|
-
metaData.push({
|
|
144
|
-
$: {
|
|
145
|
-
"android:name": "com.mapbox.token",
|
|
146
|
-
"android:value": accessToken,
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
application["meta-data"] = metaData;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return cfg;
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
return config;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const plugin = createRunOncePlugin(
|
|
161
|
-
withExpoMapboxNavigation,
|
|
162
|
-
"expo-mapbox-navigation",
|
|
163
|
-
"1.0.7"
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
module.exports = plugin;
|
|
167
|
-
module.exports.default = plugin;
|