react-native-google-maps-plus 0.1.0 → 1.0.0
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/GoogleMapsNitro.podspec +34 -0
- package/LICENSE +20 -0
- package/README.md +40 -0
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +135 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +8 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/googlemapsnitro/Color.kt +65 -0
- package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroPackage.kt +35 -0
- package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroViewImpl.kt +720 -0
- package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroModule.kt +22 -0
- package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroView.kt +337 -0
- package/android/src/main/java/com/googlemapsnitro/LocationHandler.kt +205 -0
- package/android/src/main/java/com/googlemapsnitro/MapMarker.kt +145 -0
- package/android/src/main/java/com/googlemapsnitro/MapPolygon.kt +36 -0
- package/android/src/main/java/com/googlemapsnitro/MapPolyline.kt +59 -0
- package/android/src/main/java/com/googlemapsnitro/PermissionHandler.kt +116 -0
- package/android/src/main/java/com/googlemapsnitro/PlayServicesHandler.kt +25 -0
- package/ios/Color.swift +109 -0
- package/ios/GoogleMapNitroViewImpl.swift +590 -0
- package/ios/HybridGoogleMapsNitroModule.swift +27 -0
- package/ios/HybridGoogleMapsNitroView.swift +348 -0
- package/ios/LocationHandler.swift +205 -0
- package/ios/MapHelper.swift +18 -0
- package/ios/MapMarker.swift +207 -0
- package/ios/MapPolygon.swift +55 -0
- package/ios/MapPolyline.swift +83 -0
- package/ios/PermissionHandler.swift +73 -0
- package/lib/module/GoogleMapsNitroModule.nitro.js +4 -0
- package/lib/module/GoogleMapsNitroModule.nitro.js.map +1 -0
- package/lib/module/GoogleMapsNitroView.nitro.js +4 -0
- package/lib/module/GoogleMapsNitroView.nitro.js.map +1 -0
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types.js +78 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts +12 -0
- package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts.map +1 -0
- package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts +34 -0
- package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +7 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +113 -0
- package/lib/typescript/src/types.d.ts.map +1 -0
- package/nitro.json +28 -0
- package/package.json +13 -3
- package/src/GoogleMapsNitroModule.nitro.ts +13 -0
- package/src/GoogleMapsNitroView.nitro.ts +78 -0
- package/src/index.tsx +24 -0
- package/src/types.ts +174 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
package com.googlemapsnitro
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
4
|
+
import com.google.android.gms.maps.model.PolygonOptions
|
|
5
|
+
|
|
6
|
+
class MapPolygonOptions {
|
|
7
|
+
fun buildPolygonOptions(poly: RNPolygon): PolygonOptions =
|
|
8
|
+
PolygonOptions().apply {
|
|
9
|
+
poly.coordinates.forEach { pt ->
|
|
10
|
+
add(
|
|
11
|
+
com.google.android.gms.maps.model
|
|
12
|
+
.LatLng(pt.latitude, pt.longitude),
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
poly.fillColor?.let { fillColor(it.toColor()) }
|
|
16
|
+
poly.strokeColor?.let { strokeColor(it.toColor()) }
|
|
17
|
+
poly.strokeWidth?.let { strokeWidth(it.dpToPx()) }
|
|
18
|
+
zIndex(poly.zIndex.toFloat())
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fun RNPolygon.polygonEquals(b: RNPolygon): Boolean {
|
|
23
|
+
if (zIndex != b.zIndex) return false
|
|
24
|
+
if (strokeWidth != b.strokeWidth) return false
|
|
25
|
+
if (fillColor != b.fillColor) return false
|
|
26
|
+
if (strokeColor != b.strokeColor) return false
|
|
27
|
+
val ac = coordinates
|
|
28
|
+
val bc = b.coordinates
|
|
29
|
+
if (ac.size != bc.size) return false
|
|
30
|
+
for (i in ac.indices) {
|
|
31
|
+
val p = ac[i]
|
|
32
|
+
val q = bc[i]
|
|
33
|
+
if (p.latitude != q.latitude || p.longitude != q.longitude) return false
|
|
34
|
+
}
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
package com.googlemapsnitro
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
4
|
+
import com.google.android.gms.maps.model.ButtCap
|
|
5
|
+
import com.google.android.gms.maps.model.Cap
|
|
6
|
+
import com.google.android.gms.maps.model.JointType
|
|
7
|
+
import com.google.android.gms.maps.model.PolylineOptions
|
|
8
|
+
import com.google.android.gms.maps.model.RoundCap
|
|
9
|
+
import com.google.android.gms.maps.model.SquareCap
|
|
10
|
+
|
|
11
|
+
class MapPolylineOptions {
|
|
12
|
+
fun buildPolylineOptions(pl: RNPolyline): PolylineOptions =
|
|
13
|
+
PolylineOptions().apply {
|
|
14
|
+
pl.coordinates.forEach { pt ->
|
|
15
|
+
add(
|
|
16
|
+
com.google.android.gms.maps.model
|
|
17
|
+
.LatLng(pt.latitude, pt.longitude),
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
pl.width?.let { width(it.dpToPx()) }
|
|
21
|
+
pl.lineCap?.let { startCap(mapLineCap(it)) }
|
|
22
|
+
pl.lineCap?.let { endCap(mapLineCap(it)) }
|
|
23
|
+
pl.lineJoin?.let { jointType(mapLineJoin(it)) }
|
|
24
|
+
pl.color?.let { color(it.toColor()) }
|
|
25
|
+
zIndex(pl.zIndex.toFloat())
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fun mapLineCap(type: RNLineCapType?): Cap =
|
|
29
|
+
when (type) {
|
|
30
|
+
RNLineCapType.ROUND -> RoundCap()
|
|
31
|
+
RNLineCapType.SQUARE -> SquareCap()
|
|
32
|
+
else -> ButtCap()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fun mapLineJoin(type: RNLineJoinType?): Int =
|
|
36
|
+
when (type) {
|
|
37
|
+
RNLineJoinType.ROUND -> JointType.ROUND
|
|
38
|
+
RNLineJoinType.BEVEL -> JointType.BEVEL
|
|
39
|
+
RNLineJoinType.MITER -> JointType.DEFAULT
|
|
40
|
+
null -> JointType.DEFAULT
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fun RNPolyline.polylineEquals(b: RNPolyline): Boolean {
|
|
45
|
+
if (zIndex != b.zIndex) return false
|
|
46
|
+
if ((width ?: 0.0) != (b.width ?: 0.0)) return false
|
|
47
|
+
if (lineCap != b.lineCap) return false
|
|
48
|
+
if (lineJoin != b.lineJoin) return false
|
|
49
|
+
if (color != b.color) return false
|
|
50
|
+
val ac = coordinates
|
|
51
|
+
val bc = b.coordinates
|
|
52
|
+
if (ac.size != bc.size) return false
|
|
53
|
+
for (i in ac.indices) {
|
|
54
|
+
val p = ac[i]
|
|
55
|
+
val q = bc[i]
|
|
56
|
+
if (p.latitude != q.latitude || p.longitude != q.longitude) return false
|
|
57
|
+
}
|
|
58
|
+
return true
|
|
59
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
package com.googlemapsnitro
|
|
2
|
+
|
|
3
|
+
import android.Manifest
|
|
4
|
+
import android.content.pm.PackageManager
|
|
5
|
+
import androidx.core.content.ContextCompat
|
|
6
|
+
import com.facebook.react.bridge.ReactContext
|
|
7
|
+
import com.facebook.react.bridge.UiThreadUtil
|
|
8
|
+
import com.facebook.react.modules.core.PermissionAwareActivity
|
|
9
|
+
import com.facebook.react.modules.core.PermissionListener
|
|
10
|
+
import com.margelo.nitro.core.Promise
|
|
11
|
+
|
|
12
|
+
private const val REQ_LOCATION = 1001
|
|
13
|
+
|
|
14
|
+
class PermissionHandler(
|
|
15
|
+
private val context: ReactContext,
|
|
16
|
+
) {
|
|
17
|
+
fun requestLocationPermission(): Promise<RNLocationPermissionResult> {
|
|
18
|
+
val promise = Promise<RNLocationPermissionResult>()
|
|
19
|
+
|
|
20
|
+
val perms =
|
|
21
|
+
arrayOf(
|
|
22
|
+
Manifest.permission.ACCESS_COARSE_LOCATION,
|
|
23
|
+
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
val alreadyGranted =
|
|
27
|
+
ContextCompat.checkSelfPermission(
|
|
28
|
+
context,
|
|
29
|
+
Manifest.permission.ACCESS_COARSE_LOCATION,
|
|
30
|
+
) == PackageManager.PERMISSION_GRANTED
|
|
31
|
+
if (alreadyGranted) {
|
|
32
|
+
promise.resolve(RNLocationPermissionResult(RNAndroidLocationPermissionResult.GRANTED, null))
|
|
33
|
+
return promise
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
UiThreadUtil.runOnUiThread {
|
|
37
|
+
val hostActivity = context.currentActivity
|
|
38
|
+
if (hostActivity !is PermissionAwareActivity) {
|
|
39
|
+
promise.resolve(RNLocationPermissionResult(RNAndroidLocationPermissionResult.DENIED, null))
|
|
40
|
+
return@runOnUiThread
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
hostActivity.requestPermissions(
|
|
44
|
+
perms,
|
|
45
|
+
REQ_LOCATION,
|
|
46
|
+
object : PermissionListener {
|
|
47
|
+
override fun onRequestPermissionsResult(
|
|
48
|
+
requestCode: Int,
|
|
49
|
+
permissions: Array<String>,
|
|
50
|
+
grantResults: IntArray,
|
|
51
|
+
): Boolean {
|
|
52
|
+
if (requestCode != REQ_LOCATION) return false
|
|
53
|
+
|
|
54
|
+
var coarseGranted = false
|
|
55
|
+
var fineGranted = false
|
|
56
|
+
|
|
57
|
+
for (i in permissions.indices) {
|
|
58
|
+
val p = permissions[i]
|
|
59
|
+
val r = grantResults.getOrNull(i) ?: continue
|
|
60
|
+
if (p == Manifest.permission.ACCESS_COARSE_LOCATION && r == PackageManager.PERMISSION_GRANTED) {
|
|
61
|
+
coarseGranted = true
|
|
62
|
+
}
|
|
63
|
+
if (p == Manifest.permission.ACCESS_FINE_LOCATION && r == PackageManager.PERMISSION_GRANTED) {
|
|
64
|
+
fineGranted = true
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
val hostActivity =
|
|
69
|
+
context.currentActivity ?: run {
|
|
70
|
+
promise.resolve(
|
|
71
|
+
RNLocationPermissionResult(
|
|
72
|
+
RNAndroidLocationPermissionResult.DENIED,
|
|
73
|
+
null,
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
return true
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
val granted = coarseGranted || fineGranted
|
|
80
|
+
if (granted) {
|
|
81
|
+
promise.resolve(
|
|
82
|
+
RNLocationPermissionResult(
|
|
83
|
+
RNAndroidLocationPermissionResult.GRANTED,
|
|
84
|
+
null,
|
|
85
|
+
),
|
|
86
|
+
)
|
|
87
|
+
} else {
|
|
88
|
+
val neverAskAgain =
|
|
89
|
+
!hostActivity.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_COARSE_LOCATION)
|
|
90
|
+
|
|
91
|
+
if (neverAskAgain) {
|
|
92
|
+
promise.resolve(
|
|
93
|
+
RNLocationPermissionResult(
|
|
94
|
+
RNAndroidLocationPermissionResult.NEVER_ASK_AGAIN,
|
|
95
|
+
null,
|
|
96
|
+
),
|
|
97
|
+
)
|
|
98
|
+
} else {
|
|
99
|
+
promise.resolve(
|
|
100
|
+
RNLocationPermissionResult(
|
|
101
|
+
RNAndroidLocationPermissionResult.DENIED,
|
|
102
|
+
null,
|
|
103
|
+
),
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return true
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return promise
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package com.googlemapsnitro
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactContext
|
|
4
|
+
import com.google.android.gms.common.ConnectionResult
|
|
5
|
+
import com.google.android.gms.common.GoogleApiAvailability
|
|
6
|
+
|
|
7
|
+
class PlayServicesHandler(
|
|
8
|
+
val context: ReactContext,
|
|
9
|
+
) {
|
|
10
|
+
fun playServicesAvailability(): Int {
|
|
11
|
+
val availability = GoogleApiAvailability.getInstance()
|
|
12
|
+
return availability.isGooglePlayServicesAvailable(context)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
fun isPlayServicesAvailable(): Boolean {
|
|
16
|
+
val availability = playServicesAvailability()
|
|
17
|
+
return when (availability) {
|
|
18
|
+
ConnectionResult.SERVICE_MISSING,
|
|
19
|
+
ConnectionResult.SERVICE_INVALID,
|
|
20
|
+
-> false
|
|
21
|
+
|
|
22
|
+
else -> true
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
package/ios/Color.swift
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
extension String {
|
|
2
|
+
func toUIColor(default defaultColor: UIColor = .clear) -> UIColor {
|
|
3
|
+
return UIColor.fromCssString(self) ?? defaultColor
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
extension UIColor {
|
|
8
|
+
static func fromCssString(_ s: String) -> UIColor? {
|
|
9
|
+
let str = s.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()
|
|
10
|
+
if str.hasPrefix("#") { return Self.fromHex(str) }
|
|
11
|
+
if str.hasPrefix("rgb") { return Self.fromRGBFunction(str) }
|
|
12
|
+
if str.hasPrefix("hsl") { return Self.fromHSLFunction(str) }
|
|
13
|
+
if let named = namedColors[str] { return named }
|
|
14
|
+
return nil
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private static let namedColors: [String: UIColor] = [
|
|
18
|
+
"red": .red, "green": .green, "blue": .blue,
|
|
19
|
+
"black": .black, "white": .white, "gray": .gray, "grey": .gray,
|
|
20
|
+
"yellow": .yellow, "orange": .orange, "purple": .purple,
|
|
21
|
+
"cyan": .cyan, "aqua": .cyan, "magenta": .magenta, "fuchsia": .magenta,
|
|
22
|
+
"brown": .brown, "clear": .clear, "transparent": .clear
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
private static func fromHex(_ hex: String) -> UIColor? {
|
|
26
|
+
var sanitized = hex.replacingOccurrences(of: "#", with: "")
|
|
27
|
+
if sanitized.count == 3 || sanitized.count == 4 {
|
|
28
|
+
sanitized = sanitized.map { "\($0)\($0)" }.joined()
|
|
29
|
+
}
|
|
30
|
+
if sanitized.count == 6 { sanitized += "ff" }
|
|
31
|
+
guard sanitized.count == 8, let rgba = UInt32(sanitized, radix: 16) else {
|
|
32
|
+
return nil
|
|
33
|
+
}
|
|
34
|
+
let r = CGFloat((rgba & 0xff00_0000) >> 24) / 255.0
|
|
35
|
+
let g = CGFloat((rgba & 0x00ff_0000) >> 16) / 255.0
|
|
36
|
+
let b = CGFloat((rgba & 0x0000_ff00) >> 8) / 255.0
|
|
37
|
+
let a = CGFloat(rgba & 0x0000_00ff) / 255.0
|
|
38
|
+
return UIColor(red: r, green: g, blue: b, alpha: a)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private static func fromRGBFunction(_ s: String) -> UIColor? {
|
|
42
|
+
let nums =
|
|
43
|
+
s
|
|
44
|
+
.replacingOccurrences(of: "rgba", with: "")
|
|
45
|
+
.replacingOccurrences(of: "rgb", with: "")
|
|
46
|
+
.replacingOccurrences(of: "(", with: "")
|
|
47
|
+
.replacingOccurrences(of: ")", with: "")
|
|
48
|
+
.split(separator: ",")
|
|
49
|
+
.map { $0.trimmingCharacters(in: .whitespaces) }
|
|
50
|
+
|
|
51
|
+
guard nums.count == 3 || nums.count == 4,
|
|
52
|
+
let r = Double(nums[0]),
|
|
53
|
+
let g = Double(nums[1]),
|
|
54
|
+
let b = Double(nums[2])
|
|
55
|
+
else { return nil }
|
|
56
|
+
let a = (nums.count == 4) ? (Double(nums[3]) ?? 1.0) : 1.0
|
|
57
|
+
return UIColor(
|
|
58
|
+
red: CGFloat(r / 255.0),
|
|
59
|
+
green: CGFloat(g / 255.0),
|
|
60
|
+
blue: CGFloat(b / 255.0),
|
|
61
|
+
alpha: CGFloat(a)
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private static func fromHSLFunction(_ s: String) -> UIColor? {
|
|
66
|
+
let parts =
|
|
67
|
+
s
|
|
68
|
+
.replacingOccurrences(of: "hsla", with: "")
|
|
69
|
+
.replacingOccurrences(of: "hsl", with: "")
|
|
70
|
+
.replacingOccurrences(of: "(", with: "")
|
|
71
|
+
.replacingOccurrences(of: ")", with: "")
|
|
72
|
+
.replacingOccurrences(of: "%", with: "")
|
|
73
|
+
.split(separator: ",")
|
|
74
|
+
.map { $0.trimmingCharacters(in: .whitespaces) }
|
|
75
|
+
|
|
76
|
+
guard parts.count == 3 || parts.count == 4,
|
|
77
|
+
let h = Double(parts[0]),
|
|
78
|
+
let sPerc = Double(parts[1]),
|
|
79
|
+
let lPerc = Double(parts[2])
|
|
80
|
+
else { return nil }
|
|
81
|
+
|
|
82
|
+
let a = (parts.count == 4) ? (Double(parts[3]) ?? 1.0) : 1.0
|
|
83
|
+
let s = sPerc / 100.0
|
|
84
|
+
let l = lPerc / 100.0
|
|
85
|
+
|
|
86
|
+
let c = (1 - Swift.abs(2 * l - 1)) * s
|
|
87
|
+
let x = c * (1 - Swift.abs((h / 60).truncatingRemainder(dividingBy: 2) - 1))
|
|
88
|
+
let m = l - c / 2
|
|
89
|
+
|
|
90
|
+
// swiftlint:disable:next large_tuple
|
|
91
|
+
let (r1, g1, b1): (Double, Double, Double)
|
|
92
|
+
switch h {
|
|
93
|
+
case 0..<60: (r1, g1, b1) = (c, x, 0)
|
|
94
|
+
case 60..<120: (r1, g1, b1) = (x, c, 0)
|
|
95
|
+
case 120..<180: (r1, g1, b1) = (0, c, x)
|
|
96
|
+
case 180..<240: (r1, g1, b1) = (0, x, c)
|
|
97
|
+
case 240..<300: (r1, g1, b1) = (x, 0, c)
|
|
98
|
+
case 300..<360: (r1, g1, b1) = (c, 0, x)
|
|
99
|
+
default: (r1, g1, b1) = (0, 0, 0)
|
|
100
|
+
}
|
|
101
|
+
return UIColor(
|
|
102
|
+
red: CGFloat(r1 + m),
|
|
103
|
+
green: CGFloat(g1 + m),
|
|
104
|
+
blue: CGFloat(b1 + m),
|
|
105
|
+
alpha: CGFloat(a)
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|