zixflow-reactnative 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/LICENSE +21 -0
- package/README.md +451 -0
- package/android/build.gradle +155 -0
- package/android/cio-core.gradle +12 -0
- package/android/consumer-rules.pro +3 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +19 -0
- package/android/src/main/java/io/customer/reactnative/sdk/CustomerIOReactNativePackage.kt +85 -0
- package/android/src/main/java/io/customer/reactnative/sdk/NativeCustomerIOModule.kt +201 -0
- package/android/src/main/java/io/customer/reactnative/sdk/constant/Keys.kt +20 -0
- package/android/src/main/java/io/customer/reactnative/sdk/extension/MapExtensions.kt +92 -0
- package/android/src/main/java/io/customer/reactnative/sdk/extension/ReactExtensions.kt +11 -0
- package/android/src/main/java/io/customer/reactnative/sdk/extension/StringExtensions.kt +3 -0
- package/android/src/main/java/io/customer/reactnative/sdk/extension/ViewExtensions.kt +34 -0
- package/android/src/main/java/io/customer/reactnative/sdk/location/NativeLocationModule.kt +66 -0
- package/android/src/main/java/io/customer/reactnative/sdk/logging/NativeCustomerIOLoggingModule.kt +90 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/InlineInAppMessageViewManager.kt +56 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/NativeMessagingInAppModule.kt +215 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/NotificationInboxExtensions.kt +23 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInAppEventListener.kt +77 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInAppPlatformDelegate.kt +37 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInlineInAppMessageView.kt +44 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactNotificationInboxChangeListener.kt +47 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/NativeMessagingPushModule.kt +283 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/PermissionStatus.kt +9 -0
- package/android/src/main/java/io/customer/reactnative/sdk/messagingpush/PushMessagingExtensions.kt +58 -0
- package/android/src/main/java/io/customer/reactnative/sdk/util/Preconditions.kt +35 -0
- package/android/src/main/res/values/customer_io_config.xml +13 -0
- package/customerio-reactnative.podspec +60 -0
- package/ios/CustomerioReactnative.xcodeproj/project.pbxproj +285 -0
- package/ios/CustomerioReactnative.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/ios/CustomerioReactnative.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/wrappers/CustomerioReactnative-Bridging-Header.h +2 -0
- package/ios/wrappers/NativeCustomerIO.mm +100 -0
- package/ios/wrappers/NativeCustomerIO.swift +162 -0
- package/ios/wrappers/inapp/InboxMessage+Conversion.swift +22 -0
- package/ios/wrappers/inapp/NativeMessagingInApp.mm +122 -0
- package/ios/wrappers/inapp/NativeMessagingInApp.swift +214 -0
- package/ios/wrappers/inapp/ReactInAppEventListener.swift +74 -0
- package/ios/wrappers/inapp/inline/InlineInAppMessageStateEvent.swift +23 -0
- package/ios/wrappers/inapp/inline/RCTInlineMessageNative.h +18 -0
- package/ios/wrappers/inapp/inline/RCTInlineMessageNative.mm +168 -0
- package/ios/wrappers/inapp/inline/ReactInlineMessageView.h +42 -0
- package/ios/wrappers/inapp/inline/ReactInlineMessageView.swift +124 -0
- package/ios/wrappers/location/NativeLocation.mm +52 -0
- package/ios/wrappers/location/NativeLocation.swift +37 -0
- package/ios/wrappers/logging/NativeCustomerIOLogging.mm +81 -0
- package/ios/wrappers/logging/NativeCustomerIOLogging.swift +62 -0
- package/ios/wrappers/push/NativeMessagingPush.mm +87 -0
- package/ios/wrappers/push/NativeMessagingPush.swift +119 -0
- package/ios/wrappers/utils/CioConfigUtils.swift +63 -0
- package/ios/wrappers/utils/CioConstants.swift +25 -0
- package/ios/wrappers/utils/Preconditions.swift +20 -0
- package/ios/wrappers/utils/RCTCustomerIOUtils.h +19 -0
- package/lib/commonjs/cio-params.js +2 -0
- package/lib/commonjs/cio-params.js.map +1 -0
- package/lib/commonjs/components/InlineInAppMessageView.js +146 -0
- package/lib/commonjs/components/InlineInAppMessageView.js.map +1 -0
- package/lib/commonjs/components/index.js +14 -0
- package/lib/commonjs/components/index.js.map +1 -0
- package/lib/commonjs/customerio-cdp.js +163 -0
- package/lib/commonjs/customerio-cdp.js.map +1 -0
- package/lib/commonjs/customerio-inapp.js +107 -0
- package/lib/commonjs/customerio-inapp.js.map +1 -0
- package/lib/commonjs/customerio-location.js +53 -0
- package/lib/commonjs/customerio-location.js.map +1 -0
- package/lib/commonjs/customerio-push.js +115 -0
- package/lib/commonjs/customerio-push.js.map +1 -0
- package/lib/commonjs/index.js +17 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/native-logger-listener.js +84 -0
- package/lib/commonjs/native-logger-listener.js.map +1 -0
- package/lib/commonjs/notification-inbox.js +132 -0
- package/lib/commonjs/notification-inbox.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/postInstall.js +13 -0
- package/lib/commonjs/postInstall.js.map +1 -0
- package/lib/commonjs/specs/components/InlineMessageNativeComponent.ts +59 -0
- package/lib/commonjs/specs/modules/NativeCustomerIO.js +40 -0
- package/lib/commonjs/specs/modules/NativeCustomerIO.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOLocation.js +15 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOLocation.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOLogging.js +19 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOLogging.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOMessagingInApp.js +16 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOMessagingInApp.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOMessagingPush.js +15 -0
- package/lib/commonjs/specs/modules/NativeCustomerIOMessagingPush.js.map +1 -0
- package/lib/commonjs/types/data-pipelines.js +123 -0
- package/lib/commonjs/types/data-pipelines.js.map +1 -0
- package/lib/commonjs/types/in-app.js +43 -0
- package/lib/commonjs/types/in-app.js.map +1 -0
- package/lib/commonjs/types/index.js +39 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/internal.js +2 -0
- package/lib/commonjs/types/internal.js.map +1 -0
- package/lib/commonjs/types/push.js +49 -0
- package/lib/commonjs/types/push.js.map +1 -0
- package/lib/commonjs/utils/native-bridge.js +31 -0
- package/lib/commonjs/utils/native-bridge.js.map +1 -0
- package/lib/commonjs/utils/param-validation.js +136 -0
- package/lib/commonjs/utils/param-validation.js.map +1 -0
- package/lib/commonjs/zixflow.js +71 -0
- package/lib/commonjs/zixflow.js.map +1 -0
- package/lib/module/cio-params.js +2 -0
- package/lib/module/cio-params.js.map +1 -0
- package/lib/module/components/InlineInAppMessageView.js +141 -0
- package/lib/module/components/InlineInAppMessageView.js.map +1 -0
- package/lib/module/components/index.js +6 -0
- package/lib/module/components/index.js.map +1 -0
- package/lib/module/customerio-cdp.js +157 -0
- package/lib/module/customerio-cdp.js.map +1 -0
- package/lib/module/customerio-inapp.js +92 -0
- package/lib/module/customerio-inapp.js.map +1 -0
- package/lib/module/customerio-location.js +48 -0
- package/lib/module/customerio-location.js.map +1 -0
- package/lib/module/customerio-push.js +111 -0
- package/lib/module/customerio-push.js.map +1 -0
- package/lib/module/index.js +12 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native-logger-listener.js +79 -0
- package/lib/module/native-logger-listener.js.map +1 -0
- package/lib/module/notification-inbox.js +127 -0
- package/lib/module/notification-inbox.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/postInstall.js +13 -0
- package/lib/module/postInstall.js.map +1 -0
- package/lib/module/specs/components/InlineMessageNativeComponent.ts +59 -0
- package/lib/module/specs/modules/NativeCustomerIO.js +41 -0
- package/lib/module/specs/modules/NativeCustomerIO.js.map +1 -0
- package/lib/module/specs/modules/NativeCustomerIOLocation.js +13 -0
- package/lib/module/specs/modules/NativeCustomerIOLocation.js.map +1 -0
- package/lib/module/specs/modules/NativeCustomerIOLogging.js +18 -0
- package/lib/module/specs/modules/NativeCustomerIOLogging.js.map +1 -0
- package/lib/module/specs/modules/NativeCustomerIOMessagingInApp.js +15 -0
- package/lib/module/specs/modules/NativeCustomerIOMessagingInApp.js.map +1 -0
- package/lib/module/specs/modules/NativeCustomerIOMessagingPush.js +13 -0
- package/lib/module/specs/modules/NativeCustomerIOMessagingPush.js.map +1 -0
- package/lib/module/types/data-pipelines.js +126 -0
- package/lib/module/types/data-pipelines.js.map +1 -0
- package/lib/module/types/in-app.js +42 -0
- package/lib/module/types/in-app.js.map +1 -0
- package/lib/module/types/index.js +6 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/internal.js +2 -0
- package/lib/module/types/internal.js.map +1 -0
- package/lib/module/types/push.js +47 -0
- package/lib/module/types/push.js.map +1 -0
- package/lib/module/utils/native-bridge.js +25 -0
- package/lib/module/utils/native-bridge.js.map +1 -0
- package/lib/module/utils/param-validation.js +132 -0
- package/lib/module/utils/param-validation.js.map +1 -0
- package/lib/module/zixflow.js +23 -0
- package/lib/module/zixflow.js.map +1 -0
- package/lib/typescript/commonjs/cio-params.d.ts +5 -0
- package/lib/typescript/commonjs/cio-params.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/InlineInAppMessageView.d.ts +41 -0
- package/lib/typescript/commonjs/components/InlineInAppMessageView.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/index.d.ts +3 -0
- package/lib/typescript/commonjs/components/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/customerio-cdp.d.ts +40 -0
- package/lib/typescript/commonjs/customerio-cdp.d.ts.map +1 -0
- package/lib/typescript/commonjs/customerio-inapp.d.ts +48 -0
- package/lib/typescript/commonjs/customerio-inapp.d.ts.map +1 -0
- package/lib/typescript/commonjs/customerio-location.d.ts +31 -0
- package/lib/typescript/commonjs/customerio-location.d.ts.map +1 -0
- package/lib/typescript/commonjs/customerio-push.d.ts +56 -0
- package/lib/typescript/commonjs/customerio-push.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +8 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/native-logger-listener.d.ts +8 -0
- package/lib/typescript/commonjs/native-logger-listener.d.ts.map +1 -0
- package/lib/typescript/commonjs/notification-inbox.d.ts +57 -0
- package/lib/typescript/commonjs/notification-inbox.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/postInstall.d.ts +2 -0
- package/lib/typescript/commonjs/postInstall.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/components/InlineMessageNativeComponent.d.ts +40 -0
- package/lib/typescript/commonjs/specs/components/InlineMessageNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIO.d.ts +46 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIO.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLocation.d.ts +14 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLocation.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLogging.d.ts +18 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOLogging.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingInApp.d.ts +23 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingInApp.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingPush.d.ts +20 -0
- package/lib/typescript/commonjs/specs/modules/NativeCustomerIOMessagingPush.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/data-pipelines.d.ts +143 -0
- package/lib/typescript/commonjs/types/data-pipelines.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/in-app.d.ts +67 -0
- package/lib/typescript/commonjs/types/in-app.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/index.d.ts +4 -0
- package/lib/typescript/commonjs/types/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/internal.d.ts +20 -0
- package/lib/typescript/commonjs/types/internal.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/push.d.ts +49 -0
- package/lib/typescript/commonjs/types/push.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/native-bridge.d.ts +9 -0
- package/lib/typescript/commonjs/utils/native-bridge.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/param-validation.d.ts +44 -0
- package/lib/typescript/commonjs/utils/param-validation.d.ts.map +1 -0
- package/lib/typescript/commonjs/zixflow.d.ts +14 -0
- package/lib/typescript/commonjs/zixflow.d.ts.map +1 -0
- package/lib/typescript/module/cio-params.d.ts +5 -0
- package/lib/typescript/module/cio-params.d.ts.map +1 -0
- package/lib/typescript/module/components/InlineInAppMessageView.d.ts +41 -0
- package/lib/typescript/module/components/InlineInAppMessageView.d.ts.map +1 -0
- package/lib/typescript/module/components/index.d.ts +3 -0
- package/lib/typescript/module/components/index.d.ts.map +1 -0
- package/lib/typescript/module/customerio-cdp.d.ts +40 -0
- package/lib/typescript/module/customerio-cdp.d.ts.map +1 -0
- package/lib/typescript/module/customerio-inapp.d.ts +48 -0
- package/lib/typescript/module/customerio-inapp.d.ts.map +1 -0
- package/lib/typescript/module/customerio-location.d.ts +31 -0
- package/lib/typescript/module/customerio-location.d.ts.map +1 -0
- package/lib/typescript/module/customerio-push.d.ts +56 -0
- package/lib/typescript/module/customerio-push.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +8 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/native-logger-listener.d.ts +8 -0
- package/lib/typescript/module/native-logger-listener.d.ts.map +1 -0
- package/lib/typescript/module/notification-inbox.d.ts +57 -0
- package/lib/typescript/module/notification-inbox.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/postInstall.d.ts +2 -0
- package/lib/typescript/module/postInstall.d.ts.map +1 -0
- package/lib/typescript/module/specs/components/InlineMessageNativeComponent.d.ts +40 -0
- package/lib/typescript/module/specs/components/InlineMessageNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIO.d.ts +46 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIO.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOLocation.d.ts +14 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOLocation.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOLogging.d.ts +18 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOLogging.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingInApp.d.ts +23 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingInApp.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingPush.d.ts +20 -0
- package/lib/typescript/module/specs/modules/NativeCustomerIOMessagingPush.d.ts.map +1 -0
- package/lib/typescript/module/types/data-pipelines.d.ts +143 -0
- package/lib/typescript/module/types/data-pipelines.d.ts.map +1 -0
- package/lib/typescript/module/types/in-app.d.ts +67 -0
- package/lib/typescript/module/types/in-app.d.ts.map +1 -0
- package/lib/typescript/module/types/index.d.ts +4 -0
- package/lib/typescript/module/types/index.d.ts.map +1 -0
- package/lib/typescript/module/types/internal.d.ts +20 -0
- package/lib/typescript/module/types/internal.d.ts.map +1 -0
- package/lib/typescript/module/types/push.d.ts +49 -0
- package/lib/typescript/module/types/push.d.ts.map +1 -0
- package/lib/typescript/module/utils/native-bridge.d.ts +9 -0
- package/lib/typescript/module/utils/native-bridge.d.ts.map +1 -0
- package/lib/typescript/module/utils/param-validation.d.ts +44 -0
- package/lib/typescript/module/utils/param-validation.d.ts.map +1 -0
- package/lib/typescript/module/zixflow.d.ts +14 -0
- package/lib/typescript/module/zixflow.d.ts.map +1 -0
- package/package.json +165 -0
- package/src/cio-params.ts +4 -0
- package/src/components/InlineInAppMessageView.tsx +187 -0
- package/src/components/index.ts +3 -0
- package/src/customerio-cdp.ts +190 -0
- package/src/customerio-inapp.ts +127 -0
- package/src/customerio-location.ts +56 -0
- package/src/customerio-push.ts +127 -0
- package/src/index.ts +9 -0
- package/src/native-logger-listener.ts +84 -0
- package/src/notification-inbox.ts +154 -0
- package/src/postInstall.js +10 -0
- package/src/specs/components/InlineMessageNativeComponent.ts +59 -0
- package/src/specs/modules/NativeCustomerIO.ts +55 -0
- package/src/specs/modules/NativeCustomerIOLocation.ts +15 -0
- package/src/specs/modules/NativeCustomerIOLogging.ts +24 -0
- package/src/specs/modules/NativeCustomerIOMessagingInApp.ts +30 -0
- package/src/specs/modules/NativeCustomerIOMessagingPush.ts +27 -0
- package/src/types/data-pipelines.ts +150 -0
- package/src/types/in-app.ts +69 -0
- package/src/types/index.ts +3 -0
- package/src/types/internal.ts +20 -0
- package/src/types/push.ts +50 -0
- package/src/utils/native-bridge.ts +30 -0
- package/src/utils/param-validation.ts +178 -0
- package/src/zixflow.ts +24 -0
- package/zixflow-reactnative-richpush.podspec +42 -0
- package/zixflow-reactnative.podspec +66 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
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.ReadableMap
|
|
7
|
+
import io.customer.messaginginapp.MessagingInAppModuleConfig
|
|
8
|
+
import io.customer.messaginginapp.ModuleMessagingInApp
|
|
9
|
+
import io.customer.messaginginapp.di.inAppMessaging
|
|
10
|
+
import io.customer.messaginginapp.gist.data.model.InboxMessage
|
|
11
|
+
import io.customer.messaginginapp.gist.data.model.response.InboxMessageFactory
|
|
12
|
+
import io.customer.messaginginapp.inbox.NotificationInbox
|
|
13
|
+
import io.customer.reactnative.sdk.NativeCustomerIOMessagingInAppSpec
|
|
14
|
+
import io.customer.reactnative.sdk.constant.Keys
|
|
15
|
+
import io.customer.reactnative.sdk.extension.getTypedValue
|
|
16
|
+
import io.customer.reactnative.sdk.extension.toMap
|
|
17
|
+
import io.customer.sdk.CustomerIO
|
|
18
|
+
import io.customer.sdk.CustomerIOBuilder
|
|
19
|
+
import io.customer.sdk.core.di.SDKComponent
|
|
20
|
+
import io.customer.sdk.core.util.Logger
|
|
21
|
+
import io.customer.sdk.data.model.Region
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* React Native module implementation for Customer.io In-App Messaging Native SDK
|
|
25
|
+
* using TurboModules with new architecture.
|
|
26
|
+
*/
|
|
27
|
+
class NativeMessagingInAppModule(
|
|
28
|
+
reactContext: ReactApplicationContext,
|
|
29
|
+
) : NativeCustomerIOMessagingInAppSpec(reactContext) {
|
|
30
|
+
private val logger: Logger = SDKComponent.logger
|
|
31
|
+
private val inAppMessagingModule: ModuleMessagingInApp?
|
|
32
|
+
get() = runCatching { CustomerIO.instance().inAppMessaging() }.getOrNull()
|
|
33
|
+
|
|
34
|
+
private val inAppEventListener = ReactInAppEventListener.instance
|
|
35
|
+
private val inboxChangeListener = ReactNotificationInboxChangeListener.instance
|
|
36
|
+
|
|
37
|
+
// Dedicated lock for inbox listener setup to avoid blocking other operations
|
|
38
|
+
private val inboxListenerLock = Any()
|
|
39
|
+
private var isInboxChangeListenerSetup = false
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Returns NotificationInbox instance if available, null otherwise, logging error on failure.
|
|
43
|
+
* Note: Notification Inbox is only available after SDK is initialized.
|
|
44
|
+
*/
|
|
45
|
+
private fun requireInboxInstance(): NotificationInbox? {
|
|
46
|
+
val inbox = inAppMessagingModule?.inbox()
|
|
47
|
+
if (inbox == null) {
|
|
48
|
+
logger.error("Notification Inbox is not available. Ensure CustomerIO SDK is initialized.")
|
|
49
|
+
}
|
|
50
|
+
return inbox
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override fun initialize() {
|
|
54
|
+
super.initialize()
|
|
55
|
+
inAppEventListener.setEventEmitter { data ->
|
|
56
|
+
emitOnInAppEventReceived(data)
|
|
57
|
+
}
|
|
58
|
+
// Note: Inbox change listener is set up lazily when inbox is first accessed via
|
|
59
|
+
// setupInboxListener() and not here as Notification Inbox becomes available only after
|
|
60
|
+
// CustomerIO.initialize() is called, which may not have happened yet at this point.
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override fun invalidate() {
|
|
64
|
+
inAppEventListener.clearEventEmitter()
|
|
65
|
+
clearInboxChangeListener()
|
|
66
|
+
super.invalidate()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun dismissMessage() {
|
|
70
|
+
inAppMessagingModule?.dismissMessage()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
override fun setupInboxListener() {
|
|
74
|
+
setupInboxChangeListener()
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
override fun getMessages(topic: String?, promise: Promise?) {
|
|
78
|
+
try {
|
|
79
|
+
val inbox = requireInboxInstance() ?: run {
|
|
80
|
+
promise?.reject(
|
|
81
|
+
"INBOX_NOT_AVAILABLE",
|
|
82
|
+
"Notification Inbox is not available. Ensure CustomerIO SDK is initialized."
|
|
83
|
+
)
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
inbox.fetchMessages(topic) { result ->
|
|
88
|
+
result.onSuccess { messages ->
|
|
89
|
+
val messagesArray = Arguments.createArray()
|
|
90
|
+
messages.forEach { message ->
|
|
91
|
+
messagesArray.pushMap(message.toWritableMap())
|
|
92
|
+
}
|
|
93
|
+
promise?.resolve(messagesArray)
|
|
94
|
+
}.onFailure { error ->
|
|
95
|
+
promise?.reject(
|
|
96
|
+
"FETCH_FAILED",
|
|
97
|
+
error.localizedMessage ?: "Failed to fetch messages"
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch (e: Exception) {
|
|
102
|
+
promise?.reject("FETCH_ERROR", e.localizedMessage ?: "Unknown error")
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override fun markMessageOpened(message: ReadableMap?) {
|
|
107
|
+
performInboxMessageAction(message) { inbox, inboxMessage ->
|
|
108
|
+
inbox.markMessageOpened(inboxMessage)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
override fun markMessageUnopened(message: ReadableMap?) {
|
|
113
|
+
performInboxMessageAction(message) { inbox, inboxMessage ->
|
|
114
|
+
inbox.markMessageUnopened(inboxMessage)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
override fun markMessageDeleted(message: ReadableMap?) {
|
|
119
|
+
performInboxMessageAction(message) { inbox, inboxMessage ->
|
|
120
|
+
inbox.markMessageDeleted(inboxMessage)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
override fun trackMessageClicked(message: ReadableMap?, actionName: String?) {
|
|
125
|
+
performInboxMessageAction(message) { inbox, inboxMessage ->
|
|
126
|
+
inbox.trackMessageClicked(inboxMessage, actionName)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Sets up the inbox change listener to receive real-time updates.
|
|
132
|
+
* This method can be called multiple times safely and will only set up the listener once.
|
|
133
|
+
* Note: Inbox must be available (SDK initialized) before this can succeed.
|
|
134
|
+
*/
|
|
135
|
+
private fun setupInboxChangeListener() {
|
|
136
|
+
synchronized(inboxListenerLock) {
|
|
137
|
+
// Only set up once to avoid duplicate listeners
|
|
138
|
+
if (isInboxChangeListenerSetup) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
val inbox = requireInboxInstance() ?: run {
|
|
143
|
+
logger.debug("Inbox not available yet, skipping listener setup")
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
inboxChangeListener.setEventEmitter(
|
|
148
|
+
emitter = { data ->
|
|
149
|
+
emitSubscribeToMessagesChanged(data)
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
inbox.addChangeListener(inboxChangeListener)
|
|
153
|
+
isInboxChangeListenerSetup = true
|
|
154
|
+
logger.debug("NotificationInboxChangeListener set up successfully")
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private fun clearInboxChangeListener() {
|
|
159
|
+
synchronized(inboxListenerLock) {
|
|
160
|
+
if (!isInboxChangeListenerSetup) {
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
requireInboxInstance()?.removeChangeListener(inboxChangeListener)
|
|
164
|
+
inboxChangeListener.clearEventEmitter()
|
|
165
|
+
isInboxChangeListenerSetup = false
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Helper to validate inbox instance and message data before performing a message action.
|
|
171
|
+
* Returns early if inbox is unavailable or message data is invalid.
|
|
172
|
+
*/
|
|
173
|
+
private fun performInboxMessageAction(
|
|
174
|
+
message: ReadableMap?,
|
|
175
|
+
action: (NotificationInbox, InboxMessage) -> Unit
|
|
176
|
+
) {
|
|
177
|
+
val inbox = requireInboxInstance() ?: return
|
|
178
|
+
val inboxMessage = InboxMessageFactory.fromMap(message.toMap()) ?: run {
|
|
179
|
+
logger.error("Invalid message data: $message")
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
action(inbox, inboxMessage)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
companion object {
|
|
186
|
+
internal const val NAME = "NativeCustomerIOMessagingInApp"
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Adds InAppMessaging module to native Android SDK based on configuration provided by customer
|
|
190
|
+
* app.
|
|
191
|
+
*
|
|
192
|
+
* @param builder CustomerIOBuilder instance to add InAppMessaging module
|
|
193
|
+
* @param config Configuration provided by customer app for InAppMessaging module
|
|
194
|
+
* @param region Region to be used for InAppMessaging module
|
|
195
|
+
*/
|
|
196
|
+
internal fun addNativeModuleFromConfig(
|
|
197
|
+
builder: CustomerIOBuilder,
|
|
198
|
+
config: Map<String, Any>,
|
|
199
|
+
region: Region
|
|
200
|
+
) {
|
|
201
|
+
val siteId = config.getTypedValue<String>(Keys.Config.SITE_ID)
|
|
202
|
+
if (siteId.isNullOrBlank()) {
|
|
203
|
+
SDKComponent.logger.error("Site ID is required to initialize InAppMessaging module")
|
|
204
|
+
return
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
val module = ModuleMessagingInApp(
|
|
208
|
+
MessagingInAppModuleConfig.Builder(siteId = siteId, region = region).apply {
|
|
209
|
+
setEventListener(eventListener = ReactInAppEventListener.instance)
|
|
210
|
+
}.build(),
|
|
211
|
+
)
|
|
212
|
+
builder.addCustomerIOModule(module)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.WritableMap
|
|
5
|
+
import io.customer.messaginginapp.gist.data.model.InboxMessage
|
|
6
|
+
import io.customer.reactnative.sdk.extension.putOrNull
|
|
7
|
+
import io.customer.reactnative.sdk.extension.toWritableArray
|
|
8
|
+
import io.customer.reactnative.sdk.extension.toWritableMap
|
|
9
|
+
|
|
10
|
+
// Converts an [InboxMessage] to a [WritableMap] for React Native bridge
|
|
11
|
+
internal fun InboxMessage.toWritableMap(): WritableMap {
|
|
12
|
+
return Arguments.createMap().apply {
|
|
13
|
+
putString("queueId", queueId)
|
|
14
|
+
putOrNull("deliveryId", deliveryId) { k, v -> putString(k, v) }
|
|
15
|
+
putDouble("sentAt", sentAt.time.toDouble())
|
|
16
|
+
putOrNull("expiry", expiry) { k, v -> putDouble(k, v.time.toDouble()) }
|
|
17
|
+
putString("type", type)
|
|
18
|
+
putBoolean("opened", opened)
|
|
19
|
+
putArray("topics", topics.toWritableArray())
|
|
20
|
+
putOrNull("priority", priority) { k, v -> putInt(k, v) }
|
|
21
|
+
putMap("properties", properties.toWritableMap())
|
|
22
|
+
}
|
|
23
|
+
}
|
package/android/src/main/java/io/customer/reactnative/sdk/messaginginapp/ReactInAppEventListener.kt
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import io.customer.messaginginapp.type.InAppEventListener
|
|
6
|
+
import io.customer.messaginginapp.type.InAppMessage
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* React Native bridge for Customer.io in-app messaging events.
|
|
10
|
+
* Converts native SDK events to JavaScript compatible format.
|
|
11
|
+
*/
|
|
12
|
+
class ReactInAppEventListener private constructor() : InAppEventListener {
|
|
13
|
+
// Event emitter function to send events to React Native layer
|
|
14
|
+
private var eventEmitter: ((ReadableMap) -> Unit)? = null
|
|
15
|
+
|
|
16
|
+
// Sets the event emitter function
|
|
17
|
+
internal fun setEventEmitter(emitter: ((ReadableMap) -> Unit)?) {
|
|
18
|
+
this.eventEmitter = emitter
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Clears the event emitter to prevent memory leaks
|
|
22
|
+
internal fun clearEventEmitter() {
|
|
23
|
+
this.eventEmitter = null
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Emits an in-app message event to React Native with unified event structure
|
|
27
|
+
private fun emitInAppEvent(
|
|
28
|
+
eventType: String,
|
|
29
|
+
message: InAppMessage,
|
|
30
|
+
actionValue: String? = null,
|
|
31
|
+
actionName: String? = null,
|
|
32
|
+
) {
|
|
33
|
+
// Get the emitter, return early if not set
|
|
34
|
+
val emitter = eventEmitter ?: return
|
|
35
|
+
|
|
36
|
+
val data = buildMap {
|
|
37
|
+
put("eventType", eventType)
|
|
38
|
+
put("messageId", message.messageId)
|
|
39
|
+
put("deliveryId", message.deliveryId)
|
|
40
|
+
actionValue?.let { put("actionValue", it) }
|
|
41
|
+
actionName?.let { put("actionName", it) }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
emitter.invoke(Arguments.makeNativeMap(data))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
override fun errorWithMessage(message: InAppMessage) = emitInAppEvent(
|
|
48
|
+
eventType = "errorWithMessage",
|
|
49
|
+
message = message,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
override fun messageActionTaken(
|
|
53
|
+
message: InAppMessage,
|
|
54
|
+
actionValue: String,
|
|
55
|
+
actionName: String,
|
|
56
|
+
) = emitInAppEvent(
|
|
57
|
+
eventType = "messageActionTaken",
|
|
58
|
+
message = message,
|
|
59
|
+
actionValue = actionValue,
|
|
60
|
+
actionName = actionName,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
override fun messageDismissed(message: InAppMessage) = emitInAppEvent(
|
|
64
|
+
eventType = "messageDismissed",
|
|
65
|
+
message = message,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
override fun messageShown(message: InAppMessage) = emitInAppEvent(
|
|
69
|
+
eventType = "messageShown",
|
|
70
|
+
message = message,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
companion object {
|
|
74
|
+
// Singleton instance with public visibility for direct access by Expo plugin
|
|
75
|
+
val instance: ReactInAppEventListener by lazy { ReactInAppEventListener() }
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
2
|
+
|
|
3
|
+
import android.view.View
|
|
4
|
+
import com.facebook.react.bridge.Arguments
|
|
5
|
+
import io.customer.messaginginapp.ui.bridge.WrapperPlatformDelegate
|
|
6
|
+
import io.customer.reactnative.sdk.extension.sendUIEventToReactJS
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* React Native platform delegate for in-app messaging.
|
|
10
|
+
* Bridges native in-app message events to React Native components.
|
|
11
|
+
*
|
|
12
|
+
* @param view The native Android view hosting the in-app message
|
|
13
|
+
*/
|
|
14
|
+
class ReactInAppPlatformDelegate(
|
|
15
|
+
view: View,
|
|
16
|
+
) : WrapperPlatformDelegate(view) {
|
|
17
|
+
/**
|
|
18
|
+
* Dispatches in-app message events from native Android to React Native components.
|
|
19
|
+
* Converts native events to React Native UI events using the provided event name and payload.
|
|
20
|
+
*/
|
|
21
|
+
override fun dispatchEvent(eventName: String, payload: Map<String, Any?>) {
|
|
22
|
+
view.sendUIEventToReactJS(
|
|
23
|
+
eventName = eventName,
|
|
24
|
+
payload = Arguments.makeNativeMap(payload),
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Internal helper method for dispatching events within the SDK.
|
|
29
|
+
internal fun dispatchEventInternal(eventName: String, payload: Map<String, Any?>) {
|
|
30
|
+
dispatchEvent(eventName, payload)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
companion object {
|
|
34
|
+
// Event name constant for in-app message action clicks
|
|
35
|
+
const val ON_ACTION_CLICK = "onActionClick"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.AttributeSet
|
|
5
|
+
import androidx.annotation.AttrRes
|
|
6
|
+
import androidx.annotation.StyleRes
|
|
7
|
+
import io.customer.messaginginapp.type.InAppMessage
|
|
8
|
+
import io.customer.messaginginapp.type.InlineMessageActionListener
|
|
9
|
+
import io.customer.messaginginapp.ui.InlineInAppMessageView
|
|
10
|
+
import io.customer.messaginginapp.ui.core.WrapperInlineView
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* React Native implementation of inline in-app message view extending [WrapperInlineView].
|
|
14
|
+
* Replacement for [InlineInAppMessageView] from native SDK to work seamlessly with React Native.
|
|
15
|
+
* Bridges native in-app message functionality with React Native event handling and layout system.
|
|
16
|
+
*/
|
|
17
|
+
class ReactInlineInAppMessageView @JvmOverloads constructor(
|
|
18
|
+
context: Context,
|
|
19
|
+
attrs: AttributeSet? = null,
|
|
20
|
+
@AttrRes defStyleAttr: Int = 0,
|
|
21
|
+
@StyleRes defStyleRes: Int = 0
|
|
22
|
+
) : WrapperInlineView<ReactInAppPlatformDelegate>(
|
|
23
|
+
context, attrs, defStyleAttr, defStyleRes
|
|
24
|
+
), InlineMessageActionListener {
|
|
25
|
+
override val platformDelegate = ReactInAppPlatformDelegate(view = this)
|
|
26
|
+
|
|
27
|
+
init {
|
|
28
|
+
initializeView()
|
|
29
|
+
setActionListener(this)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
override fun onActionClick(message: InAppMessage, actionValue: String, actionName: String) {
|
|
33
|
+
val payload = mapOf(
|
|
34
|
+
"message" to mapOf(
|
|
35
|
+
"messageId" to message.messageId,
|
|
36
|
+
"deliveryId" to message.deliveryId,
|
|
37
|
+
"elementId" to elementId
|
|
38
|
+
),
|
|
39
|
+
"actionValue" to actionValue,
|
|
40
|
+
"actionName" to actionName
|
|
41
|
+
)
|
|
42
|
+
platformDelegate.dispatchEventInternal(ReactInAppPlatformDelegate.ON_ACTION_CLICK, payload)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
package io.customer.reactnative.sdk.messaginginapp
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import io.customer.messaginginapp.gist.data.model.InboxMessage
|
|
6
|
+
import io.customer.messaginginapp.inbox.NotificationInboxChangeListener
|
|
7
|
+
|
|
8
|
+
class ReactNotificationInboxChangeListener private constructor() : NotificationInboxChangeListener {
|
|
9
|
+
|
|
10
|
+
// Event emitter function to send events to React Native layer
|
|
11
|
+
private var eventEmitter: ((ReadableMap) -> Unit)? = null
|
|
12
|
+
|
|
13
|
+
// Sets the event emitter function and message converter
|
|
14
|
+
internal fun setEventEmitter(emitter: ((ReadableMap) -> Unit)?) {
|
|
15
|
+
this.eventEmitter = emitter
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Clears the event emitter to prevent memory leaks
|
|
19
|
+
internal fun clearEventEmitter() {
|
|
20
|
+
this.eventEmitter = null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private fun emitMessagesUpdate(messages: List<InboxMessage>) {
|
|
24
|
+
// Get the emitter and converter, return early if not set
|
|
25
|
+
val emitter = eventEmitter ?: return
|
|
26
|
+
|
|
27
|
+
val messagesArray = Arguments.createArray()
|
|
28
|
+
messages.forEach { message ->
|
|
29
|
+
messagesArray.pushMap(message.toWritableMap())
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
val payload = Arguments.createMap().apply {
|
|
33
|
+
putArray("messages", messagesArray)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
emitter.invoke(payload)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override fun onMessagesChanged(messages: List<InboxMessage>) {
|
|
40
|
+
emitMessagesUpdate(messages)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
companion object {
|
|
44
|
+
// Singleton instance with public visibility for direct access
|
|
45
|
+
val instance: ReactNotificationInboxChangeListener by lazy { ReactNotificationInboxChangeListener() }
|
|
46
|
+
}
|
|
47
|
+
}
|