@react-native-kakao/map 2.2.7 → 3.1.0-next.2

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 (165) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +5 -38
  3. package/RNCKakaoMap.podspec +16 -52
  4. package/android/build.gradle +12 -107
  5. package/android/consumer-rules.pro +2 -0
  6. package/android/src/main/AndroidManifest.xml +3 -1
  7. package/android/src/main/java/net/mjstudio/rnkakao/map/CameraOptions.kt +61 -0
  8. package/android/src/main/java/net/mjstudio/rnkakao/map/KakaoMapModule.kt +131 -0
  9. package/android/src/main/java/net/mjstudio/rnkakao/map/KakaoMapView.kt +1257 -0
  10. package/android/src/main/java/net/mjstudio/rnkakao/map/MapCameraCommands.kt +306 -0
  11. package/android/src/main/java/net/mjstudio/rnkakao/map/MapDimScreen.kt +431 -0
  12. package/android/src/main/java/net/mjstudio/rnkakao/map/MapGui.kt +899 -0
  13. package/android/src/main/java/net/mjstudio/rnkakao/map/MapImageLoader.kt +232 -0
  14. package/android/src/main/java/net/mjstudio/rnkakao/map/MapLabels.kt +1572 -0
  15. package/android/src/main/java/net/mjstudio/rnkakao/map/MapOptions.kt +360 -0
  16. package/android/src/main/java/net/mjstudio/rnkakao/map/MapRoutes.kt +805 -0
  17. package/android/src/main/java/net/mjstudio/rnkakao/map/MapShapes.kt +1096 -0
  18. package/android/src/main/java/net/mjstudio/rnkakao/map/MapUtilities.kt +495 -0
  19. package/expo-module.config.json +5 -0
  20. package/ios/CameraOptions.swift +41 -0
  21. package/ios/KakaoMapModule.swift +204 -0
  22. package/ios/KakaoMapView.swift +1018 -0
  23. package/ios/MapCameraCommands.swift +451 -0
  24. package/ios/MapDimScreen.swift +463 -0
  25. package/ios/MapGui.swift +1099 -0
  26. package/ios/MapImageLoader.swift +177 -0
  27. package/ios/MapLabels.swift +1676 -0
  28. package/ios/MapOptions.swift +374 -0
  29. package/ios/MapRoutes.swift +903 -0
  30. package/ios/MapShapes.swift +1294 -0
  31. package/ios/MapUnits.swift +20 -0
  32. package/ios/MapUtilities.swift +365 -0
  33. package/lib/commonjs/index.js +180 -29
  34. package/lib/commonjs/index.js.map +1 -1
  35. package/lib/commonjs/index.web.js +18 -0
  36. package/lib/commonjs/index.web.js.map +1 -0
  37. package/lib/commonjs/package.json +1 -0
  38. package/lib/commonjs/types-assets.js +2 -0
  39. package/lib/commonjs/types-assets.js.map +1 -0
  40. package/lib/commonjs/types-camera.js +6 -0
  41. package/lib/commonjs/types-camera.js.map +1 -0
  42. package/lib/commonjs/types-dim.js +6 -0
  43. package/lib/commonjs/types-dim.js.map +1 -0
  44. package/lib/commonjs/types-gui.js +6 -0
  45. package/lib/commonjs/types-gui.js.map +1 -0
  46. package/lib/commonjs/types-labels.js +6 -0
  47. package/lib/commonjs/types-labels.js.map +1 -0
  48. package/lib/commonjs/types-routes.js +6 -0
  49. package/lib/commonjs/types-routes.js.map +1 -0
  50. package/lib/commonjs/types-shapes.js +6 -0
  51. package/lib/commonjs/types-shapes.js.map +1 -0
  52. package/lib/commonjs/types-utilities.js +6 -0
  53. package/lib/commonjs/types-utilities.js.map +1 -0
  54. package/lib/commonjs/types.js +6 -0
  55. package/lib/commonjs/types.js.map +1 -0
  56. package/lib/module/index.js +180 -22
  57. package/lib/module/index.js.map +1 -1
  58. package/lib/module/index.web.js +13 -0
  59. package/lib/module/index.web.js.map +1 -0
  60. package/lib/module/types-assets.js +2 -0
  61. package/lib/module/types-assets.js.map +1 -0
  62. package/lib/module/types-camera.js +4 -0
  63. package/lib/module/types-camera.js.map +1 -0
  64. package/lib/module/types-dim.js +4 -0
  65. package/lib/module/types-dim.js.map +1 -0
  66. package/lib/module/types-gui.js +4 -0
  67. package/lib/module/types-gui.js.map +1 -0
  68. package/lib/module/types-labels.js +4 -0
  69. package/lib/module/types-labels.js.map +1 -0
  70. package/lib/module/types-routes.js +4 -0
  71. package/lib/module/types-routes.js.map +1 -0
  72. package/lib/module/types-shapes.js +4 -0
  73. package/lib/module/types-shapes.js.map +1 -0
  74. package/lib/module/types-utilities.js +4 -0
  75. package/lib/module/types-utilities.js.map +1 -0
  76. package/lib/module/types.js +4 -0
  77. package/lib/module/types.js.map +1 -0
  78. package/lib/typescript/src/index.d.ts +59 -9
  79. package/lib/typescript/src/index.d.ts.map +1 -1
  80. package/lib/typescript/src/types-assets.d.ts +9 -0
  81. package/lib/typescript/src/types-assets.d.ts.map +1 -0
  82. package/lib/typescript/src/types-camera.d.ts +123 -0
  83. package/lib/typescript/src/types-camera.d.ts.map +1 -0
  84. package/lib/typescript/src/types-dim.d.ts +54 -0
  85. package/lib/typescript/src/types-dim.d.ts.map +1 -0
  86. package/lib/typescript/src/types-gui.d.ts +189 -0
  87. package/lib/typescript/src/types-gui.d.ts.map +1 -0
  88. package/lib/typescript/src/types-labels.d.ts +246 -0
  89. package/lib/typescript/src/types-labels.d.ts.map +1 -0
  90. package/lib/typescript/src/types-routes.d.ts +162 -0
  91. package/lib/typescript/src/types-routes.d.ts.map +1 -0
  92. package/lib/typescript/src/types-shapes.d.ts +253 -0
  93. package/lib/typescript/src/types-shapes.d.ts.map +1 -0
  94. package/lib/typescript/src/types-utilities.d.ts +130 -0
  95. package/lib/typescript/src/types-utilities.d.ts.map +1 -0
  96. package/lib/typescript/src/types.d.ts +222 -0
  97. package/lib/typescript/src/types.d.ts.map +1 -0
  98. package/package.json +24 -77
  99. package/src/index.tsx +322 -0
  100. package/src/index.web.tsx +46 -0
  101. package/src/types-assets.ts +8 -0
  102. package/src/types-camera.ts +97 -0
  103. package/src/types-dim.ts +54 -0
  104. package/src/types-gui.ts +171 -0
  105. package/src/types-labels.ts +207 -0
  106. package/src/types-routes.ts +118 -0
  107. package/src/types-shapes.ts +244 -0
  108. package/src/types-utilities.ts +115 -0
  109. package/src/types.ts +223 -0
  110. package/android/gradle.properties +0 -1
  111. package/android/src/main/AndroidManifestNew.xml +0 -2
  112. package/android/src/main/java/net/mjstudio/rnkakao/map/RNCKakaoMapModule.kt +0 -25
  113. package/android/src/main/java/net/mjstudio/rnkakao/map/RNCKakaoMapPackage.kt +0 -35
  114. package/android/src/newarch/KakaoMapSpec.kt +0 -7
  115. package/android/src/oldarch/KakaoMapSpec.kt +0 -14
  116. package/ios/Component/Map/RNCKakaoMapView.h +0 -23
  117. package/ios/Component/Map/RNCKakaoMapView.mm +0 -209
  118. package/ios/Component/Map/RNCKakaoMapViewManager.mm +0 -19
  119. package/ios/NativeModule/RNCKakaoMap.h +0 -7
  120. package/ios/NativeModule/RNCKakaoMap.mm +0 -19
  121. package/ios/NativeModule/RNCKakaoMapManager.swift +0 -7
  122. package/ios/Util/Util.h +0 -97
  123. package/lib/commonjs/component/KakaoMapView.js +0 -54
  124. package/lib/commonjs/component/KakaoMapView.js.map +0 -1
  125. package/lib/commonjs/spec/NativeKakaoMap.js +0 -9
  126. package/lib/commonjs/spec/NativeKakaoMap.js.map +0 -1
  127. package/lib/commonjs/spec/RNCKakaoMapViewNativeComponent.js +0 -15
  128. package/lib/commonjs/spec/RNCKakaoMapViewNativeComponent.js.map +0 -1
  129. package/lib/commonjs/type/type.js +0 -2
  130. package/lib/commonjs/type/type.js.map +0 -1
  131. package/lib/commonjs/util/Const.js +0 -14
  132. package/lib/commonjs/util/Const.js.map +0 -1
  133. package/lib/commonjs/util/Util.js +0 -15
  134. package/lib/commonjs/util/Util.js.map +0 -1
  135. package/lib/module/component/KakaoMapView.js +0 -48
  136. package/lib/module/component/KakaoMapView.js.map +0 -1
  137. package/lib/module/spec/NativeKakaoMap.js +0 -3
  138. package/lib/module/spec/NativeKakaoMap.js.map +0 -1
  139. package/lib/module/spec/RNCKakaoMapViewNativeComponent.js +0 -10
  140. package/lib/module/spec/RNCKakaoMapViewNativeComponent.js.map +0 -1
  141. package/lib/module/type/type.js +0 -2
  142. package/lib/module/type/type.js.map +0 -1
  143. package/lib/module/util/Const.js +0 -8
  144. package/lib/module/util/Const.js.map +0 -1
  145. package/lib/module/util/Util.js +0 -9
  146. package/lib/module/util/Util.js.map +0 -1
  147. package/lib/typescript/src/component/KakaoMapView.d.ts +0 -25
  148. package/lib/typescript/src/component/KakaoMapView.d.ts.map +0 -1
  149. package/lib/typescript/src/spec/NativeKakaoMap.d.ts +0 -7
  150. package/lib/typescript/src/spec/NativeKakaoMap.d.ts.map +0 -1
  151. package/lib/typescript/src/spec/RNCKakaoMapViewNativeComponent.d.ts +0 -32
  152. package/lib/typescript/src/spec/RNCKakaoMapViewNativeComponent.d.ts.map +0 -1
  153. package/lib/typescript/src/type/type.d.ts +0 -8
  154. package/lib/typescript/src/type/type.d.ts.map +0 -1
  155. package/lib/typescript/src/util/Const.d.ts +0 -8
  156. package/lib/typescript/src/util/Const.d.ts.map +0 -1
  157. package/lib/typescript/src/util/Util.d.ts +0 -3
  158. package/lib/typescript/src/util/Util.d.ts.map +0 -1
  159. package/src/component/KakaoMapView.tsx +0 -82
  160. package/src/index.ts +0 -43
  161. package/src/spec/NativeKakaoMap.ts +0 -8
  162. package/src/spec/RNCKakaoMapViewNativeComponent.ts +0 -38
  163. package/src/type/type.ts +0 -7
  164. package/src/util/Const.ts +0 -7
  165. package/src/util/Util.ts +0 -11
@@ -0,0 +1,232 @@
1
+ package net.mjstudio.rnkakao.map
2
+
3
+ import android.graphics.Bitmap
4
+ import android.graphics.Canvas
5
+ import android.net.Uri
6
+ import android.os.Handler
7
+ import android.os.Looper
8
+ import android.util.LruCache
9
+ import com.facebook.common.executors.CallerThreadExecutor
10
+ import com.facebook.common.references.CloseableReference
11
+ import com.facebook.datasource.BaseDataSubscriber
12
+ import com.facebook.datasource.DataSource
13
+ import com.facebook.drawee.backends.pipeline.Fresco
14
+ import com.facebook.imagepipeline.common.RotationOptions
15
+ import com.facebook.imagepipeline.image.CloseableBitmap
16
+ import com.facebook.imagepipeline.image.CloseableImage
17
+ import com.facebook.imagepipeline.request.ImageRequestBuilder
18
+ import com.facebook.react.views.imagehelper.ImageSource
19
+ import expo.modules.kotlin.AppContext
20
+ import expo.modules.kotlin.exception.CodedException
21
+ import java.lang.ref.WeakReference
22
+ import java.util.concurrent.ConcurrentHashMap
23
+ import java.util.concurrent.atomic.AtomicBoolean
24
+
25
+ private const val MAP_IMAGE_LOAD_ERROR = "ERR_KAKAO_MAP_IMAGE_LOAD"
26
+ private const val MAP_IMAGE_CACHE_KILOBYTES = 16 * 1_024
27
+ private val supportedMapImageSchemes = setOf("asset", "content", "data", "file", "http", "https")
28
+
29
+ internal class MapImageLoadException(
30
+ message: String,
31
+ cause: Throwable? = null,
32
+ ) : CodedException(MAP_IMAGE_LOAD_ERROR, message, cause)
33
+
34
+ internal class MapImageLoadToken internal constructor(
35
+ private val cancellation: () -> Unit,
36
+ ) {
37
+ private val isFinished = AtomicBoolean(false)
38
+
39
+ fun cancel() {
40
+ if (isFinished.compareAndSet(false, true)) cancellation()
41
+ }
42
+
43
+ internal fun finish() = isFinished.compareAndSet(false, true)
44
+ }
45
+
46
+ internal class MapImageLoader(
47
+ appContext: AppContext,
48
+ ) {
49
+ private data class Request(
50
+ val completion: (Result<Bitmap>) -> Unit,
51
+ var source: DataSource<CloseableReference<CloseableImage>>? = null,
52
+ )
53
+
54
+ private val reactContext = appContext.reactContext?.let(::WeakReference)
55
+ private val mainHandler = Handler(Looper.getMainLooper())
56
+ private val requests = ConcurrentHashMap<MapImageLoadToken, Request>()
57
+ private val cache =
58
+ object : LruCache<String, Bitmap>(MAP_IMAGE_CACHE_KILOBYTES) {
59
+ override fun sizeOf(
60
+ key: String,
61
+ value: Bitmap,
62
+ ) = (value.byteCount / 1_024).coerceAtLeast(1)
63
+ }
64
+ private val isDisposed = AtomicBoolean(false)
65
+
66
+ fun load(
67
+ uri: String,
68
+ completion: (Result<Bitmap>) -> Unit,
69
+ ): MapImageLoadToken {
70
+ check(Looper.myLooper() == Looper.getMainLooper()) { "Map images must be requested on the main thread." }
71
+ lateinit var token: MapImageLoadToken
72
+ val loaderReference = WeakReference(this)
73
+ token = MapImageLoadToken { loaderReference.get()?.cancel(token) }
74
+ if (isDisposed.get()) {
75
+ mainHandler.post {
76
+ if (token.finish()) completion(Result.failure(MapImageLoadException("The map image loader was destroyed.")))
77
+ }
78
+ return token
79
+ }
80
+ val request = Request(completion)
81
+ requests[token] = request
82
+
83
+ val resolvedUri =
84
+ try {
85
+ resolveUri(uri)
86
+ } catch (error: MapImageLoadException) {
87
+ mainHandler.post { finish(token, Result.failure(error)) }
88
+ return token
89
+ }
90
+ cache.get(resolvedUri)?.let { image ->
91
+ mainHandler.post { finish(token, Result.success(image)) }
92
+ return token
93
+ }
94
+ val source =
95
+ try {
96
+ val imageRequest =
97
+ ImageRequestBuilder
98
+ .newBuilderWithSource(Uri.parse(resolvedUri))
99
+ .setRotationOptions(RotationOptions.autoRotate())
100
+ .build()
101
+ Fresco.getImagePipeline().fetchDecodedImage(imageRequest, this)
102
+ } catch (error: Exception) {
103
+ mainHandler.post {
104
+ finish(
105
+ token,
106
+ Result.failure(MapImageLoadException(error.message ?: "Could not load the map image.", error)),
107
+ )
108
+ }
109
+ return token
110
+ }
111
+ request.source = source
112
+ try {
113
+ source.subscribe(
114
+ object : BaseDataSubscriber<CloseableReference<CloseableImage>>() {
115
+ override fun onNewResultImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
116
+ if (!dataSource.isFinished) return
117
+ val imageReference = dataSource.result
118
+ if (imageReference == null) {
119
+ mainHandler.post {
120
+ finish(token, Result.failure(MapImageLoadException("Could not decode the map image.")))
121
+ }
122
+ return
123
+ }
124
+ val result =
125
+ try {
126
+ val image =
127
+ imageReference.get() as? CloseableBitmap
128
+ ?: throw MapImageLoadException("Could not decode the map image as a bitmap.")
129
+ val sourceBitmap =
130
+ image.underlyingBitmap
131
+ ?: throw MapImageLoadException("The decoded map image does not contain a bitmap.")
132
+ Result.success(copyBitmap(sourceBitmap))
133
+ } catch (error: Exception) {
134
+ Result.failure(
135
+ if (error is MapImageLoadException) {
136
+ error
137
+ } else {
138
+ MapImageLoadException(error.message ?: "Could not decode the map image.", error)
139
+ },
140
+ )
141
+ } finally {
142
+ CloseableReference.closeSafely(imageReference)
143
+ }
144
+ mainHandler.post { finish(token, result, resolvedUri) }
145
+ }
146
+
147
+ override fun onFailureImpl(dataSource: DataSource<CloseableReference<CloseableImage>>) {
148
+ val error = dataSource.failureCause
149
+ mainHandler.post {
150
+ finish(
151
+ token,
152
+ Result.failure(MapImageLoadException(error?.message ?: "Could not load the map image.", error)),
153
+ )
154
+ }
155
+ }
156
+
157
+ override fun onCancellation(dataSource: DataSource<CloseableReference<CloseableImage>>) {
158
+ mainHandler.post {
159
+ finish(token, Result.failure(MapImageLoadException("The map image load was cancelled.")))
160
+ }
161
+ }
162
+ },
163
+ CallerThreadExecutor.getInstance(),
164
+ )
165
+ } catch (error: Exception) {
166
+ source.close()
167
+ mainHandler.post {
168
+ finish(
169
+ token,
170
+ Result.failure(MapImageLoadException(error.message ?: "Could not schedule the map image load.", error)),
171
+ )
172
+ }
173
+ }
174
+ return token
175
+ }
176
+
177
+ private fun copyBitmap(source: Bitmap): Bitmap {
178
+ val copy = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
179
+ copy.density = source.density
180
+ Canvas(copy).drawBitmap(source, 0f, 0f, null)
181
+ return copy
182
+ }
183
+
184
+ fun dispose() {
185
+ check(Looper.myLooper() == Looper.getMainLooper()) { "Map images must be disposed on the main thread." }
186
+ if (!isDisposed.compareAndSet(false, true)) return
187
+ requests.keys.toList().forEach(MapImageLoadToken::cancel)
188
+ cache.evictAll()
189
+ }
190
+
191
+ private fun resolveUri(uri: String): String {
192
+ if (isDisposed.get()) throw MapImageLoadException("The map image loader was destroyed.")
193
+ val scheme = Uri.parse(uri).scheme?.lowercase()
194
+ if (scheme != null) {
195
+ if (scheme !in supportedMapImageSchemes) {
196
+ throw MapImageLoadException("Image URI must use a supported scheme.")
197
+ }
198
+ return uri
199
+ }
200
+
201
+ val context =
202
+ reactContext?.get()
203
+ ?: throw MapImageLoadException("The React context is unavailable.")
204
+ val resourceUri = ImageSource(context, uri).uri
205
+ val resourceId =
206
+ resourceUri.path?.removePrefix("/")?.toIntOrNull()
207
+ ?: throw MapImageLoadException("Image URI must use a supported scheme or identify a bundled drawable.")
208
+ val isDrawable =
209
+ runCatching { context.resources.getResourceTypeName(resourceId) == "drawable" }.getOrDefault(false)
210
+ if (resourceUri.scheme != "res" || !isDrawable) {
211
+ throw MapImageLoadException("Image URI must use a supported scheme or identify a bundled drawable.")
212
+ }
213
+ return resourceUri.toString()
214
+ }
215
+
216
+ private fun cancel(token: MapImageLoadToken) {
217
+ val request = requests.remove(token) ?: return
218
+ request.source?.close()
219
+ }
220
+
221
+ private fun finish(
222
+ token: MapImageLoadToken,
223
+ result: Result<Bitmap>,
224
+ cacheUri: String? = null,
225
+ ) {
226
+ if (isDisposed.get()) return
227
+ val request = requests.remove(token) ?: return
228
+ if (!token.finish()) return
229
+ if (cacheUri != null) result.getOrNull()?.let { image -> cache.put(cacheUri, image) }
230
+ request.completion(result)
231
+ }
232
+ }