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,122 @@
|
|
|
1
|
+
#import "../utils/RCTCustomerIOUtils.h"
|
|
2
|
+
#import <React/RCTBridgeModule.h>
|
|
3
|
+
#import <React/RCTEventEmitter.h>
|
|
4
|
+
#import <React/RCTInitializing.h>
|
|
5
|
+
#import <React/RCTInvalidating.h>
|
|
6
|
+
#import <RNZixflowSpec/RNZixflowSpec.h>
|
|
7
|
+
|
|
8
|
+
// Protocol that extends the spec with setEventEmitter method
|
|
9
|
+
@protocol NativeMessagingInAppBridge <NativeCustomerIOMessagingInAppSpec, RCTInitializing, RCTInvalidating>
|
|
10
|
+
- (void)setEventEmitter:(id)emitter;
|
|
11
|
+
@end
|
|
12
|
+
|
|
13
|
+
// Objective-C wrapper for new architecture TurboModule implementation
|
|
14
|
+
@interface RCTNativeMessagingInApp
|
|
15
|
+
: NativeCustomerIOMessagingInAppSpecBase <NativeCustomerIOMessagingInAppSpec>
|
|
16
|
+
// Bridge to Swift implementation for cross-language compatibility
|
|
17
|
+
@property(nonatomic, strong) id<NativeMessagingInAppBridge> swiftBridge;
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
@implementation RCTNativeMessagingInApp
|
|
21
|
+
|
|
22
|
+
RCT_EXPORT_MODULE()
|
|
23
|
+
|
|
24
|
+
// Create TurboModule instance for new architecture JSI integration
|
|
25
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
26
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params {
|
|
27
|
+
return std::make_shared<facebook::react::NativeCustomerIOMessagingInAppSpecJSI>(params);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Validates Swift bridge is available before method calls
|
|
31
|
+
- (void)assertBridgeAvailable:(NSString *)context {
|
|
32
|
+
RCT_ASSERT_BRIDGE_AVAILABLE(self.swiftBridge, context);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (instancetype)init {
|
|
36
|
+
if (self = [super init]) {
|
|
37
|
+
// Use runtime class lookup to avoid import issues and circular dependencies
|
|
38
|
+
Class swiftClass = NSClassFromString(@"NativeMessagingInApp");
|
|
39
|
+
RCT_ASSERT_NOT_NIL(swiftClass, @"NativeMessagingInApp Swift class", @"during runtime lookup");
|
|
40
|
+
_swiftBridge = [[swiftClass alloc] init];
|
|
41
|
+
[self assertBridgeAvailable:@"creating NativeMessagingInApp Swift instance"];
|
|
42
|
+
|
|
43
|
+
// Set event emitter reference for new architecture
|
|
44
|
+
[_swiftBridge setEventEmitter:self];
|
|
45
|
+
}
|
|
46
|
+
return self;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Module initialization can happen on background thread
|
|
50
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
51
|
+
return NO;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
- (void)initialize {
|
|
55
|
+
[self assertBridgeAvailable:@"during initialize"];
|
|
56
|
+
[_swiftBridge initialize];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
- (void)invalidate {
|
|
60
|
+
[self assertBridgeAvailable:@"during invalidate"];
|
|
61
|
+
[_swiftBridge invalidate];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (void)dismissMessage {
|
|
65
|
+
[self assertBridgeAvailable:@"during dismissMessage"];
|
|
66
|
+
[_swiftBridge dismissMessage];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
- (void)setupInboxListener {
|
|
70
|
+
[self assertBridgeAvailable:@"during setupInboxListener"];
|
|
71
|
+
[_swiftBridge setupInboxListener];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (void)getMessages:(NSString *)topic
|
|
75
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
76
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
77
|
+
[self assertBridgeAvailable:@"during getMessages"];
|
|
78
|
+
[_swiftBridge getMessages:topic resolve:resolve reject:reject];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
- (void)markMessageOpened:(NSDictionary *)message {
|
|
82
|
+
[self assertBridgeAvailable:@"during markMessageOpened"];
|
|
83
|
+
[_swiftBridge markMessageOpened:message];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
- (void)markMessageUnopened:(NSDictionary *)message {
|
|
87
|
+
[self assertBridgeAvailable:@"during markMessageUnopened"];
|
|
88
|
+
[_swiftBridge markMessageUnopened:message];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
- (void)markMessageDeleted:(NSDictionary *)message {
|
|
92
|
+
[self assertBridgeAvailable:@"during markMessageDeleted"];
|
|
93
|
+
[_swiftBridge markMessageDeleted:message];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
- (void)trackMessageClicked:(NSDictionary *)message actionName:(NSString *)actionName {
|
|
97
|
+
[self assertBridgeAvailable:@"during trackMessageClicked"];
|
|
98
|
+
[_swiftBridge trackMessageClicked:message actionName:actionName];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
- (void)addListener:(nonnull NSString *)eventName {
|
|
102
|
+
RCT_LEGACY_ARCH_WARNING(addListener);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
- (void)removeListeners:(double)count {
|
|
106
|
+
RCT_LEGACY_ARCH_WARNING(removeListeners);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
- (void)emitOnInAppEventReceived:(NSDictionary *)value {
|
|
110
|
+
[super emitOnInAppEventReceived:value];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
- (void)emitSubscribeToMessagesChanged:(NSDictionary *)value {
|
|
114
|
+
[super emitSubscribeToMessagesChanged:value];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Export class factory function for React Native component registration
|
|
118
|
+
Class<RCTBridgeModule> NativeCustomerIOMessagingInAppCls(void) {
|
|
119
|
+
return RCTNativeMessagingInApp.class;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@end
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import CioInternalCommon
|
|
2
|
+
import CioMessagingInApp
|
|
3
|
+
import Foundation
|
|
4
|
+
import React
|
|
5
|
+
|
|
6
|
+
// In-app messaging module for new React Native architecture (TurboModule)
|
|
7
|
+
@objc(NativeMessagingInApp)
|
|
8
|
+
public class NativeMessagingInApp: NSObject {
|
|
9
|
+
// Reference to the ObjC event emitter for new architecture (TurboModule)
|
|
10
|
+
private weak var objcEventEmitter: AnyObject?
|
|
11
|
+
private lazy var inAppEventCallback: (_ body: [String: Any]) -> Void = { [weak self] body in
|
|
12
|
+
self?.sendEvent(body: body)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private let logger: CioInternalCommon.Logger = DIGraphShared.shared.logger
|
|
16
|
+
|
|
17
|
+
// Task that consumes the inbox messages stream
|
|
18
|
+
private var messagesStreamTask: Task<Void, Never>?
|
|
19
|
+
|
|
20
|
+
// Set ObjC event emitter reference for new architecture
|
|
21
|
+
@objc
|
|
22
|
+
public func setEventEmitter(_ emitter: AnyObject) {
|
|
23
|
+
objcEventEmitter = emitter
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Initialize in-app event listener - called by React Native
|
|
27
|
+
@objc
|
|
28
|
+
public func initialize() {
|
|
29
|
+
// Initialize in-app event listener - called by React Native
|
|
30
|
+
ReactInAppEventListener.shared.setEventEmitter { [weak self] data in
|
|
31
|
+
guard let self else { return }
|
|
32
|
+
|
|
33
|
+
// Filter out nil values to convert [String: Any?] to [String: Any]
|
|
34
|
+
let body = data.compactMapValues { $0 }
|
|
35
|
+
inAppEventCallback(body)
|
|
36
|
+
}
|
|
37
|
+
// If MessagingInApp module has already been initialized, this sets the listener directly.
|
|
38
|
+
// If this method is called early, accessing ReactInAppEventListener.shared will also register
|
|
39
|
+
// it into the DI graph, making it available for access in Expo during auto-initialization.
|
|
40
|
+
MessagingInApp.shared.setEventListener(ReactInAppEventListener.shared)
|
|
41
|
+
|
|
42
|
+
// Note: Inbox change listener is set up lazily when inbox is first accessed via
|
|
43
|
+
// setupInboxListener(), not here. Notification Inbox becomes available only after
|
|
44
|
+
// CustomerIO.initialize() is called, which may not have happened yet at this point.
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Clear in-app event listener to prevent memory leaks - called by React Native
|
|
48
|
+
@objc
|
|
49
|
+
public func invalidate() {
|
|
50
|
+
// Clear in-app event listener to prevent leaks
|
|
51
|
+
clearInAppEventListener()
|
|
52
|
+
clearInboxChangeListener()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Dismisses any currently displayed in-app message
|
|
56
|
+
@objc(dismissMessage)
|
|
57
|
+
public func dismissMessage() {
|
|
58
|
+
MessagingInApp.shared.dismissMessage()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// MARK: - Inbox Methods
|
|
62
|
+
|
|
63
|
+
@objc(setupInboxListener)
|
|
64
|
+
public func setupInboxListener() {
|
|
65
|
+
setupInboxChangeListener()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@objc(getMessages:resolve:reject:)
|
|
69
|
+
public func getMessages(topic: String?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
70
|
+
guard let inbox = requireInboxInstance() else {
|
|
71
|
+
reject(
|
|
72
|
+
"INBOX_NOT_AVAILABLE",
|
|
73
|
+
"Notification Inbox is not available. Ensure CustomerIO SDK is initialized.",
|
|
74
|
+
nil
|
|
75
|
+
)
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
Task {
|
|
80
|
+
// Use native topic filtering - SDK handles filtering and case sensitivity
|
|
81
|
+
let messages = await inbox.getMessages(topic: topic)
|
|
82
|
+
let messagesArray = messages.map { $0.toDictionary() }
|
|
83
|
+
resolve(messagesArray)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@objc(markMessageOpened:)
|
|
88
|
+
public func markMessageOpened(message: NSDictionary) {
|
|
89
|
+
performInboxMessageAction(message: message) { inbox, inboxMessage in
|
|
90
|
+
inbox.markMessageOpened(message: inboxMessage)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@objc(markMessageUnopened:)
|
|
95
|
+
public func markMessageUnopened(message: NSDictionary) {
|
|
96
|
+
performInboxMessageAction(message: message) { inbox, inboxMessage in
|
|
97
|
+
inbox.markMessageUnopened(message: inboxMessage)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@objc(markMessageDeleted:)
|
|
102
|
+
public func markMessageDeleted(message: NSDictionary) {
|
|
103
|
+
performInboxMessageAction(message: message) { inbox, inboxMessage in
|
|
104
|
+
inbox.markMessageDeleted(message: inboxMessage)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@objc(trackMessageClicked:actionName:)
|
|
109
|
+
public func trackMessageClicked(message: NSDictionary, actionName: String?) {
|
|
110
|
+
performInboxMessageAction(message: message) { inbox, inboxMessage in
|
|
111
|
+
inbox.trackMessageClicked(message: inboxMessage, actionName: actionName)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// MARK: - Helper Methods
|
|
116
|
+
|
|
117
|
+
// Clears the in-app event listener to prevent leaks when module is deallocated or invalidated
|
|
118
|
+
func clearInAppEventListener() {
|
|
119
|
+
ReactInAppEventListener.shared.clearEventEmitter()
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/// Returns inbox instance if available, nil otherwise with error logging
|
|
123
|
+
/// Note: Notification Inbox is only available after SDK is initialized
|
|
124
|
+
private func requireInboxInstance() -> NotificationInbox? {
|
|
125
|
+
guard MessagingInApp.shared.implementation != nil else {
|
|
126
|
+
logger.error("Notification Inbox is not available. Ensure CustomerIO SDK is initialized.")
|
|
127
|
+
return nil
|
|
128
|
+
}
|
|
129
|
+
return MessagingInApp.shared.inbox
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// Parses NSDictionary to InboxMessage with error logging
|
|
133
|
+
private func parseInboxMessage(from dictionary: NSDictionary) -> InboxMessage? {
|
|
134
|
+
guard let dict = dictionary as? [String: Any],
|
|
135
|
+
let inboxMessage = InboxMessageFactory.fromDictionary(dict)
|
|
136
|
+
else {
|
|
137
|
+
logger.error("Invalid message data: \(dictionary)")
|
|
138
|
+
return nil
|
|
139
|
+
}
|
|
140
|
+
return inboxMessage
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/// Helper to validate inbox availability and message data before performing a message action
|
|
144
|
+
/// Returns early if inbox is unavailable or message data is invalid
|
|
145
|
+
private func performInboxMessageAction(
|
|
146
|
+
message: NSDictionary,
|
|
147
|
+
action: (NotificationInbox, InboxMessage) -> Void
|
|
148
|
+
) {
|
|
149
|
+
guard let inbox = requireInboxInstance() else { return }
|
|
150
|
+
guard let inboxMessage = parseInboxMessage(from: message) else { return }
|
|
151
|
+
action(inbox, inboxMessage)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/// Sets up the inbox change listener to receive real-time updates.
|
|
155
|
+
/// This method can be called multiple times safely and will only set up the listener once.
|
|
156
|
+
/// Note: Inbox must be available (SDK initialized) before this can succeed.
|
|
157
|
+
private func setupInboxChangeListener() {
|
|
158
|
+
// Only set up once to avoid duplicate listeners
|
|
159
|
+
guard messagesStreamTask == nil else {
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Check if SDK is initialized before attempting setup
|
|
164
|
+
guard let inbox = requireInboxInstance() else {
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Consume messages stream asynchronously
|
|
169
|
+
messagesStreamTask = Task { [weak self] in
|
|
170
|
+
for await messages in inbox.messages(topic: nil) {
|
|
171
|
+
guard let self else { return }
|
|
172
|
+
|
|
173
|
+
// Emit messages to React Native
|
|
174
|
+
let messagesArray = messages.map { $0.toDictionary() }
|
|
175
|
+
let payload: [String: Any] = ["messages": messagesArray]
|
|
176
|
+
self.sendInboxChangeEvent(data: payload)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private func clearInboxChangeListener() {
|
|
182
|
+
// Cancel the stream consumption task - this automatically cleans up the stream
|
|
183
|
+
messagesStreamTask?.cancel()
|
|
184
|
+
messagesStreamTask = nil
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private func sendInboxChangeEvent(data: [String: Any]) {
|
|
188
|
+
guard let emitter = objcEventEmitter else {
|
|
189
|
+
return
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let selector = Selector(("emitSubscribeToMessagesChanged:"))
|
|
193
|
+
guard emitter.responds(to: selector) else {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
_ = emitter.perform(selector, with: data as NSDictionary)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Send in-app event to React Native layer using ObjC event emitter
|
|
200
|
+
private func sendEvent(body: [String: Any]) {
|
|
201
|
+
guard let emitter = objcEventEmitter else {
|
|
202
|
+
assertionFailure("NativeMessagingInApp: ObjC event emitter is nil, cannot send in-app event")
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// New architecture: use injected ObjC event emitter from TurboModule
|
|
207
|
+
let selector = Selector(("emitOnInAppEventReceived:"))
|
|
208
|
+
guard emitter.responds(to: selector) else {
|
|
209
|
+
assertionFailure("ObjC event emitter does not respond to selector: emitOnInAppEventReceived:")
|
|
210
|
+
return
|
|
211
|
+
}
|
|
212
|
+
_ = emitter.perform(selector, with: body as NSDictionary)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import CioInternalCommon
|
|
2
|
+
import CioMessagingInApp
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* React Native bridge for Customer.io in-app messaging events.
|
|
6
|
+
* Converts native SDK events to JavaScript compatible format.
|
|
7
|
+
*/
|
|
8
|
+
public class ReactInAppEventListener: InAppEventListener {
|
|
9
|
+
// Shared instance for global access
|
|
10
|
+
public static let shared = ReactInAppEventListener()
|
|
11
|
+
|
|
12
|
+
private init() {
|
|
13
|
+
// Registers in DI graph so it can be accessed by Expo without using direct imports and
|
|
14
|
+
// using common import and DI graph from native iOS SDK
|
|
15
|
+
DIGraphShared.shared.override(value: self, forType: InAppEventListener.self)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Event emitter function to send events to React Native layer
|
|
19
|
+
private var eventEmitter: (([String: Any?]) -> Void)?
|
|
20
|
+
|
|
21
|
+
// Sets the event emitter function
|
|
22
|
+
func setEventEmitter(_ emitter: (([String: Any?]) -> Void)?) {
|
|
23
|
+
eventEmitter = emitter
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Clears the event emitter to prevent memory leaks
|
|
27
|
+
func clearEventEmitter() {
|
|
28
|
+
eventEmitter = nil
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Emits an in-app message event to React Native with unified event structure
|
|
32
|
+
private func emitInAppEvent(
|
|
33
|
+
eventType: String,
|
|
34
|
+
message: InAppMessage,
|
|
35
|
+
actionValue: String? = nil,
|
|
36
|
+
actionName: String? = nil
|
|
37
|
+
) {
|
|
38
|
+
var data: [String: Any?] = [
|
|
39
|
+
CustomerioConstants.eventType: eventType,
|
|
40
|
+
CustomerioConstants.messageId: message.messageId,
|
|
41
|
+
CustomerioConstants.deliveryId: message.deliveryId
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
if let actionValue = actionValue {
|
|
45
|
+
data[CustomerioConstants.actionValue] = actionValue
|
|
46
|
+
}
|
|
47
|
+
if let actionName = actionName {
|
|
48
|
+
data[CustomerioConstants.actionName] = actionName
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
eventEmitter?(data)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public func messageShown(message: InAppMessage) {
|
|
55
|
+
emitInAppEvent(eventType: CustomerioConstants.messageShown, message: message)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public func messageDismissed(message: InAppMessage) {
|
|
59
|
+
emitInAppEvent(eventType: CustomerioConstants.messageDismissed, message: message)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public func errorWithMessage(message: InAppMessage) {
|
|
63
|
+
emitInAppEvent(eventType: CustomerioConstants.errorWithMessage, message: message)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
public func messageActionTaken(message: InAppMessage, actionValue: String, actionName: String) {
|
|
67
|
+
emitInAppEvent(
|
|
68
|
+
eventType: CustomerioConstants.messageActionTaken,
|
|
69
|
+
message: message,
|
|
70
|
+
actionValue: actionValue,
|
|
71
|
+
actionName: actionName
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// States representing the loading and display status of inline messages.
|
|
4
|
+
/// This enum mirrors TypeScript InlineMessageState enum for consistency.
|
|
5
|
+
@objc enum InlineInAppMessageStateEvent: Int, CaseIterable {
|
|
6
|
+
case loadingStarted
|
|
7
|
+
case loadingFinished
|
|
8
|
+
case noMessageToDisplay
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Returns the string representation of the state that matches TypeScript enum values.
|
|
12
|
+
*/
|
|
13
|
+
var stringValue: String {
|
|
14
|
+
switch self {
|
|
15
|
+
case .loadingStarted:
|
|
16
|
+
return "LoadingStarted"
|
|
17
|
+
case .loadingFinished:
|
|
18
|
+
return "LoadingFinished"
|
|
19
|
+
case .noMessageToDisplay:
|
|
20
|
+
return "NoMessageToDisplay"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// RCTViewComponentView.h transitively includes C++ code from React Native's Fabric renderer.
|
|
2
|
+
// When this header is imported from an Objective-C (.h) file, certain build phases
|
|
3
|
+
// (e.g., Clang dependency scanning, Swift bridging, and module indexing) parse it in
|
|
4
|
+
// pure Objective-C mode, where C++ constructs are not allowed.
|
|
5
|
+
//
|
|
6
|
+
// Wrapping the import in `#ifdef __cplusplus` ensures it is only visible when the file
|
|
7
|
+
// is compiled in Objective-C++ mode (.mm), preventing build failures.
|
|
8
|
+
#ifdef __cplusplus
|
|
9
|
+
#import <React/RCTViewComponentView.h>
|
|
10
|
+
#import <UIKit/UIKit.h>
|
|
11
|
+
|
|
12
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
13
|
+
|
|
14
|
+
@interface RCTInlineMessageNative : RCTViewComponentView
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
NS_ASSUME_NONNULL_END
|
|
18
|
+
#endif
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#import "RCTInlineMessageNative.h"
|
|
2
|
+
#import "ReactInlineMessageView.h"
|
|
3
|
+
|
|
4
|
+
#import <React/RCTConversions.h>
|
|
5
|
+
#import <React/RCTFabricComponentsPlugins.h>
|
|
6
|
+
#import <react/renderer/components/RNZixflowSpec/ComponentDescriptors.h>
|
|
7
|
+
#import <react/renderer/components/RNZixflowSpec/EventEmitters.h>
|
|
8
|
+
#import <react/renderer/components/RNZixflowSpec/Props.h>
|
|
9
|
+
#import <react/renderer/components/RNZixflowSpec/RCTComponentViewHelpers.h>
|
|
10
|
+
#import <react/renderer/components/RNZixflowSpec/ShadowNodes.h>
|
|
11
|
+
|
|
12
|
+
using namespace facebook::react;
|
|
13
|
+
|
|
14
|
+
/// New architecture React Native view for inline messages
|
|
15
|
+
@interface RCTInlineMessageNative () <RCTInlineMessageNativeViewProtocol>
|
|
16
|
+
/// Bridge to Swift ReactInlineMessageView for platform-agnostic implementation
|
|
17
|
+
@property(nonatomic, strong) id bridge;
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
@implementation RCTInlineMessageNative
|
|
21
|
+
|
|
22
|
+
- (void)assertBridgeAvailable:(NSString *)context {
|
|
23
|
+
NSAssert(self.bridge != nil, @"Bridge is nil when %@", context);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
- (instancetype)init {
|
|
27
|
+
return [self initWithFrame:CGRectZero];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
31
|
+
if (self = [super initWithFrame:frame]) {
|
|
32
|
+
_props = InlineMessageNativeShadowNode::defaultSharedProps();
|
|
33
|
+
|
|
34
|
+
Class bridgeClass = NSClassFromString(@"ReactInlineMessageView");
|
|
35
|
+
if (bridgeClass) {
|
|
36
|
+
self.bridge = [[bridgeClass alloc] initWithContainerView:self];
|
|
37
|
+
[self assertBridgeAvailable:@"creating ReactInlineMessageView bridge instance"];
|
|
38
|
+
[self.bridge setEventEmitter:self];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
45
|
+
const auto &newViewProps = *std::static_pointer_cast<InlineMessageNativeProps const>(props);
|
|
46
|
+
|
|
47
|
+
[self assertBridgeAvailable:@"during updateProps"];
|
|
48
|
+
[self.bridge setupForReuse];
|
|
49
|
+
|
|
50
|
+
// On first mount Fabric passes oldProps = nullptr; apply all props unconditionally.
|
|
51
|
+
// On updates, diff against the parameter rather than _props so we never rely on
|
|
52
|
+
// the ivar's runtime type.
|
|
53
|
+
BOOL elementIdChanged = YES;
|
|
54
|
+
if (oldProps) {
|
|
55
|
+
const auto &oldViewProps = *std::static_pointer_cast<InlineMessageNativeProps const>(oldProps);
|
|
56
|
+
elementIdChanged = oldViewProps.elementId != newViewProps.elementId;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (elementIdChanged) {
|
|
60
|
+
NSString *elementId = [NSString stringWithCString:newViewProps.elementId.c_str() encoding:NSUTF8StringEncoding];
|
|
61
|
+
[self assertBridgeAvailable:@"updating elementId prop"];
|
|
62
|
+
[self.bridge setElementId:elementId];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[super updateProps:props oldProps:oldProps];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- (void)layoutSubviews {
|
|
69
|
+
[super layoutSubviews];
|
|
70
|
+
[self assertBridgeAvailable:@"during layoutSubviews"];
|
|
71
|
+
[self.bridge updateLayout:[NSValue valueWithCGRect:self.bounds]];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
- (void)prepareForRecycle {
|
|
75
|
+
[super prepareForRecycle];
|
|
76
|
+
[self assertBridgeAvailable:@"during prepareForRecycle"];
|
|
77
|
+
[self.bridge prepareForRecycle];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
- (void)emitOnSizeChangeEvent:(NSDictionary *)event {
|
|
81
|
+
[self handleOnSizeChangeEvent:event];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
- (void)emitOnStateChangeEvent:(NSDictionary *)event {
|
|
85
|
+
[self handleOnStateChangeEvent:event];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
- (void)emitOnActionClickEvent:(NSDictionary *)event {
|
|
89
|
+
[self handleOnActionClickEvent:event];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
- (void)handleOnSizeChangeEvent:(NSDictionary *)event {
|
|
93
|
+
if (_eventEmitter) {
|
|
94
|
+
InlineMessageNativeEventEmitter::OnSizeChange result = InlineMessageNativeEventEmitter::OnSizeChange{};
|
|
95
|
+
|
|
96
|
+
if (event[@"width"]) {
|
|
97
|
+
result.width = [event[@"width"] doubleValue];
|
|
98
|
+
}
|
|
99
|
+
if (event[@"height"]) {
|
|
100
|
+
result.height = [event[@"height"] doubleValue];
|
|
101
|
+
}
|
|
102
|
+
if (event[@"duration"]) {
|
|
103
|
+
result.duration = [event[@"duration"] doubleValue];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
self.eventEmitter.onSizeChange(result);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
- (void)handleOnStateChangeEvent:(NSDictionary *)event {
|
|
111
|
+
if (_eventEmitter) {
|
|
112
|
+
InlineMessageNativeEventEmitter::OnStateChange result = InlineMessageNativeEventEmitter::OnStateChange{};
|
|
113
|
+
|
|
114
|
+
if (event[@"state"]) {
|
|
115
|
+
result.state = std::string([[event[@"state"] description] UTF8String]);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
self.eventEmitter.onStateChange(result);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
- (void)handleOnActionClickEvent:(NSDictionary *)event {
|
|
123
|
+
if (_eventEmitter) {
|
|
124
|
+
InlineMessageNativeEventEmitter::OnActionClick result = InlineMessageNativeEventEmitter::OnActionClick{};
|
|
125
|
+
|
|
126
|
+
if (event[@"message"]) {
|
|
127
|
+
NSDictionary *message = event[@"message"];
|
|
128
|
+
InlineMessageNativeEventEmitter::OnActionClickMessage messageStruct =
|
|
129
|
+
InlineMessageNativeEventEmitter::OnActionClickMessage{};
|
|
130
|
+
|
|
131
|
+
if (message[@"messageId"]) {
|
|
132
|
+
messageStruct.messageId = std::string([[message[@"messageId"] description] UTF8String]);
|
|
133
|
+
}
|
|
134
|
+
if (message[@"deliveryId"] && message[@"deliveryId"] != [NSNull null]) {
|
|
135
|
+
messageStruct.deliveryId = std::string([[message[@"deliveryId"] description] UTF8String]);
|
|
136
|
+
}
|
|
137
|
+
if (message[@"elementId"] && message[@"elementId"] != [NSNull null]) {
|
|
138
|
+
messageStruct.elementId = std::string([[message[@"elementId"] description] UTF8String]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
result.message = messageStruct;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (event[@"actionValue"]) {
|
|
145
|
+
result.actionValue = std::string([[event[@"actionValue"] description] UTF8String]);
|
|
146
|
+
}
|
|
147
|
+
if (event[@"actionName"]) {
|
|
148
|
+
result.actionName = std::string([[event[@"actionName"] description] UTF8String]);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
self.eventEmitter.onActionClick(result);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Event emitter convenience method
|
|
156
|
+
- (const InlineMessageNativeEventEmitter &)eventEmitter {
|
|
157
|
+
return static_cast<const InlineMessageNativeEventEmitter &>(*_eventEmitter);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
161
|
+
return concreteComponentDescriptorProvider<InlineMessageNativeComponentDescriptor>();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@end
|
|
165
|
+
|
|
166
|
+
Class<RCTComponentViewProtocol> InlineMessageNativeCls(void) {
|
|
167
|
+
return RCTInlineMessageNative.class;
|
|
168
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
@class UIView;
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Objective-C header for Swift ReactInlineMessageView class.
|
|
9
|
+
*
|
|
10
|
+
* This header provides a forward declaration for Swift interop without requiring
|
|
11
|
+
* Swift module headers, which can cause compilation issues in mixed static/dynamic
|
|
12
|
+
* linking configurations (e.g., FCM vs APN push providers).
|
|
13
|
+
*
|
|
14
|
+
* The actual Swift implementation is in ReactInlineMessageView.swift.
|
|
15
|
+
* This header provides method declarations for compile-time safety while using
|
|
16
|
+
* runtime class resolution (NSClassFromString) for the Swift bridge.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/// Forward declaration of ReactInlineMessageView Swift class
|
|
20
|
+
@interface ReactInlineMessageView : NSObject
|
|
21
|
+
|
|
22
|
+
/// Initializes the view with a container view
|
|
23
|
+
- (instancetype)initWithContainerView:(UIView *)containerView;
|
|
24
|
+
|
|
25
|
+
/// Sets the event emitter for React Native communication
|
|
26
|
+
- (void)setEventEmitter:(id)eventEmitter;
|
|
27
|
+
|
|
28
|
+
/// Sets the element ID for the inline message
|
|
29
|
+
- (void)setElementId:(NSString *)elementId;
|
|
30
|
+
|
|
31
|
+
/// Prepares the view for reuse in React Native lifecycle
|
|
32
|
+
- (void)setupForReuse;
|
|
33
|
+
|
|
34
|
+
/// Updates the view layout with new bounds
|
|
35
|
+
- (void)updateLayout:(NSValue *)boundsValue;
|
|
36
|
+
|
|
37
|
+
/// Prepares the view for recycling
|
|
38
|
+
- (void)prepareForRecycle;
|
|
39
|
+
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
NS_ASSUME_NONNULL_END
|