@kindly-ai/react-native 0.1.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.
Files changed (63) hide show
  1. package/KindlyReactNative.podspec +36 -0
  2. package/LICENSE +20 -0
  3. package/README.md +127 -0
  4. package/android/build.gradle +113 -0
  5. package/android/maven-repo/ai/kindly/sdk/1.0.93/sdk-1.0.93.aar +0 -0
  6. package/android/maven-repo/ai/kindly/sdk/1.0.93/sdk-1.0.93.pom +125 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/java/com/kindlyai/reactnative/KindlyReactNativeModule.kt +445 -0
  9. package/android/src/main/java/com/kindlyai/reactnative/KindlyReactNativePackage.kt +38 -0
  10. package/ios/Frameworks/Kindly.xcframework/Info.plist +44 -0
  11. package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeDirectory +0 -0
  12. package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeRequirements +0 -0
  13. package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  14. package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeResources +578 -0
  15. package/ios/Frameworks/Kindly.xcframework/_CodeSignature/CodeSignature +0 -0
  16. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Assets.car +0 -0
  17. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Config.plist +0 -0
  18. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/ConfirmationWindow.nib +0 -0
  19. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Headers/Kindly-Swift.h +331 -0
  20. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Headers/Kindly.h +18 -0
  21. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Info.plist +0 -0
  22. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Kindly +0 -0
  23. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.abi.json +28769 -0
  24. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.private.swiftinterface +547 -0
  25. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  26. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios.swiftinterface +543 -0
  27. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/Modules/module.modulemap +11 -0
  28. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/PrivacyInfo.xcprivacy +83 -0
  29. package/ios/Frameworks/Kindly.xcframework/ios-arm64/Kindly.framework/_CodeSignature/CodeResources +223 -0
  30. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Assets.car +0 -0
  31. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Config.plist +0 -0
  32. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/ConfirmationWindow.nib +0 -0
  33. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Headers/Kindly-Swift.h +658 -0
  34. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Headers/Kindly.h +18 -0
  35. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Info.plist +0 -0
  36. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Kindly +0 -0
  37. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.abi.json +28769 -0
  38. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +547 -0
  39. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  40. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/arm64-apple-ios-simulator.swiftinterface +543 -0
  41. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.abi.json +28769 -0
  42. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +547 -0
  43. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  44. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/Kindly.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +543 -0
  45. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/Modules/module.modulemap +11 -0
  46. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/PrivacyInfo.xcprivacy +83 -0
  47. package/ios/Frameworks/Kindly.xcframework/ios-arm64_x86_64-simulator/Kindly.framework/_CodeSignature/CodeResources +267 -0
  48. package/ios/KindlyReactNative.h +18 -0
  49. package/ios/KindlyReactNative.mm +234 -0
  50. package/ios/KindlyReactNativeImpl.swift +410 -0
  51. package/lib/module/NativeKindlyReactNative.js +22 -0
  52. package/lib/module/NativeKindlyReactNative.js.map +1 -0
  53. package/lib/module/index.js +280 -0
  54. package/lib/module/index.js.map +1 -0
  55. package/lib/module/package.json +1 -0
  56. package/lib/typescript/package.json +1 -0
  57. package/lib/typescript/src/NativeKindlyReactNative.d.ts +47 -0
  58. package/lib/typescript/src/NativeKindlyReactNative.d.ts.map +1 -0
  59. package/lib/typescript/src/index.d.ts +150 -0
  60. package/lib/typescript/src/index.d.ts.map +1 -0
  61. package/package.json +121 -0
  62. package/src/NativeKindlyReactNative.ts +80 -0
  63. package/src/index.tsx +353 -0
@@ -0,0 +1,445 @@
1
+ package com.kindlyai.reactnative
2
+
3
+ import android.app.Activity
4
+ import android.app.Application
5
+ import android.net.Uri
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.LifecycleEventListener
8
+ import com.facebook.react.bridge.Promise
9
+ import com.facebook.react.bridge.ReactApplicationContext
10
+ import com.facebook.react.bridge.ReadableArray
11
+ import com.facebook.react.bridge.ReadableMap
12
+ import com.facebook.react.bridge.WritableMap
13
+ import com.facebook.react.modules.core.DeviceEventManagerModule
14
+ import com.google.firebase.messaging.RemoteMessage
15
+ import androidx.compose.ui.graphics.Color
16
+ import kotlinx.coroutines.CompletableDeferred
17
+ import kotlinx.coroutines.CoroutineScope
18
+ import kotlinx.coroutines.Dispatchers
19
+ import kotlinx.coroutines.SupervisorJob
20
+ import kotlinx.coroutines.launch
21
+ import kotlinx.coroutines.runBlocking
22
+ import kotlinx.coroutines.withTimeoutOrNull
23
+ import no.kindly.chatsdk.chat.AuthTokenCallback
24
+ import no.kindly.chatsdk.chat.ChatKindlySDK
25
+ import no.kindly.chatsdk.chat.common.CallbackHandover
26
+ import no.kindly.chatsdk.chat.common.KindlySDKInteraction
27
+ import no.kindly.chatsdk.chat.domain.MessageChat
28
+ import no.kindly.chatsdk.chat.domain.entites.ButtonChat
29
+ import no.kindly.chatsdk.chat.domain.entites.ExternalNotification
30
+ import java.util.UUID
31
+ import java.util.concurrent.ConcurrentHashMap
32
+
33
+ /**
34
+ * KindlyReactNativeModule — Kotlin TurboModule that bridges JS calls into
35
+ * the Kindly Android SDK (`ChatKindlySDK`).
36
+ *
37
+ * Symmetric with `flutter-sdk/.../KindlyPlugin.kt`. Major differences from
38
+ * the Flutter version:
39
+ * 1. Extends the codegen-generated `NativeKindlyReactNativeSpec` abstract
40
+ * class (not `MethodCallHandler`) — RN's TurboModule contract.
41
+ * 2. JS→native calls arrive as method invocations on this class; native→JS
42
+ * callbacks fire via `DeviceEventManagerModule.RCTDeviceEventEmitter`.
43
+ * 3. Sync-bool delegate callbacks (`shouldHandleLink`,
44
+ * `shouldHandleNotification`) use a request-id round-trip — native fires
45
+ * an event with a UUID, blocks on a `Map<id, CompletableDeferred>` for
46
+ * up to 5s, JS replies via `respondToShouldHandle(requestId, value)`.
47
+ * Default `true` on timeout — never hang chat UI.
48
+ *
49
+ * The codegen-derived `NativeKindlyReactNativeSpec` class is generated at
50
+ * build time from `src/NativeKindlyReactNative.ts`. Its package is set in
51
+ * `package.json` -> `codegenConfig.android.javaPackageName` to match this
52
+ * file's `package` line.
53
+ */
54
+ class KindlyReactNativeModule(reactContext: ReactApplicationContext) :
55
+ NativeKindlyReactNativeSpec(reactContext), LifecycleEventListener {
56
+
57
+ private val context = reactContext
58
+ private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
59
+
60
+ // Pending request maps for the sync round-trips.
61
+ private val authPending = ConcurrentHashMap<String, CompletableDeferred<String?>>()
62
+ private val shouldHandlePending = ConcurrentHashMap<String, CompletableDeferred<Boolean>>()
63
+
64
+ // Delegate bridge — set on ChatKindlySDK.`interface` when at least one
65
+ // delegate flag is on.
66
+ private var delegateBridge: KindlyDelegateBridge? = null
67
+
68
+ init {
69
+ reactContext.addLifecycleEventListener(this)
70
+ }
71
+
72
+ override fun getName(): String = NAME
73
+
74
+ // Required by the codegen-generated spec for event-emitter accounting.
75
+ override fun addListener(eventName: String) {
76
+ // No-op — RCTDeviceEventEmitter manages itself on Android.
77
+ }
78
+
79
+ override fun removeListeners(count: Double) {
80
+ // No-op
81
+ }
82
+
83
+ override fun onHostResume() {}
84
+ override fun onHostPause() {}
85
+ override fun onHostDestroy() {
86
+ // Best-effort — clear any pending deferreds so the JS side doesn't hang.
87
+ authPending.values.forEach { it.complete(null) }
88
+ authPending.clear()
89
+ shouldHandlePending.values.forEach { it.complete(true) }
90
+ shouldHandlePending.clear()
91
+ }
92
+
93
+ // MARK: - Lifecycle
94
+
95
+ override fun start(botKey: String, languageCode: String?, hasAuthCallback: Boolean) {
96
+ val app = context.applicationContext as? Application
97
+ if (app == null) return
98
+
99
+ val authCallback: AuthTokenCallback? = if (hasAuthCallback) {
100
+ { _: String ->
101
+ val deferred = CompletableDeferred<String>()
102
+ val requestId = UUID.randomUUID().toString()
103
+ val pending = CompletableDeferred<String?>()
104
+ authPending[requestId] = pending
105
+
106
+ emitEvent("KindlyGetAuthToken", Arguments.createMap().apply {
107
+ putString("requestId", requestId)
108
+ })
109
+
110
+ // Fan out to the SDK's deferred — the SDK consumes it on its own thread.
111
+ scope.launch {
112
+ val tok = pending.await()
113
+ if (tok != null) deferred.complete(tok)
114
+ else deferred.completeExceptionally(IllegalStateException("Auth token not provided"))
115
+ }
116
+ deferred
117
+ }
118
+ } else {
119
+ null
120
+ }
121
+
122
+ ChatKindlySDK.start(
123
+ application = app,
124
+ botKey = botKey,
125
+ languageCode = languageCode ?: "en",
126
+ authTokenCallback = authCallback,
127
+ )
128
+ }
129
+
130
+ override fun displayChat(languageCode: String?, triggerDialogueId: String?) {
131
+ val act = currentActivity ?: return
132
+ ChatKindlySDK.displayChat(act)
133
+ if (triggerDialogueId != null) {
134
+ ChatKindlySDK.triggerDialogue(triggerDialogueId)
135
+ }
136
+ }
137
+
138
+ override fun launchChat(triggerDialogueId: String?) {
139
+ val act = currentActivity ?: return
140
+ ChatKindlySDK.launchChat(context = act, triggerDialogueId = triggerDialogueId)
141
+ }
142
+
143
+ override fun closeChat() {
144
+ ChatKindlySDK.close()
145
+ }
146
+
147
+ override fun endChat(promise: Promise) {
148
+ try {
149
+ ChatKindlySDK.endChat()
150
+ promise.resolve(null)
151
+ } catch (e: Throwable) {
152
+ promise.reject("END_CHAT_FAILED", e.message, e)
153
+ }
154
+ }
155
+
156
+ override fun kill(promise: Promise) {
157
+ try {
158
+ ChatKindlySDK.kill()
159
+ promise.resolve(null)
160
+ } catch (e: Throwable) {
161
+ promise.reject("KILL_FAILED", e.message, e)
162
+ }
163
+ }
164
+
165
+ override fun setLanguage(languageCode: String, promise: Promise) {
166
+ try {
167
+ ChatKindlySDK.setLanguage(languageCode)
168
+ promise.resolve(null)
169
+ } catch (e: Throwable) {
170
+ promise.reject("SET_LANGUAGE_FAILED", e.message, e)
171
+ }
172
+ }
173
+
174
+ // MARK: - Messaging
175
+
176
+ override fun sendMessage(message: String, newContext: ReadableMap?, promise: Promise) {
177
+ val ctx = newContext?.toStringMap()
178
+ scope.launch {
179
+ try {
180
+ val msg = ChatKindlySDK.sendMessage(message, ctx).await()
181
+ promise.resolve(serializeMessageChat(msg))
182
+ } catch (e: Throwable) {
183
+ promise.reject("SEND_MESSAGE_FAILED", e.message, e)
184
+ }
185
+ }
186
+ }
187
+
188
+ override fun setNewContext(context: ReadableMap) {
189
+ ChatKindlySDK.setNewContext(context.toStringMap())
190
+ }
191
+
192
+ override fun clearNewContext() {
193
+ ChatKindlySDK.clearNewContext()
194
+ }
195
+
196
+ override fun triggerDialogue(dialogueId: String) {
197
+ ChatKindlySDK.triggerDialogue(dialogueId)
198
+ }
199
+
200
+ override fun clearTriggerDialogue() {
201
+ ChatKindlySDK.clearTriggerDialog()
202
+ }
203
+
204
+ override fun handleUrl(url: String, promise: Promise) {
205
+ val act = currentActivity
206
+ if (act == null) {
207
+ promise.resolve(false)
208
+ return
209
+ }
210
+ promise.resolve(ChatKindlySDK.handleUrl(act, Uri.parse(url)))
211
+ }
212
+
213
+ // MARK: - Theme
214
+
215
+ override fun setCustomTheme(colors: ReadableMap) {
216
+ fun color(key: String): Color? =
217
+ if (colors.hasKey(key) && !colors.isNull(key)) Color(colors.getInt(key)) else null
218
+
219
+ ChatKindlySDK.setCustomTheme(
220
+ background = color("background"),
221
+ botMessageBackground = color("botMessageBackground"),
222
+ botMessageText = color("botMessageText"),
223
+ buttonBackground = color("buttonBackground"),
224
+ buttonOutline = color("buttonOutline"),
225
+ buttonText = color("buttonText"),
226
+ chatLogElements = color("chatLogElements"),
227
+ // Flutter/RN expose navBarBackground / navBarText (iOS naming);
228
+ // Android maps them to headerBackground / headerText.
229
+ headerBackground = color("navBarBackground"),
230
+ headerText = color("navBarText"),
231
+ inputBackground = color("inputBackground"),
232
+ inputText = color("inputText"),
233
+ userMessageBackground = color("userMessageBackground"),
234
+ userMessageText = color("userMessageText"),
235
+ maintenanceHeaderBackground = color("maintenanceHeaderBackground"),
236
+ )
237
+ }
238
+
239
+ override fun clearCustomTheme() {
240
+ ChatKindlySDK.clearCustomTheme()
241
+ }
242
+
243
+ // MARK: - Push
244
+
245
+ override fun setAPNSDeviceToken(token: String) {
246
+ // iOS-only — accept silently.
247
+ }
248
+
249
+ override fun saveNotificationToken(token: String) {
250
+ ChatKindlySDK.saveNotificationToken(token)
251
+ }
252
+
253
+ override fun handleNotification(data: ReadableMap) {
254
+ val rm = mapToRemoteMessage(data) ?: return
255
+ ChatKindlySDK.handleNotification(rm)
256
+ }
257
+
258
+ override fun isKindlyNotification(data: ReadableMap): Boolean {
259
+ val rm = mapToRemoteMessage(data) ?: return false
260
+ return ChatKindlySDK.isKindlyNotification(rm)
261
+ }
262
+
263
+ // MARK: - State / settings
264
+
265
+ override fun saveAuthToken(token: String, promise: Promise) {
266
+ // Android handles auth via AuthTokenCallback; accept symmetrically.
267
+ promise.resolve(true)
268
+ }
269
+
270
+ override fun isChatDisplayed(promise: Promise) {
271
+ // Not exposed by Android EntryPoint — always false (matches Flutter SDK).
272
+ promise.resolve(false)
273
+ }
274
+
275
+ override fun setVerboseLogging(enabled: Boolean) {
276
+ ChatKindlySDK.verboseLogging = enabled
277
+ }
278
+
279
+ override fun setCrashReporting(enabled: Boolean) {
280
+ ChatKindlySDK.enableCrashReporting = enabled
281
+ }
282
+
283
+ // MARK: - Round-trip responders (called by JS)
284
+
285
+ override fun respondToAuthToken(requestId: String, token: String?) {
286
+ authPending.remove(requestId)?.complete(token)
287
+ }
288
+
289
+ override fun respondToShouldHandle(requestId: String, value: Boolean) {
290
+ shouldHandlePending.remove(requestId)?.complete(value)
291
+ }
292
+
293
+ // MARK: - Delegate gating
294
+
295
+ override fun setDelegate(
296
+ onButtonPressed: Boolean,
297
+ shouldHandleLink: Boolean,
298
+ shouldHandleNotification: Boolean,
299
+ onHandover: Boolean,
300
+ ) {
301
+ val bridge = delegateBridge ?: KindlyDelegateBridge(this)
302
+ bridge.hasButtonPressed = onButtonPressed
303
+ bridge.hasShouldHandleLink = shouldHandleLink
304
+ bridge.hasShouldHandleNotification = shouldHandleNotification
305
+ delegateBridge = bridge
306
+
307
+ val anySet = onButtonPressed || shouldHandleLink || shouldHandleNotification
308
+ ChatKindlySDK.`interface` = if (anySet) bridge else null
309
+ }
310
+
311
+ override fun callHandover() {
312
+ val listener = object : CallbackHandover {
313
+ override fun callHandover() {
314
+ emitEvent("KindlyOnHandover", null)
315
+ }
316
+ }
317
+ ChatKindlySDK.callHandover(listener)
318
+ }
319
+
320
+ // MARK: - Event emit helper
321
+
322
+ internal fun emitEvent(name: String, body: WritableMap?) {
323
+ context
324
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
325
+ .emit(name, body)
326
+ }
327
+
328
+ /**
329
+ * Block the calling thread for up to 5s while JS computes a Bool answer.
330
+ * Default `true` on timeout / no-listener — never hang chat UI.
331
+ */
332
+ internal fun blockingShouldHandle(eventName: String, payload: WritableMap): Boolean {
333
+ val requestId = UUID.randomUUID().toString()
334
+ val deferred = CompletableDeferred<Boolean>()
335
+ shouldHandlePending[requestId] = deferred
336
+ payload.putString("requestId", requestId)
337
+ emitEvent(eventName, payload)
338
+ return runBlocking {
339
+ withTimeoutOrNull(5_000) { deferred.await() } ?: run {
340
+ shouldHandlePending.remove(requestId)
341
+ true
342
+ }
343
+ }
344
+ }
345
+
346
+ companion object {
347
+ const val NAME = "KindlyReactNative"
348
+ }
349
+ }
350
+
351
+ // MARK: - Helpers
352
+
353
+ private fun ReadableMap.toStringMap(): Map<String, String> {
354
+ val out = HashMap<String, String>()
355
+ val iter = this.keySetIterator()
356
+ while (iter.hasNextKey()) {
357
+ val k = iter.nextKey()
358
+ val v = this.getString(k) ?: continue
359
+ out[k] = v
360
+ }
361
+ return out
362
+ }
363
+
364
+ private fun serializeMessageChat(msg: MessageChat): WritableMap {
365
+ return Arguments.createMap().apply {
366
+ putString("id", msg.id)
367
+ putString("text", msg.message)
368
+ putString("created", msg.created)
369
+ putString("sender", msg.sender)
370
+ putString("chatId", msg.chatId)
371
+ putBoolean("isMine", msg.isMine)
372
+ putString("exchangeId", msg.exchangeId)
373
+ }
374
+ }
375
+
376
+ private fun serializeButtonChat(button: ButtonChat): WritableMap {
377
+ return Arguments.createMap().apply {
378
+ putString("id", button.id)
379
+ putString("type", button.buttonType)
380
+ putString("label", button.label)
381
+ putString("value", button.value)
382
+ putInt("index", button.index)
383
+ putBoolean("hasBeenSelected", button.clicked)
384
+ putString("languageCode", button.languageCode)
385
+ }
386
+ }
387
+
388
+ private fun serializeExternalNotification(notification: ExternalNotification): WritableMap {
389
+ return Arguments.createMap().apply {
390
+ putString("id", notification.id)
391
+ putString("title", notification.title)
392
+ putString("body", notification.body)
393
+ val data = Arguments.createMap()
394
+ notification.data.forEach { (k, v) -> data.putString(k.toString(), v.toString()) }
395
+ putMap("data", data)
396
+ }
397
+ }
398
+
399
+ private fun mapToRemoteMessage(data: ReadableMap): RemoteMessage? {
400
+ val builder = RemoteMessage.Builder("kindly_rn@gcm.googleapis.com")
401
+ val iter = data.keySetIterator()
402
+ while (iter.hasNextKey()) {
403
+ val k = iter.nextKey()
404
+ val v = data.getString(k) ?: continue
405
+ builder.addData(k, v)
406
+ }
407
+ return builder.build()
408
+ }
409
+
410
+ /**
411
+ * Bridges the Android SDK's `KindlySDKInteraction` interface to the JS-side
412
+ * callbacks registered via `KindlySDK.setDelegate(...)`.
413
+ */
414
+ private class KindlyDelegateBridge(
415
+ private val module: KindlyReactNativeModule,
416
+ ) : KindlySDKInteraction {
417
+ var hasButtonPressed: Boolean = false
418
+ var hasShouldHandleLink: Boolean = false
419
+ var hasShouldHandleNotification: Boolean = false
420
+
421
+ override fun didPressButton(chatButton: ButtonChat, chatLog: List<MessageChat>) {
422
+ if (!hasButtonPressed) return
423
+ val payload = Arguments.createMap().apply {
424
+ putMap("button", serializeButtonChat(chatButton))
425
+ val arr = Arguments.createArray()
426
+ chatLog.forEach { arr.pushMap(serializeMessageChat(it)) }
427
+ putArray("chatLog", arr)
428
+ }
429
+ module.emitEvent("KindlyOnButtonPressed", payload)
430
+ }
431
+
432
+ override fun shouldHandleLink(url: String): Boolean {
433
+ if (!hasShouldHandleLink) return true
434
+ val payload = Arguments.createMap().apply { putString("url", url) }
435
+ return module.blockingShouldHandle("KindlyShouldHandleLink", payload)
436
+ }
437
+
438
+ override fun shouldHandleNotification(notification: ExternalNotification): Boolean {
439
+ if (!hasShouldHandleNotification) return true
440
+ val payload = Arguments.createMap().apply {
441
+ putMap("notification", serializeExternalNotification(notification))
442
+ }
443
+ return module.blockingShouldHandle("KindlyShouldHandleNotification", payload)
444
+ }
445
+ }
@@ -0,0 +1,38 @@
1
+ package com.kindlyai.reactnative
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
+
9
+ /**
10
+ * Auto-linking entry point for the Kindly React Native package.
11
+ *
12
+ * Registered in customer apps automatically via `react-native.config.js`
13
+ * (autolinking) — they don't need to add anything to MainApplication.kt.
14
+ *
15
+ * Returns the single TurboModule we ship: `KindlyReactNativeModule`.
16
+ */
17
+ class KindlyReactNativePackage : BaseReactPackage() {
18
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
19
+ return if (name == KindlyReactNativeModule.NAME) {
20
+ KindlyReactNativeModule(reactContext)
21
+ } else {
22
+ null
23
+ }
24
+ }
25
+
26
+ override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
27
+ mapOf(
28
+ KindlyReactNativeModule.NAME to ReactModuleInfo(
29
+ /* name = */ KindlyReactNativeModule.NAME,
30
+ /* className = */ KindlyReactNativeModule.NAME,
31
+ /* canOverrideExistingModule = */ false,
32
+ /* needsEagerInit = */ false,
33
+ /* isCxxModule = */ false,
34
+ /* isTurboModule = */ true,
35
+ )
36
+ )
37
+ }
38
+ }
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>AvailableLibraries</key>
6
+ <array>
7
+ <dict>
8
+ <key>BinaryPath</key>
9
+ <string>Kindly.framework/Kindly</string>
10
+ <key>LibraryIdentifier</key>
11
+ <string>ios-arm64_x86_64-simulator</string>
12
+ <key>LibraryPath</key>
13
+ <string>Kindly.framework</string>
14
+ <key>SupportedArchitectures</key>
15
+ <array>
16
+ <string>arm64</string>
17
+ <string>x86_64</string>
18
+ </array>
19
+ <key>SupportedPlatform</key>
20
+ <string>ios</string>
21
+ <key>SupportedPlatformVariant</key>
22
+ <string>simulator</string>
23
+ </dict>
24
+ <dict>
25
+ <key>BinaryPath</key>
26
+ <string>Kindly.framework/Kindly</string>
27
+ <key>LibraryIdentifier</key>
28
+ <string>ios-arm64</string>
29
+ <key>LibraryPath</key>
30
+ <string>Kindly.framework</string>
31
+ <key>SupportedArchitectures</key>
32
+ <array>
33
+ <string>arm64</string>
34
+ </array>
35
+ <key>SupportedPlatform</key>
36
+ <string>ios</string>
37
+ </dict>
38
+ </array>
39
+ <key>CFBundlePackageType</key>
40
+ <string>XFWK</string>
41
+ <key>XCFrameworkFormatVersion</key>
42
+ <string>1.0</string>
43
+ </dict>
44
+ </plist>