@exterio/react-native-yamap-lite 1.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.
Files changed (141) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +510 -0
  3. package/YamapLite.podspec +21 -0
  4. package/android/build.gradle +101 -0
  5. package/android/gradle.properties +14 -0
  6. package/android/settings.gradle +1 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/com/yamaplite/ClusteredYamapLiteViewManager.kt +181 -0
  9. package/android/src/main/java/com/yamaplite/Components/ClusteredYamapLiteView.kt +169 -0
  10. package/android/src/main/java/com/yamaplite/Components/YamapLiteCircleView.kt +145 -0
  11. package/android/src/main/java/com/yamaplite/Components/YamapLiteMarkerView.kt +214 -0
  12. package/android/src/main/java/com/yamaplite/Components/YamapLitePolygon.kt +149 -0
  13. package/android/src/main/java/com/yamaplite/Components/YamapLitePolyline.kt +171 -0
  14. package/android/src/main/java/com/yamaplite/Components/YamapLiteView.kt +678 -0
  15. package/android/src/main/java/com/yamaplite/Events/CameraPositionChangeEvent.kt +38 -0
  16. package/android/src/main/java/com/yamaplite/Events/MapLoadEvent.kt +34 -0
  17. package/android/src/main/java/com/yamaplite/Events/PressEvent.kt +24 -0
  18. package/android/src/main/java/com/yamaplite/Utils/ImageCache.kt +45 -0
  19. package/android/src/main/java/com/yamaplite/Utils/PointParser.kt +39 -0
  20. package/android/src/main/java/com/yamaplite/Utils/ResolveImageHelper.kt +122 -0
  21. package/android/src/main/java/com/yamaplite/Utils/YamapUtils.kt +169 -0
  22. package/android/src/main/java/com/yamaplite/YamapLiteCircleViewManager.kt +67 -0
  23. package/android/src/main/java/com/yamaplite/YamapLiteMarkerViewManager.kt +82 -0
  24. package/android/src/main/java/com/yamaplite/YamapLitePackage.kt +41 -0
  25. package/android/src/main/java/com/yamaplite/YamapLitePolygonViewManager.kt +61 -0
  26. package/android/src/main/java/com/yamaplite/YamapLitePolylineViewManager.kt +75 -0
  27. package/android/src/main/java/com/yamaplite/YamapLiteViewManager.kt +176 -0
  28. package/ios/ClusteredYamapLiteView.h +15 -0
  29. package/ios/ClusteredYamapLiteView.mm +325 -0
  30. package/ios/ClusteredYamapLiteViewManager.mm +17 -0
  31. package/ios/Components/Circle.swift +108 -0
  32. package/ios/Components/ClusteredYamap.swift +190 -0
  33. package/ios/Components/Marker.swift +187 -0
  34. package/ios/Components/Polygon.swift +108 -0
  35. package/ios/Components/Polyline.swift +125 -0
  36. package/ios/Components/Yamap.swift +585 -0
  37. package/ios/Listeners/CameraListener.swift +54 -0
  38. package/ios/Listeners/ClusterListener.swift +38 -0
  39. package/ios/Listeners/MapInputListener.swift +35 -0
  40. package/ios/Listeners/MapLoadListener.swift +35 -0
  41. package/ios/Listeners/MapObjectTap.swift +12 -0
  42. package/ios/Listeners/UserLocationObjectListener.swift +29 -0
  43. package/ios/Models/YamapModels.swift +77 -0
  44. package/ios/Utils/ImageCache.swift +20 -0
  45. package/ios/Utils/PointsEqual.h +45 -0
  46. package/ios/Utils/ResolveImageHelper.swift +142 -0
  47. package/ios/YamapLiteCircleView.h +15 -0
  48. package/ios/YamapLiteCircleView.mm +102 -0
  49. package/ios/YamapLiteMarkerView.h +15 -0
  50. package/ios/YamapLiteMarkerView.mm +102 -0
  51. package/ios/YamapLitePolygonView.h +15 -0
  52. package/ios/YamapLitePolygonView.mm +120 -0
  53. package/ios/YamapLitePolylineView.h +15 -0
  54. package/ios/YamapLitePolylineView.mm +115 -0
  55. package/ios/YamapLiteView.h +15 -0
  56. package/ios/YamapLiteView.mm +361 -0
  57. package/ios/YamapLiteViewManager.mm +17 -0
  58. package/ios/YamapUtils.h +5 -0
  59. package/ios/YamapUtils.mm +205 -0
  60. package/lib/module/@types/index.js +8 -0
  61. package/lib/module/@types/index.js.map +1 -0
  62. package/lib/module/ClusteredYamapLiteViewNativeComponent.ts +98 -0
  63. package/lib/module/Components/Circle.js +20 -0
  64. package/lib/module/Components/Circle.js.map +1 -0
  65. package/lib/module/Components/ClusteredYamap.js +133 -0
  66. package/lib/module/Components/ClusteredYamap.js.map +1 -0
  67. package/lib/module/Components/Marker.js +40 -0
  68. package/lib/module/Components/Marker.js.map +1 -0
  69. package/lib/module/Components/Polygon.js +25 -0
  70. package/lib/module/Components/Polygon.js.map +1 -0
  71. package/lib/module/Components/Polyline.js +25 -0
  72. package/lib/module/Components/Polyline.js.map +1 -0
  73. package/lib/module/Components/Yamap.js +124 -0
  74. package/lib/module/Components/Yamap.js.map +1 -0
  75. package/lib/module/Components/index.js +9 -0
  76. package/lib/module/Components/index.js.map +1 -0
  77. package/lib/module/NativeYamapUtils.js +5 -0
  78. package/lib/module/NativeYamapUtils.js.map +1 -0
  79. package/lib/module/Utils/YamapUtils.js +14 -0
  80. package/lib/module/Utils/YamapUtils.js.map +1 -0
  81. package/lib/module/YamapCircleViewNativeComponent.ts +28 -0
  82. package/lib/module/YamapLiteViewNativeComponent.ts +93 -0
  83. package/lib/module/YamapMarkerViewNativeComponent.ts +32 -0
  84. package/lib/module/YamapPolygonViewNativeComponent.ts +28 -0
  85. package/lib/module/YamapPolylineViewNativeComponent.ts +31 -0
  86. package/lib/module/index.js +7 -0
  87. package/lib/module/index.js.map +1 -0
  88. package/lib/module/package.json +1 -0
  89. package/lib/typescript/package.json +1 -0
  90. package/lib/typescript/src/@types/index.d.ts +257 -0
  91. package/lib/typescript/src/@types/index.d.ts.map +1 -0
  92. package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts +82 -0
  93. package/lib/typescript/src/ClusteredYamapLiteViewNativeComponent.d.ts.map +1 -0
  94. package/lib/typescript/src/Components/Circle.d.ts +4 -0
  95. package/lib/typescript/src/Components/Circle.d.ts.map +1 -0
  96. package/lib/typescript/src/Components/ClusteredYamap.d.ts +3 -0
  97. package/lib/typescript/src/Components/ClusteredYamap.d.ts.map +1 -0
  98. package/lib/typescript/src/Components/Marker.d.ts +3 -0
  99. package/lib/typescript/src/Components/Marker.d.ts.map +1 -0
  100. package/lib/typescript/src/Components/Polygon.d.ts +4 -0
  101. package/lib/typescript/src/Components/Polygon.d.ts.map +1 -0
  102. package/lib/typescript/src/Components/Polyline.d.ts +4 -0
  103. package/lib/typescript/src/Components/Polyline.d.ts.map +1 -0
  104. package/lib/typescript/src/Components/Yamap.d.ts +3 -0
  105. package/lib/typescript/src/Components/Yamap.d.ts.map +1 -0
  106. package/lib/typescript/src/Components/index.d.ts +7 -0
  107. package/lib/typescript/src/Components/index.d.ts.map +1 -0
  108. package/lib/typescript/src/NativeYamapUtils.d.ts +30 -0
  109. package/lib/typescript/src/NativeYamapUtils.d.ts.map +1 -0
  110. package/lib/typescript/src/Utils/YamapUtils.d.ts +27 -0
  111. package/lib/typescript/src/Utils/YamapUtils.d.ts.map +1 -0
  112. package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts +20 -0
  113. package/lib/typescript/src/YamapCircleViewNativeComponent.d.ts.map +1 -0
  114. package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts +80 -0
  115. package/lib/typescript/src/YamapLiteViewNativeComponent.d.ts.map +1 -0
  116. package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts +25 -0
  117. package/lib/typescript/src/YamapMarkerViewNativeComponent.d.ts.map +1 -0
  118. package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts +20 -0
  119. package/lib/typescript/src/YamapPolygonViewNativeComponent.d.ts.map +1 -0
  120. package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts +23 -0
  121. package/lib/typescript/src/YamapPolylineViewNativeComponent.d.ts.map +1 -0
  122. package/lib/typescript/src/index.d.ts +5 -0
  123. package/lib/typescript/src/index.d.ts.map +1 -0
  124. package/package.json +189 -0
  125. package/src/@types/index.ts +314 -0
  126. package/src/ClusteredYamapLiteViewNativeComponent.ts +98 -0
  127. package/src/Components/Circle.tsx +22 -0
  128. package/src/Components/ClusteredYamap.tsx +194 -0
  129. package/src/Components/Marker.tsx +50 -0
  130. package/src/Components/Polygon.tsx +27 -0
  131. package/src/Components/Polyline.tsx +27 -0
  132. package/src/Components/Yamap.tsx +176 -0
  133. package/src/Components/index.ts +6 -0
  134. package/src/NativeYamapUtils.ts +47 -0
  135. package/src/Utils/YamapUtils.ts +63 -0
  136. package/src/YamapCircleViewNativeComponent.ts +28 -0
  137. package/src/YamapLiteViewNativeComponent.ts +93 -0
  138. package/src/YamapMarkerViewNativeComponent.ts +32 -0
  139. package/src/YamapPolygonViewNativeComponent.ts +28 -0
  140. package/src/YamapPolylineViewNativeComponent.ts +31 -0
  141. package/src/index.tsx +5 -0
@@ -0,0 +1,34 @@
1
+ package com.yamaplite.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+ import com.yandex.mapkit.map.MapLoadStatistics
7
+
8
+ class MapLoadEvent(
9
+ surfaceId: Int,
10
+ viewTag: Int,
11
+ private val statistics: MapLoadStatistics,
12
+ ) : Event<MapLoadEvent>(surfaceId, viewTag) {
13
+
14
+ override fun getEventName(): String = EVENT_NAME
15
+
16
+ override fun getEventData(): WritableMap =
17
+ Arguments.createMap().apply {
18
+ putInt("renderObjectCount", statistics.renderObjectCount)
19
+ putDouble("curZoomModelsLoaded", statistics.curZoomModelsLoaded.toDouble())
20
+ putDouble("curZoomPlacemarksLoaded", statistics.curZoomPlacemarksLoaded.toDouble())
21
+ putDouble("curZoomLabelsLoaded", statistics.curZoomLabelsLoaded.toDouble())
22
+ putDouble("curZoomGeometryLoaded", statistics.curZoomGeometryLoaded.toDouble())
23
+ putDouble("tileMemoryUsage", statistics.tileMemoryUsage.toDouble())
24
+ putDouble("delayedGeometryLoaded", statistics.delayedGeometryLoaded.toDouble())
25
+ putDouble("fullyAppeared", statistics.fullyAppeared.toDouble())
26
+ putDouble("fullyLoaded", statistics.fullyLoaded.toDouble())
27
+ }
28
+
29
+ override fun getCoalescingKey(): Short = 0
30
+
31
+ companion object {
32
+ const val EVENT_NAME = "onMapLoaded"
33
+ }
34
+ }
@@ -0,0 +1,24 @@
1
+ package com.yamaplite.events
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+ import com.yandex.mapkit.geometry.Point
7
+
8
+ class PressEvent(
9
+ surfaceId: Int,
10
+ viewTag: Int,
11
+ private val eventName: String,
12
+ private val point: Point,
13
+ ) : Event<PressEvent>(surfaceId, viewTag) {
14
+
15
+ override fun getEventName(): String = eventName
16
+
17
+ override fun getEventData(): WritableMap =
18
+ Arguments.createMap().apply {
19
+ putDouble("lat", point.latitude)
20
+ putDouble("lon", point.longitude)
21
+ }
22
+
23
+ override fun getCoalescingKey(): Short = 0
24
+ }
@@ -0,0 +1,45 @@
1
+ package com.yamaplite.utils
2
+
3
+ import android.graphics.Bitmap
4
+ import android.util.LruCache
5
+ import android.util.Log
6
+ import java.lang.Runtime
7
+
8
+ object ImageCache {
9
+
10
+ private val cacheSize = 50 * 1024 * 1024 // 50 МБ в байтах
11
+
12
+ private val memoryCache: LruCache<String, Bitmap> = object : LruCache<String, Bitmap>(cacheSize) {
13
+ override fun sizeOf(key: String, value: Bitmap): Int {
14
+ return value.byteCount // размер в байтах
15
+ }
16
+ }
17
+
18
+ /** Получить Bitmap из кэша по URL */
19
+ fun get(url: String): Bitmap? {
20
+ val bitmap = memoryCache.get(url)
21
+ if (bitmap != null) {
22
+ Log.d("ImageCache", "Cache HIT for: $url (size: ${bitmap.byteCount} bytes)")
23
+ } else {
24
+ Log.d("ImageCache", "Cache MISS for: $url")
25
+ }
26
+ return bitmap
27
+ }
28
+
29
+ /** Положить Bitmap в кэш по URL */
30
+ fun put(url: String, bitmap: Bitmap) {
31
+ val size = bitmap.byteCount
32
+ memoryCache.put(url, bitmap)
33
+ Log.d("ImageCache", "Cached image: $url (size: $size bytes, cache size: ${memoryCache.size()} bytes)")
34
+ }
35
+
36
+ /** Проверка наличия Bitmap в кэше */
37
+ fun contains(url: String): Boolean {
38
+ return memoryCache.get(url) != null
39
+ }
40
+
41
+ /** Очистить весь кэш */
42
+ fun clear() {
43
+ memoryCache.evictAll()
44
+ }
45
+ }
@@ -0,0 +1,39 @@
1
+ package com.yamaplite.utils
2
+
3
+ import com.facebook.react.bridge.ReadableArray
4
+ import com.yandex.mapkit.ScreenPoint
5
+ import com.yandex.mapkit.geometry.Point
6
+
7
+ object PointParser {
8
+
9
+ fun parsePoints(points: ReadableArray?): ArrayList<Point> {
10
+ val result = ArrayList<Point>()
11
+ if (points == null) return result
12
+ for (i in 0 until points.size()) {
13
+ val map = points.getMap(i) ?: continue
14
+ if (!map.hasKey("lat") || !map.hasKey("lon")) continue
15
+ result.add(Point(map.getDouble("lat"), map.getDouble("lon")))
16
+ }
17
+ return result
18
+ }
19
+
20
+ fun parseRings(rings: ReadableArray?): ArrayList<ArrayList<Point>> {
21
+ val result = ArrayList<ArrayList<Point>>()
22
+ if (rings == null) return result
23
+ for (i in 0 until rings.size()) {
24
+ result.add(parsePoints(rings.getArray(i)))
25
+ }
26
+ return result
27
+ }
28
+
29
+ fun parseScreenPoints(points: ReadableArray?): ArrayList<ScreenPoint?> {
30
+ val result = ArrayList<ScreenPoint?>()
31
+ if (points == null) return result
32
+ for (i in 0 until points.size()) {
33
+ val map = points.getMap(i) ?: continue
34
+ if (!map.hasKey("x") || !map.hasKey("y")) continue
35
+ result.add(ScreenPoint(map.getDouble("x").toFloat(), map.getDouble("y").toFloat()))
36
+ }
37
+ return result
38
+ }
39
+ }
@@ -0,0 +1,122 @@
1
+ package com.yamaplite.utils
2
+
3
+ import com.yamaplite.utils.ImageCache
4
+ import com.yandex.runtime.image.ImageProvider
5
+ import android.util.Log
6
+ import android.content.Context
7
+ import android.graphics.Bitmap
8
+ import android.graphics.BitmapFactory
9
+ import okhttp3.OkHttpClient
10
+ import okhttp3.Request
11
+ import okhttp3.Call
12
+ import okhttp3.Response
13
+ import java.io.IOException
14
+ import android.os.Handler
15
+ import android.os.Looper
16
+ import kotlinx.coroutines.suspendCancellableCoroutine
17
+ import kotlinx.coroutines.Dispatchers
18
+ import kotlinx.coroutines.withContext
19
+ import kotlin.coroutines.resume
20
+
21
+
22
+ class ResolveImageHelper {
23
+
24
+ companion object {
25
+ private val httpClient: OkHttpClient by lazy {
26
+ OkHttpClient.Builder()
27
+ .retryOnConnectionFailure(true)
28
+ .build()
29
+ }
30
+
31
+ @Volatile private var instance: ResolveImageHelper? = null
32
+
33
+ fun getInstance(): ResolveImageHelper =
34
+ instance ?: synchronized(this) {
35
+ instance ?: ResolveImageHelper().also { instance = it }
36
+ }
37
+ }
38
+
39
+ suspend fun resolveImage(context: Context, url: String, iconSize: Int): ImageProvider? = withContext(Dispatchers.IO) {
40
+ // 1. Проверка кэша - всегда ресайзим изображение из кэша под нужный размер
41
+ Log.d("ImageLoader", "Checking cache for: $url")
42
+ ImageCache.get(url)?.let { cachedBitmap ->
43
+ Log.d("ImageLoader", "Loaded from cache: $url")
44
+ val resizedBitmap = resizeBitmap(context, cachedBitmap, iconSize) ?: cachedBitmap
45
+ return@withContext ImageProvider.fromBitmap(resizedBitmap)
46
+ }
47
+ Log.d("ImageLoader", "Cache miss, trying other sources for: $url")
48
+
49
+ // 2. Проверяем как ресурс Android (для React Native ассетов в res/drawable-*)
50
+ val resId = context.resources.getIdentifier(url, "drawable", context.packageName)
51
+ if (resId != 0) {
52
+ try {
53
+ val bmp = BitmapFactory.decodeResource(context.resources, resId)
54
+ val resized = resizeBitmap(context, bmp, iconSize)
55
+ ImageCache.put(url, resized ?: bmp)
56
+ Log.d("ImageLoader", "Loaded from resources: $url")
57
+ return@withContext ImageProvider.fromBitmap(resized ?: bmp)
58
+ } catch (e: Exception) {
59
+ Log.e("ImageLoader", "Error loading from resources: $url", e)
60
+ }
61
+ }
62
+
63
+ // 3. HTTP/HTTPS → асинхронно, ждем завершения через suspendCancellableCoroutine
64
+ if (url.startsWith("http://") || url.startsWith("https://")) {
65
+ Log.d("ImageLoader", "Loading from network: $url")
66
+
67
+ return@withContext suspendCancellableCoroutine { continuation ->
68
+ val request = Request.Builder().url(url).build()
69
+ val call = httpClient.newCall(request)
70
+ continuation.invokeOnCancellation { call.cancel() }
71
+ call.enqueue(object : okhttp3.Callback {
72
+ override fun onFailure(call: Call, e: IOException) {
73
+ Log.e("ImageLoader", "Network load failed: $url", e)
74
+ continuation.resume(null)
75
+ }
76
+
77
+ override fun onResponse(call: Call, response: Response) {
78
+ var bitmap: Bitmap? = null
79
+ try {
80
+ response.body?.byteStream()?.use { inputStream ->
81
+ try {
82
+ bitmap = BitmapFactory.decodeStream(inputStream)?.let { resizeBitmap(context, it, iconSize) }
83
+ bitmap?.let { ImageCache.put(url, it) }
84
+ } catch (e: Exception) {
85
+ Log.e("ImageLoader", "Error decoding image: $url", e)
86
+ } finally {
87
+ response.close()
88
+ }
89
+ }
90
+ } catch (e: Exception) {
91
+ Log.e("ImageLoader", "Error processing response: $url", e)
92
+ }
93
+
94
+ val imageProvider = bitmap?.let { ImageProvider.fromBitmap(it) }
95
+ continuation.resume(imageProvider)
96
+ }
97
+ })
98
+ }
99
+ }
100
+
101
+ return@withContext null
102
+ }
103
+
104
+ fun resizeBitmap(context: Context, bitmap: Bitmap?, targetSize: Int): Bitmap? {
105
+ if (bitmap == null || targetSize <= 0) return bitmap
106
+
107
+ // Convert dp to pixels based on screen density
108
+ val density = context.resources.displayMetrics.density
109
+ val targetSizePx = (targetSize * density).toInt()
110
+
111
+ val width = bitmap.width
112
+ val height = bitmap.height
113
+
114
+ if (width == targetSizePx && height == targetSizePx) return bitmap
115
+
116
+ val scale = targetSizePx.toFloat() / width.coerceAtLeast(height).toFloat()
117
+ val scaledWidth = (width * scale).toInt()
118
+ val scaledHeight = (height * scale).toInt()
119
+
120
+ return Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true)
121
+ }
122
+ }
@@ -0,0 +1,169 @@
1
+ package com.yamaplite.utils
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.Promise
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReadableArray
7
+ import com.facebook.react.bridge.UiThreadUtil
8
+ import com.facebook.react.module.annotations.ReactModule
9
+ import com.facebook.react.uimanager.UIManagerHelper
10
+ import com.yamaplite.NativeYamapUtilsSpec
11
+ import com.yamaplite.components.YamapLiteView
12
+ import com.yandex.mapkit.MapKitFactory
13
+ import com.yandex.runtime.i18n.I18nManagerFactory
14
+
15
+ @ReactModule(name = NativeYamapUtilsSpec.NAME)
16
+ class YamapUtils(reactContext: ReactApplicationContext) : NativeYamapUtilsSpec(reactContext) {
17
+
18
+ private fun withView(viewId: Double, promise: Promise, action: (YamapLiteView) -> Unit) {
19
+ UiThreadUtil.runOnUiThread {
20
+ try {
21
+ val uiManager =
22
+ UIManagerHelper.getUIManager(getReactApplicationContext(), viewId.toInt())
23
+ val view = uiManager?.resolveView(viewId.toInt()) as? YamapLiteView
24
+ if (view != null) {
25
+ action(view)
26
+ } else {
27
+ promise.reject("YamapLite", "failed to get view")
28
+ }
29
+ } catch (e: Exception) {
30
+ promise.reject("YamapLite", "failed to resolve view", e)
31
+ }
32
+ }
33
+ }
34
+
35
+ override fun getCameraPosition(viewId: Double, promise: Promise) =
36
+ withView(viewId, promise) { view ->
37
+ val cameraPosition = view.getCameraPosition()
38
+ if (cameraPosition != null) {
39
+ promise.resolve(cameraPosition)
40
+ } else {
41
+ promise.reject("YamapLite", "failed to get camera position")
42
+ }
43
+ }
44
+
45
+ override fun getMapObjectCount(viewId: Double, promise: Promise) =
46
+ withView(viewId, promise) { view ->
47
+ promise.resolve(view.getMapObjectCount().toDouble())
48
+ }
49
+
50
+ override fun getScreenPoints(viewId: Double, points: ReadableArray, promise: Promise) =
51
+ withView(viewId, promise) { view ->
52
+ val screenPoints = view.getScreenPoints(PointParser.parsePoints(points))
53
+ promise.resolve(Arguments.createMap().apply { putArray("points", screenPoints) })
54
+ }
55
+
56
+ override fun getVisibleRegion(viewId: Double, promise: Promise) =
57
+ withView(viewId, promise) { view ->
58
+ val visibleRegion = view.getVisibleRegion()
59
+ if (visibleRegion != null) {
60
+ promise.resolve(visibleRegion)
61
+ } else {
62
+ promise.reject("YamapLite", "failed to get visible region")
63
+ }
64
+ }
65
+
66
+ override fun fitAllMarkers(viewId: Double, promise: Promise) =
67
+ withView(viewId, promise) { view ->
68
+ view.fitAllMarkers()
69
+ promise.resolve(null)
70
+ }
71
+
72
+ override fun setZoom(
73
+ viewId: Double,
74
+ zoom: Double,
75
+ duration: Double,
76
+ animation: String,
77
+ promise: Promise
78
+ ) =
79
+ withView(viewId, promise) { view ->
80
+ view.setZoom(zoom.toFloat(), duration.toInt(), animation)
81
+ promise.resolve(null)
82
+ }
83
+
84
+ override fun setCenter(
85
+ viewId: Double,
86
+ latitude: Double,
87
+ longitude: Double,
88
+ zoom: Double,
89
+ azimuth: Double,
90
+ tilt: Double,
91
+ duration: Double,
92
+ animation: String,
93
+ promise: Promise
94
+ ) =
95
+ withView(viewId, promise) { view ->
96
+ view.setCenter(
97
+ latitude,
98
+ longitude,
99
+ zoom.toFloat(),
100
+ azimuth.toFloat(),
101
+ tilt.toFloat(),
102
+ duration.toInt(),
103
+ animation
104
+ )
105
+ promise.resolve(null)
106
+ }
107
+
108
+ override fun getWorldPoints(viewId: Double, points: ReadableArray, promise: Promise) =
109
+ withView(viewId, promise) { view ->
110
+ val worldPoints = view.getWorldPoints(PointParser.parseScreenPoints(points))
111
+ promise.resolve(Arguments.createMap().apply { putArray("points", worldPoints) })
112
+ }
113
+
114
+ override fun init(apiKey: String, promise: Promise) {
115
+ UiThreadUtil.runOnUiThread {
116
+ try {
117
+ if (!isInitialized) {
118
+ MapKitFactory.setApiKey(apiKey)
119
+ MapKitFactory.initialize(getReactApplicationContext())
120
+ isInitialized = true
121
+ }
122
+ promise.resolve(null)
123
+ } catch (e: Exception) {
124
+ promise.reject("YamapLite", "failed to init MapKit", e)
125
+ }
126
+ }
127
+ }
128
+
129
+ override fun getLocale(promise: Promise) {
130
+ UiThreadUtil.runOnUiThread {
131
+ try {
132
+ val locale = I18nManagerFactory.getLocale()
133
+ if (locale != null) {
134
+ promise.resolve(locale)
135
+ } else {
136
+ promise.reject("YamapLite", "failed to get locale")
137
+ }
138
+ } catch (e: Exception) {
139
+ promise.reject("YamapLite", "failed to get locale", e)
140
+ }
141
+ }
142
+ }
143
+
144
+ override fun setLocale(locale: String, promise: Promise) {
145
+ UiThreadUtil.runOnUiThread {
146
+ try {
147
+ I18nManagerFactory.setLocale(locale)
148
+ promise.resolve(null)
149
+ } catch (e: Exception) {
150
+ promise.reject("YamapLite", "failed to set locale", e)
151
+ }
152
+ }
153
+ }
154
+
155
+ override fun resetLocale(promise: Promise) {
156
+ UiThreadUtil.runOnUiThread {
157
+ try {
158
+ I18nManagerFactory.setLocale(null)
159
+ promise.resolve(null)
160
+ } catch (e: Exception) {
161
+ promise.reject("YamapLite", "failed to reset locale", e)
162
+ }
163
+ }
164
+ }
165
+
166
+ companion object {
167
+ @Volatile private var isInitialized = false
168
+ }
169
+ }
@@ -0,0 +1,67 @@
1
+ package com.yamaplite
2
+
3
+ import android.graphics.Color
4
+ import com.facebook.react.bridge.ReadableMap
5
+ import com.facebook.react.module.annotations.ReactModule
6
+ import com.facebook.react.uimanager.SimpleViewManager
7
+ import com.facebook.react.uimanager.ThemedReactContext
8
+ import com.facebook.react.uimanager.annotations.ReactProp
9
+ import com.facebook.react.viewmanagers.YamapLiteCircleViewManagerInterface
10
+ import com.yamaplite.components.YamapCircle
11
+ import com.yandex.mapkit.geometry.Point
12
+
13
+ @ReactModule(name = YamapLiteCircleViewManager.NAME)
14
+ class YamapLiteCircleViewManager :
15
+ SimpleViewManager<YamapCircle>(), YamapLiteCircleViewManagerInterface<YamapCircle> {
16
+
17
+ override fun getName(): String {
18
+ return NAME
19
+ }
20
+
21
+ override fun createViewInstance(context: ThemedReactContext): YamapCircle {
22
+ return YamapCircle(context)
23
+ }
24
+
25
+ @ReactProp(name = "fillColor")
26
+ override fun setFillColor(view: YamapCircle, color: Int?) {
27
+ view.setFillColor(color ?: Color.BLACK)
28
+ }
29
+
30
+ @ReactProp(name = "strokeColor")
31
+ override fun setStrokeColor(view: YamapCircle, color: Int?) {
32
+ view.setStrokeColor(color ?: Color.BLACK)
33
+ }
34
+
35
+ @ReactProp(name = "strokeWidth", defaultFloat = 1f)
36
+ override fun setStrokeWidth(view: YamapCircle, width: Float) {
37
+ view.setStrokeWidth(width)
38
+ }
39
+
40
+ @ReactProp(name = "zInd", defaultInt = 0)
41
+ override fun setZInd(view: YamapCircle, zInd: Int) {
42
+ view.setZInd(zInd)
43
+ }
44
+
45
+ @ReactProp(name = "center")
46
+ override fun setCenter(view: YamapCircle, center: ReadableMap?) {
47
+ if (center != null) {
48
+ val lat = if (center.hasKey("lat")) center.getDouble("lat") else 0.0
49
+ val lon = if (center.hasKey("lon")) center.getDouble("lon") else 0.0
50
+ view.setCenter(Point(lat, lon))
51
+ }
52
+ }
53
+
54
+ @ReactProp(name = "radius", defaultFloat = 0f)
55
+ override fun setRadius(view: YamapCircle, radius: Float) {
56
+ view.setRadius(radius)
57
+ }
58
+
59
+ @ReactProp(name = "handled", defaultBoolean = false)
60
+ override fun setHandled(view: YamapCircle, handled: Boolean) {
61
+ view.setHandled(handled)
62
+ }
63
+
64
+ companion object {
65
+ const val NAME = "YamapLiteCircleView"
66
+ }
67
+ }
@@ -0,0 +1,82 @@
1
+ package com.yamaplite
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+ import com.facebook.react.uimanager.SimpleViewManager
5
+ import com.facebook.react.uimanager.ThemedReactContext
6
+ import com.facebook.react.uimanager.annotations.ReactProp
7
+ import com.facebook.react.uimanager.ViewManagerDelegate
8
+ import com.facebook.react.viewmanagers.YamapLiteMarkerViewManagerInterface
9
+ import com.facebook.react.viewmanagers.YamapLiteMarkerViewManagerDelegate
10
+ import com.yamaplite.components.YamapLiteMarkerView
11
+
12
+ class YamapLiteMarkerViewManager : SimpleViewManager<YamapLiteMarkerView>(), YamapLiteMarkerViewManagerInterface<YamapLiteMarkerView> {
13
+ private val mDelegate: ViewManagerDelegate<YamapLiteMarkerView>
14
+
15
+ init {
16
+ mDelegate = YamapLiteMarkerViewManagerDelegate(this)
17
+ }
18
+
19
+ override fun getDelegate(): ViewManagerDelegate<YamapLiteMarkerView> = mDelegate
20
+
21
+ override fun getName(): String = "YamapLiteMarkerView"
22
+
23
+ override fun createViewInstance(context: ThemedReactContext): YamapLiteMarkerView {
24
+ return YamapLiteMarkerView(context)
25
+ }
26
+
27
+ override fun onDropViewInstance(view: YamapLiteMarkerView) {
28
+ view.onDrop()
29
+ super.onDropViewInstance(view)
30
+ }
31
+
32
+ @ReactProp(name = "point")
33
+ override fun setPoint(view: YamapLiteMarkerView, value: ReadableMap?) {
34
+ if (value == null) return
35
+ val lat = if (value.hasKey("lat")) value.getDouble("lat") else 0.0
36
+ val lon = if (value.hasKey("lon")) value.getDouble("lon") else 0.0
37
+ view.setPoint(lat, lon)
38
+ }
39
+
40
+ @ReactProp(name = "source")
41
+ override fun setSource(view: YamapLiteMarkerView, value: String?) {
42
+ view.setIconSource(value)
43
+ }
44
+
45
+ @ReactProp(name = "scale")
46
+ override fun setScale(view: YamapLiteMarkerView, value: Double) {
47
+ view.setScale(value)
48
+ }
49
+
50
+ @ReactProp(name = "zInd")
51
+ override fun setZInd(view: YamapLiteMarkerView, value: Int) {
52
+ view.setZInd(value)
53
+ }
54
+
55
+ @ReactProp(name = "visible")
56
+ override fun setVisible(view: YamapLiteMarkerView, value: Boolean) {
57
+ view.setVisible(value)
58
+ }
59
+
60
+ @ReactProp(name = "anchor")
61
+ override fun setAnchor(view: YamapLiteMarkerView, value: ReadableMap?) {
62
+ if (value == null) return
63
+ val x = if (value.hasKey("x")) value.getDouble("x") else 0.5
64
+ val y = if (value.hasKey("y")) value.getDouble("y") else 0.5
65
+ view.setAnchor(x, y)
66
+ }
67
+
68
+ @ReactProp(name = "rotated")
69
+ override fun setRotated(view: YamapLiteMarkerView, value: Boolean) {
70
+ view.setRotated(value)
71
+ }
72
+
73
+ @ReactProp(name = "handled")
74
+ override fun setHandled(view: YamapLiteMarkerView, value: Boolean) {
75
+ view.setHandled(value)
76
+ }
77
+
78
+ @ReactProp(name = "size")
79
+ override fun setSize(view: YamapLiteMarkerView, size: Int) {
80
+ view.setSize(size)
81
+ }
82
+ }
@@ -0,0 +1,41 @@
1
+ package com.yamaplite
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+ import com.facebook.react.uimanager.ViewManager
9
+ import com.yamaplite.utils.YamapUtils
10
+
11
+ class YamapLiteViewPackage : BaseReactPackage() {
12
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =
13
+ when (name) {
14
+ NativeYamapUtilsSpec.NAME -> YamapUtils(reactContext)
15
+ else -> null
16
+ }
17
+
18
+ override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
19
+ mapOf(
20
+ NativeYamapUtilsSpec.NAME to
21
+ ReactModuleInfo(
22
+ NativeYamapUtilsSpec.NAME,
23
+ NativeYamapUtilsSpec.NAME,
24
+ false,
25
+ false,
26
+ false,
27
+ true
28
+ )
29
+ )
30
+ }
31
+
32
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> =
33
+ listOf<ViewManager<*, *>>(
34
+ YamapLiteViewManager(),
35
+ YamapLiteMarkerViewManager(),
36
+ YamapLiteCircleViewManager(),
37
+ YamapLitePolylineViewManager(),
38
+ YamapLitePolygonViewManager(),
39
+ ClusteredYamapLiteViewManager()
40
+ )
41
+ }
@@ -0,0 +1,61 @@
1
+ package com.yamaplite
2
+
3
+ import android.graphics.Color
4
+ import com.facebook.react.bridge.ReadableArray
5
+ import com.facebook.react.uimanager.SimpleViewManager
6
+ import com.facebook.react.uimanager.ThemedReactContext
7
+ import com.facebook.react.uimanager.annotations.ReactProp
8
+ import com.facebook.react.viewmanagers.YamapLitePolygonViewManagerInterface
9
+ import com.yamaplite.components.YamapPolygon
10
+ import com.yamaplite.utils.PointParser
11
+
12
+ class YamapLitePolygonViewManager :
13
+ SimpleViewManager<YamapPolygon>(), YamapLitePolygonViewManagerInterface<YamapPolygon> {
14
+
15
+ override fun getName(): String {
16
+ return NAME
17
+ }
18
+
19
+ override fun createViewInstance(context: ThemedReactContext): YamapPolygon {
20
+ return YamapPolygon(context)
21
+ }
22
+
23
+ @ReactProp(name = "fillColor")
24
+ override fun setFillColor(view: YamapPolygon, color: Int?) {
25
+ view.setFillColor(color ?: Color.BLACK)
26
+ }
27
+
28
+ @ReactProp(name = "strokeColor")
29
+ override fun setStrokeColor(view: YamapPolygon, color: Int?) {
30
+ view.setStrokeColor(color ?: Color.BLACK)
31
+ }
32
+
33
+ @ReactProp(name = "strokeWidth")
34
+ override fun setStrokeWidth(view: YamapPolygon, width: Float) {
35
+ view.setStrokeWidth(width)
36
+ }
37
+
38
+ @ReactProp(name = "zInd")
39
+ override fun setZInd(view: YamapPolygon, zIndex: Int) {
40
+ view.setZIndex(zIndex.toFloat())
41
+ }
42
+
43
+ @ReactProp(name = "points")
44
+ override fun setPoints(view: YamapPolygon, points: ReadableArray?) {
45
+ view.setPoints(PointParser.parsePoints(points))
46
+ }
47
+
48
+ @ReactProp(name = "innerRings")
49
+ override fun setInnerRings(view: YamapPolygon, innerRings: ReadableArray?) {
50
+ view.setInnerRings(PointParser.parseRings(innerRings))
51
+ }
52
+
53
+ @ReactProp(name = "handled")
54
+ override fun setHandled(view: YamapPolygon, handled: Boolean) {
55
+ view.setHandled(handled)
56
+ }
57
+
58
+ companion object {
59
+ const val NAME = "YamapLitePolygonView"
60
+ }
61
+ }