zixflow-reactnative 1.1.2 → 1.1.4
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/README.md +2224 -322
- package/android/build.gradle +18 -1
- package/android/consumer-rules.pro +3 -2
- package/android/gradle.properties +1 -1
- package/android/src/main/java/com/zixflow/reactnative/sdk/NativeZixflowModule.kt +69 -24
- package/android/src/main/java/com/zixflow/reactnative/sdk/ZixflowReactNativePackage.kt +25 -1
- package/android/src/main/java/com/zixflow/reactnative/sdk/constant/Keys.kt +19 -3
- package/android/src/main/java/com/zixflow/reactnative/sdk/geofence/NativeGeofenceModule.kt +65 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/liveactivities/NativeLiveActivitiesModule.kt +310 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/logging/NativeZixflowLoggingModule.kt +2 -2
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginapp/NativeMessagingInAppModule.kt +149 -10
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginapp/ReactInboxEventListener.kt +99 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/NotificationInboxBellViewManager.kt +38 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/NotificationInboxViewManager.kt +30 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactComposeHostView.kt +96 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactNotificationInboxBellView.kt +48 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginbox/ReactNotificationInboxView.kt +17 -0
- package/android/src/main/java/com/zixflow/reactnative/sdk/messagingpush/NativeMessagingPushModule.kt +11 -1
- package/android/src/main/res/values/zixflow_config.xml +1 -1
- package/android/zixflow-core.gradle +17 -7
- package/docs/cocoapods-deployment-target-normalization.md +139 -0
- package/ios/cocoapods_deployment_target.rb +432 -0
- package/ios/wrappers/NativeZixflow.mm +37 -0
- package/ios/wrappers/NativeZixflow.swift +135 -1
- package/ios/wrappers/ZixflowReactNativeDeepLinkRequestStore.swift +123 -0
- package/ios/wrappers/ZixflowReactNativeDeepLinkRouter.swift +312 -0
- package/ios/wrappers/geofence/NativeGeofence.mm +46 -0
- package/ios/wrappers/geofence/NativeGeofence.swift +27 -0
- package/ios/wrappers/inapp/NativeMessagingInApp.mm +22 -0
- package/ios/wrappers/inapp/NativeMessagingInApp.swift +90 -0
- package/ios/wrappers/inbox/InboxHostContainment.swift +40 -0
- package/ios/wrappers/inbox/RCTNotificationInboxBellNative.h +12 -0
- package/ios/wrappers/inbox/RCTNotificationInboxBellNative.mm +98 -0
- package/ios/wrappers/inbox/RCTNotificationInboxViewNative.h +12 -0
- package/ios/wrappers/inbox/RCTNotificationInboxViewNative.mm +78 -0
- package/ios/wrappers/inbox/ReactInboxEventListener.swift +76 -0
- package/ios/wrappers/inbox/ReactNotificationInboxBellView.h +22 -0
- package/ios/wrappers/inbox/ReactNotificationInboxBellView.swift +109 -0
- package/ios/wrappers/inbox/ReactNotificationInboxView.h +22 -0
- package/ios/wrappers/inbox/ReactNotificationInboxView.swift +69 -0
- package/ios/wrappers/liveactivities/NativeLiveActivities.mm +83 -0
- package/ios/wrappers/liveactivities/NativeLiveActivities.swift +390 -0
- package/ios/wrappers/location/NativeLocation.swift +7 -5
- package/ios/wrappers/utils/ZixflowConfigUtils.swift +5 -9
- package/ios/wrappers/utils/ZixflowConstants.swift +4 -0
- package/ios/wrappers/zixflow_reactnative.h +6 -0
- package/lib/commonjs/components/NotificationInboxBellView.js +49 -0
- package/lib/commonjs/components/NotificationInboxBellView.js.map +1 -0
- package/lib/commonjs/components/NotificationInboxView.js +36 -0
- package/lib/commonjs/components/NotificationInboxView.js.map +1 -0
- package/lib/commonjs/components/index.js +14 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/index.js +81 -4
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/notification-inbox.js +1 -0
- package/lib/commonjs/notification-inbox.js.map +1 -1
- package/lib/commonjs/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
- package/lib/commonjs/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
- package/lib/commonjs/specs/modules/NativeZixflow.js.map +1 -1
- package/lib/commonjs/specs/modules/NativeZixflowGeofence.js +15 -0
- package/lib/commonjs/specs/modules/NativeZixflowGeofence.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeZixflowLiveActivities.js +23 -0
- package/lib/commonjs/specs/modules/NativeZixflowLiveActivities.js.map +1 -0
- package/lib/commonjs/specs/modules/NativeZixflowMessagingInApp.js +3 -1
- package/lib/commonjs/specs/modules/NativeZixflowMessagingInApp.js.map +1 -1
- package/lib/commonjs/specs/modules/NativeZixflowMessagingPush.js +3 -1
- package/lib/commonjs/specs/modules/NativeZixflowMessagingPush.js.map +1 -1
- package/lib/commonjs/types/data-pipelines.js +15 -15
- package/lib/commonjs/types/data-pipelines.js.map +1 -1
- package/lib/commonjs/types/in-app.js +24 -1
- package/lib/commonjs/types/in-app.js.map +1 -1
- package/lib/commonjs/types/inbox.js +79 -0
- package/lib/commonjs/types/inbox.js.map +1 -0
- package/lib/commonjs/types/index.js +22 -0
- package/lib/commonjs/types/index.js.map +1 -1
- package/lib/commonjs/types/live-activities.js +85 -0
- package/lib/commonjs/types/live-activities.js.map +1 -0
- package/lib/commonjs/utils/param-validation.js +77 -2
- package/lib/commonjs/utils/param-validation.js.map +1 -1
- package/lib/commonjs/zixflow-cdp.js +101 -11
- package/lib/commonjs/zixflow-cdp.js.map +1 -1
- package/lib/commonjs/zixflow-geofence.js +55 -0
- package/lib/commonjs/zixflow-geofence.js.map +1 -0
- package/lib/commonjs/zixflow-inapp.js +120 -0
- package/lib/commonjs/zixflow-inapp.js.map +1 -1
- package/lib/commonjs/zixflow-liveactivities.js +85 -0
- package/lib/commonjs/zixflow-liveactivities.js.map +1 -0
- package/lib/commonjs/zixflow.js.map +1 -1
- package/lib/module/components/NotificationInboxBellView.js +44 -0
- package/lib/module/components/NotificationInboxBellView.js.map +1 -0
- package/lib/module/components/NotificationInboxView.js +31 -0
- package/lib/module/components/NotificationInboxView.js.map +1 -0
- package/lib/module/components/index.js +5 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/index.js +8 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/notification-inbox.js +1 -1
- package/lib/module/notification-inbox.js.map +1 -1
- package/lib/module/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
- package/lib/module/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
- package/lib/module/specs/modules/NativeZixflow.js.map +1 -1
- package/lib/module/specs/modules/NativeZixflowGeofence.js +13 -0
- package/lib/module/specs/modules/NativeZixflowGeofence.js.map +1 -0
- package/lib/module/specs/modules/NativeZixflowLiveActivities.js +21 -0
- package/lib/module/specs/modules/NativeZixflowLiveActivities.js.map +1 -0
- package/lib/module/specs/modules/NativeZixflowMessagingInApp.js +3 -1
- package/lib/module/specs/modules/NativeZixflowMessagingInApp.js.map +1 -1
- package/lib/module/specs/modules/NativeZixflowMessagingPush.js +3 -1
- package/lib/module/specs/modules/NativeZixflowMessagingPush.js.map +1 -1
- package/lib/module/types/data-pipelines.js +15 -15
- package/lib/module/types/data-pipelines.js.map +1 -1
- package/lib/module/types/in-app.js +24 -0
- package/lib/module/types/in-app.js.map +1 -1
- package/lib/module/types/inbox.js +75 -0
- package/lib/module/types/inbox.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -1
- package/lib/module/types/live-activities.js +88 -0
- package/lib/module/types/live-activities.js.map +1 -0
- package/lib/module/utils/param-validation.js +77 -2
- package/lib/module/utils/param-validation.js.map +1 -1
- package/lib/module/zixflow-cdp.js +101 -11
- package/lib/module/zixflow-cdp.js.map +1 -1
- package/lib/module/zixflow-geofence.js +50 -0
- package/lib/module/zixflow-geofence.js.map +1 -0
- package/lib/module/zixflow-inapp.js +99 -1
- package/lib/module/zixflow-inapp.js.map +1 -1
- package/lib/module/zixflow-liveactivities.js +80 -0
- package/lib/module/zixflow-liveactivities.js.map +1 -0
- package/lib/module/zixflow.js +0 -6
- package/lib/module/zixflow.js.map +1 -1
- package/lib/typescript/commonjs/components/NotificationInboxBellView.d.ts +39 -0
- package/lib/typescript/commonjs/components/NotificationInboxBellView.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/NotificationInboxView.d.ts +25 -0
- package/lib/typescript/commonjs/components/NotificationInboxView.d.ts.map +1 -0
- package/lib/typescript/commonjs/components/index.d.ts +4 -0
- package/lib/typescript/commonjs/components/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +8 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/notification-inbox.d.ts +5 -0
- package/lib/typescript/commonjs/notification-inbox.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/components/NotificationInboxBellNativeComponent.d.ts +13 -0
- package/lib/typescript/commonjs/specs/components/NotificationInboxBellNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/components/NotificationInboxViewNativeComponent.d.ts +12 -0
- package/lib/typescript/commonjs/specs/components/NotificationInboxViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeZixflow.d.ts +6 -1
- package/lib/typescript/commonjs/specs/modules/NativeZixflow.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/modules/NativeZixflowGeofence.d.ts +13 -0
- package/lib/typescript/commonjs/specs/modules/NativeZixflowGeofence.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeZixflowLiveActivities.d.ts +31 -0
- package/lib/typescript/commonjs/specs/modules/NativeZixflowLiveActivities.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingInApp.d.ts +5 -1
- package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingInApp.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingPush.d.ts +1 -1
- package/lib/typescript/commonjs/specs/modules/NativeZixflowMessagingPush.d.ts.map +1 -1
- package/lib/typescript/commonjs/types/data-pipelines.d.ts +54 -18
- package/lib/typescript/commonjs/types/data-pipelines.d.ts.map +1 -1
- package/lib/typescript/commonjs/types/in-app.d.ts +22 -0
- package/lib/typescript/commonjs/types/in-app.d.ts.map +1 -1
- package/lib/typescript/commonjs/types/inbox.d.ts +97 -0
- package/lib/typescript/commonjs/types/inbox.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/index.d.ts +2 -0
- package/lib/typescript/commonjs/types/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/types/live-activities.d.ts +161 -0
- package/lib/typescript/commonjs/types/live-activities.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/param-validation.d.ts +7 -0
- package/lib/typescript/commonjs/utils/param-validation.d.ts.map +1 -1
- package/lib/typescript/commonjs/zixflow-cdp.d.ts +38 -0
- package/lib/typescript/commonjs/zixflow-cdp.d.ts.map +1 -1
- package/lib/typescript/commonjs/zixflow-geofence.d.ts +36 -0
- package/lib/typescript/commonjs/zixflow-geofence.d.ts.map +1 -0
- package/lib/typescript/commonjs/zixflow-inapp.d.ts +36 -2
- package/lib/typescript/commonjs/zixflow-inapp.d.ts.map +1 -1
- package/lib/typescript/commonjs/zixflow-liveactivities.d.ts +66 -0
- package/lib/typescript/commonjs/zixflow-liveactivities.d.ts.map +1 -0
- package/lib/typescript/commonjs/zixflow.d.ts +0 -5
- package/lib/typescript/commonjs/zixflow.d.ts.map +1 -1
- package/lib/typescript/module/components/NotificationInboxBellView.d.ts +39 -0
- package/lib/typescript/module/components/NotificationInboxBellView.d.ts.map +1 -0
- package/lib/typescript/module/components/NotificationInboxView.d.ts +25 -0
- package/lib/typescript/module/components/NotificationInboxView.d.ts.map +1 -0
- package/lib/typescript/module/components/index.d.ts +4 -0
- package/lib/typescript/module/components/index.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +8 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/notification-inbox.d.ts +5 -0
- package/lib/typescript/module/notification-inbox.d.ts.map +1 -1
- package/lib/typescript/module/specs/components/NotificationInboxBellNativeComponent.d.ts +13 -0
- package/lib/typescript/module/specs/components/NotificationInboxBellNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/specs/components/NotificationInboxViewNativeComponent.d.ts +12 -0
- package/lib/typescript/module/specs/components/NotificationInboxViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeZixflow.d.ts +6 -1
- package/lib/typescript/module/specs/modules/NativeZixflow.d.ts.map +1 -1
- package/lib/typescript/module/specs/modules/NativeZixflowGeofence.d.ts +13 -0
- package/lib/typescript/module/specs/modules/NativeZixflowGeofence.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeZixflowLiveActivities.d.ts +31 -0
- package/lib/typescript/module/specs/modules/NativeZixflowLiveActivities.d.ts.map +1 -0
- package/lib/typescript/module/specs/modules/NativeZixflowMessagingInApp.d.ts +5 -1
- package/lib/typescript/module/specs/modules/NativeZixflowMessagingInApp.d.ts.map +1 -1
- package/lib/typescript/module/specs/modules/NativeZixflowMessagingPush.d.ts +1 -1
- package/lib/typescript/module/specs/modules/NativeZixflowMessagingPush.d.ts.map +1 -1
- package/lib/typescript/module/types/data-pipelines.d.ts +54 -18
- package/lib/typescript/module/types/data-pipelines.d.ts.map +1 -1
- package/lib/typescript/module/types/in-app.d.ts +22 -0
- package/lib/typescript/module/types/in-app.d.ts.map +1 -1
- package/lib/typescript/module/types/inbox.d.ts +97 -0
- package/lib/typescript/module/types/inbox.d.ts.map +1 -0
- package/lib/typescript/module/types/index.d.ts +2 -0
- package/lib/typescript/module/types/index.d.ts.map +1 -1
- package/lib/typescript/module/types/live-activities.d.ts +161 -0
- package/lib/typescript/module/types/live-activities.d.ts.map +1 -0
- package/lib/typescript/module/utils/param-validation.d.ts +7 -0
- package/lib/typescript/module/utils/param-validation.d.ts.map +1 -1
- package/lib/typescript/module/zixflow-cdp.d.ts +38 -0
- package/lib/typescript/module/zixflow-cdp.d.ts.map +1 -1
- package/lib/typescript/module/zixflow-geofence.d.ts +36 -0
- package/lib/typescript/module/zixflow-geofence.d.ts.map +1 -0
- package/lib/typescript/module/zixflow-inapp.d.ts +36 -2
- package/lib/typescript/module/zixflow-inapp.d.ts.map +1 -1
- package/lib/typescript/module/zixflow-liveactivities.d.ts +66 -0
- package/lib/typescript/module/zixflow-liveactivities.d.ts.map +1 -0
- package/lib/typescript/module/zixflow.d.ts +0 -5
- package/lib/typescript/module/zixflow.d.ts.map +1 -1
- package/package.json +14 -5
- package/src/components/NotificationInboxBellView.tsx +55 -0
- package/src/components/NotificationInboxView.tsx +30 -0
- package/src/components/index.ts +6 -0
- package/src/index.ts +8 -3
- package/src/notification-inbox.ts +1 -1
- package/src/specs/components/NotificationInboxBellNativeComponent.ts +24 -0
- package/src/specs/components/NotificationInboxViewNativeComponent.ts +22 -0
- package/src/specs/modules/NativeZixflow.ts +9 -1
- package/src/specs/modules/NativeZixflowGeofence.ts +14 -0
- package/src/specs/modules/NativeZixflowLiveActivities.ts +39 -0
- package/src/specs/modules/NativeZixflowMessagingInApp.ts +12 -1
- package/src/specs/modules/NativeZixflowMessagingPush.ts +3 -1
- package/src/types/data-pipelines.ts +55 -19
- package/src/types/in-app.ts +23 -0
- package/src/types/inbox.ts +110 -0
- package/src/types/index.ts +2 -0
- package/src/types/live-activities.ts +170 -0
- package/src/utils/param-validation.ts +104 -1
- package/src/zixflow-cdp.ts +119 -13
- package/src/zixflow-geofence.ts +56 -0
- package/src/zixflow-inapp.ts +125 -2
- package/src/zixflow-liveactivities.ts +86 -0
- package/src/zixflow.ts +0 -6
- package/zixflow-reactnative-richpush.podspec +6 -3
- package/zixflow-reactnative.podspec +28 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// See RCTInlineMessageNative.h for why this RCTViewComponentView import is guarded by __cplusplus.
|
|
2
|
+
#ifdef __cplusplus
|
|
3
|
+
#import <React/RCTViewComponentView.h>
|
|
4
|
+
#import <UIKit/UIKit.h>
|
|
5
|
+
|
|
6
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
7
|
+
|
|
8
|
+
@interface RCTNotificationInboxBellNative : RCTViewComponentView
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_END
|
|
12
|
+
#endif
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#import "RCTNotificationInboxBellNative.h"
|
|
2
|
+
#import "ReactNotificationInboxBellView.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 hosting the SwiftUI NotificationInboxBell.
|
|
15
|
+
@interface RCTNotificationInboxBellNative () <RCTNotificationInboxBellNativeViewProtocol>
|
|
16
|
+
@property(nonatomic, strong) id bridge;
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation RCTNotificationInboxBellNative
|
|
20
|
+
|
|
21
|
+
- (void)assertBridgeAvailable:(NSString *)context {
|
|
22
|
+
NSAssert(self.bridge != nil, @"Bridge is nil when %@", context);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
- (instancetype)init {
|
|
26
|
+
return [self initWithFrame:CGRectZero];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (instancetype)initWithFrame:(CGRect)frame {
|
|
30
|
+
if (self = [super initWithFrame:frame]) {
|
|
31
|
+
_props = NotificationInboxBellNativeShadowNode::defaultSharedProps();
|
|
32
|
+
|
|
33
|
+
// The Swift bridge is @available(iOS 16.0, *) because the bell opens the SDK's inbox sheet, which
|
|
34
|
+
// uses system detents. Below iOS 16 the class exists but must not be instantiated, so the view
|
|
35
|
+
// stays empty rather than crashing — every method below therefore tolerates a nil bridge.
|
|
36
|
+
if (@available(iOS 16.0, *)) {
|
|
37
|
+
Class bridgeClass = NSClassFromString(@"ReactNotificationInboxBellView");
|
|
38
|
+
if (bridgeClass) {
|
|
39
|
+
self.bridge = [[bridgeClass alloc] initWithContainerView:self];
|
|
40
|
+
[self assertBridgeAvailable:@"creating ReactNotificationInboxBellView bridge instance"];
|
|
41
|
+
[self.bridge setEventEmitter:self];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return self;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
- (void)layoutSubviews {
|
|
49
|
+
[super layoutSubviews];
|
|
50
|
+
if (self.bridge == nil) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
[self.bridge updateLayout:[NSValue valueWithCGRect:self.bounds]];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Containment can only happen once the view is in a window: React Native creates component views
|
|
57
|
+
// before mounting them, so at init there is no parent view controller to attach the host to.
|
|
58
|
+
- (void)didMoveToWindow {
|
|
59
|
+
[super didMoveToWindow];
|
|
60
|
+
if (self.bridge == nil) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (self.window != nil) {
|
|
64
|
+
[self.bridge attachToParentViewController];
|
|
65
|
+
} else {
|
|
66
|
+
[self.bridge detachFromParentViewController];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
- (void)prepareForRecycle {
|
|
71
|
+
[super prepareForRecycle];
|
|
72
|
+
if (self.bridge == nil) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
[self.bridge prepareForRecycle];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
- (void)emitOnTapEvent:(NSDictionary *)event {
|
|
79
|
+
if (_eventEmitter) {
|
|
80
|
+
NotificationInboxBellNativeEventEmitter::OnTap result =
|
|
81
|
+
NotificationInboxBellNativeEventEmitter::OnTap{};
|
|
82
|
+
self.eventEmitter.onTap(result);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
- (const NotificationInboxBellNativeEventEmitter &)eventEmitter {
|
|
87
|
+
return static_cast<const NotificationInboxBellNativeEventEmitter &>(*_eventEmitter);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
91
|
+
return concreteComponentDescriptorProvider<NotificationInboxBellNativeComponentDescriptor>();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@end
|
|
95
|
+
|
|
96
|
+
Class<RCTComponentViewProtocol> NotificationInboxBellNativeCls(void) {
|
|
97
|
+
return RCTNotificationInboxBellNative.class;
|
|
98
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// See RCTInlineMessageNative.h for why this RCTViewComponentView import is guarded by __cplusplus.
|
|
2
|
+
#ifdef __cplusplus
|
|
3
|
+
#import <React/RCTViewComponentView.h>
|
|
4
|
+
#import <UIKit/UIKit.h>
|
|
5
|
+
|
|
6
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
7
|
+
|
|
8
|
+
@interface RCTNotificationInboxViewNative : RCTViewComponentView
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
NS_ASSUME_NONNULL_END
|
|
12
|
+
#endif
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#import "RCTNotificationInboxViewNative.h"
|
|
2
|
+
#import "ReactNotificationInboxView.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 hosting the SwiftUI NotificationInboxView (message list).
|
|
15
|
+
/// This view emits no events; message actions flow through the existing global InboxEventListener.
|
|
16
|
+
@interface RCTNotificationInboxViewNative () <RCTNotificationInboxViewNativeViewProtocol>
|
|
17
|
+
@property(nonatomic, strong) id bridge;
|
|
18
|
+
@end
|
|
19
|
+
|
|
20
|
+
@implementation RCTNotificationInboxViewNative
|
|
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 = NotificationInboxViewNativeShadowNode::defaultSharedProps();
|
|
33
|
+
|
|
34
|
+
Class bridgeClass = NSClassFromString(@"ReactNotificationInboxView");
|
|
35
|
+
if (bridgeClass) {
|
|
36
|
+
self.bridge = [[bridgeClass alloc] initWithContainerView:self];
|
|
37
|
+
[self assertBridgeAvailable:@"creating ReactNotificationInboxView bridge instance"];
|
|
38
|
+
[self.bridge setEventEmitter:self];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (void)layoutSubviews {
|
|
45
|
+
[super layoutSubviews];
|
|
46
|
+
[self assertBridgeAvailable:@"during layoutSubviews"];
|
|
47
|
+
[self.bridge updateLayout:[NSValue valueWithCGRect:self.bounds]];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Containment can only happen once the view is in a window: React Native creates component views
|
|
51
|
+
// before mounting them, so at init there is no parent view controller to attach the host to. The list
|
|
52
|
+
// presents nothing, but containment is what gives the hosted SwiftUI a correct trait/safe-area chain
|
|
53
|
+
// and lifecycle callbacks.
|
|
54
|
+
- (void)didMoveToWindow {
|
|
55
|
+
[super didMoveToWindow];
|
|
56
|
+
[self assertBridgeAvailable:@"during didMoveToWindow"];
|
|
57
|
+
if (self.window != nil) {
|
|
58
|
+
[self.bridge attachToParentViewController];
|
|
59
|
+
} else {
|
|
60
|
+
[self.bridge detachFromParentViewController];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (void)prepareForRecycle {
|
|
65
|
+
[super prepareForRecycle];
|
|
66
|
+
[self assertBridgeAvailable:@"during prepareForRecycle"];
|
|
67
|
+
[self.bridge prepareForRecycle];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider {
|
|
71
|
+
return concreteComponentDescriptorProvider<NotificationInboxViewNativeComponentDescriptor>();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@end
|
|
75
|
+
|
|
76
|
+
Class<RCTComponentViewProtocol> NotificationInboxViewNativeCls(void) {
|
|
77
|
+
return RCTNotificationInboxViewNative.class;
|
|
78
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import ZixflowInternalCommon
|
|
2
|
+
import ZixflowMessagingInApp
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* React Native bridge for Zixflow Visual Notification Inbox events.
|
|
6
|
+
*
|
|
7
|
+
* Registered on the SDK (via `MessagingInApp.shared.setInboxEventListener`) only while a JS listener
|
|
8
|
+
* is registered. Because the New-Arch event emitter is one-way we cannot round-trip a bool back from
|
|
9
|
+
* JS, so `messageActionTaken` forwards the event fire-and-forget and RETURNS `true` — telling the SDK
|
|
10
|
+
* the host handled the action so the SDK suppresses its default navigation. The JS host owns action
|
|
11
|
+
* handling while a listener is registered. Observational callbacks forward fire-and-forget.
|
|
12
|
+
*/
|
|
13
|
+
public class ReactInboxEventListener: InboxEventListener {
|
|
14
|
+
// Shared instance for global access
|
|
15
|
+
public static let shared = ReactInboxEventListener()
|
|
16
|
+
|
|
17
|
+
private init() {}
|
|
18
|
+
|
|
19
|
+
// Event emitter function to send events to React Native layer
|
|
20
|
+
private var eventEmitter: (([String: Any?]) -> Void)?
|
|
21
|
+
|
|
22
|
+
// Sets the event emitter function
|
|
23
|
+
func setEventEmitter(_ emitter: (([String: Any?]) -> Void)?) {
|
|
24
|
+
eventEmitter = emitter
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Clears the event emitter to prevent memory leaks
|
|
28
|
+
func clearEventEmitter() {
|
|
29
|
+
eventEmitter = nil
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Emits an inbox message event to React Native with a serialized message payload
|
|
33
|
+
private func emitInboxEvent(
|
|
34
|
+
eventType: String,
|
|
35
|
+
message: InboxMessage,
|
|
36
|
+
actionName: String? = nil,
|
|
37
|
+
actionValue: String? = nil
|
|
38
|
+
) {
|
|
39
|
+
var data: [String: Any?] = [
|
|
40
|
+
ZixflowConstants.eventType: eventType,
|
|
41
|
+
ZixflowConstants.inboxMessage: message.toDictionary()
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
if let actionName = actionName {
|
|
45
|
+
data[ZixflowConstants.actionName] = actionName
|
|
46
|
+
}
|
|
47
|
+
if let actionValue = actionValue {
|
|
48
|
+
data[ZixflowConstants.actionValue] = actionValue
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
eventEmitter?(data)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public func messageActionTaken(message: InboxMessage, actionName: String, actionValue: String) -> Bool {
|
|
55
|
+
emitInboxEvent(
|
|
56
|
+
eventType: ZixflowConstants.messageActionTaken,
|
|
57
|
+
message: message,
|
|
58
|
+
actionName: actionName,
|
|
59
|
+
actionValue: actionValue
|
|
60
|
+
)
|
|
61
|
+
// Host (React Native) owns action handling while a listener is registered.
|
|
62
|
+
return true
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public func messageShown(message: InboxMessage) {
|
|
66
|
+
emitInboxEvent(eventType: ZixflowConstants.messageShown, message: message)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public func messageOpened(message: InboxMessage) {
|
|
70
|
+
emitInboxEvent(eventType: ZixflowConstants.messageOpened, message: message)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public func messageDismissed(message: InboxMessage) {
|
|
74
|
+
emitInboxEvent(eventType: ZixflowConstants.messageDismissed, message: message)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
@class UIView;
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Objective-C forward declaration for the Swift `ReactNotificationInboxBellView` class.
|
|
9
|
+
* See `ReactNotificationInboxOverlayView.h` for the rationale behind runtime resolution.
|
|
10
|
+
*/
|
|
11
|
+
@interface ReactNotificationInboxBellView : NSObject
|
|
12
|
+
|
|
13
|
+
- (instancetype)initWithContainerView:(UIView *)containerView;
|
|
14
|
+
- (void)setEventEmitter:(id)eventEmitter;
|
|
15
|
+
- (void)updateLayout:(NSValue *)boundsValue;
|
|
16
|
+
- (void)attachToParentViewController;
|
|
17
|
+
- (void)detachFromParentViewController;
|
|
18
|
+
- (void)prepareForRecycle;
|
|
19
|
+
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import ZixflowMessagingInbox
|
|
2
|
+
import Foundation
|
|
3
|
+
import SwiftUI
|
|
4
|
+
import UIKit
|
|
5
|
+
|
|
6
|
+
/// React Native wrapper hosting the SwiftUI `NotificationInboxOverlay` inside a `UIHostingController`.
|
|
7
|
+
///
|
|
8
|
+
/// Despite the name, the hosted composition is the overlay rather than the bare `NotificationInboxBell`:
|
|
9
|
+
/// only the overlay ties the bell to the SDK's own inbox sheet, and the wrapper deliberately does not
|
|
10
|
+
/// reimplement panel presentation. Sized to the frame React Native assigns, that composition *is* a bell
|
|
11
|
+
/// that opens the inbox — the component wrappers expose.
|
|
12
|
+
///
|
|
13
|
+
/// Remote branding still styles the bell (colors, icon). Branding's bell *position* has no effect here:
|
|
14
|
+
/// alignment resolves inside this view's frame, so the host owns placement via `style`.
|
|
15
|
+
///
|
|
16
|
+
/// iOS 16+ because the panel is a sheet with system detents.
|
|
17
|
+
@available(iOS 16.0, *)
|
|
18
|
+
@objc(ReactNotificationInboxBellView)
|
|
19
|
+
class ReactNotificationInboxBellView: NSObject {
|
|
20
|
+
private weak var eventEmitter: AnyObject?
|
|
21
|
+
private weak var containerView: UIView?
|
|
22
|
+
private let hostingController: UIHostingController<NotificationInboxOverlay>
|
|
23
|
+
|
|
24
|
+
@objc
|
|
25
|
+
init(containerView: UIView) {
|
|
26
|
+
self.containerView = containerView
|
|
27
|
+
self.hostingController = UIHostingController(rootView: NotificationInboxOverlay())
|
|
28
|
+
super.init()
|
|
29
|
+
|
|
30
|
+
let hostedView = hostingController.view!
|
|
31
|
+
hostedView.backgroundColor = .clear
|
|
32
|
+
hostedView.translatesAutoresizingMaskIntoConstraints = false
|
|
33
|
+
containerView.addSubview(hostedView)
|
|
34
|
+
NSLayoutConstraint.activate([
|
|
35
|
+
hostedView.topAnchor.constraint(equalTo: containerView.topAnchor),
|
|
36
|
+
hostedView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
|
37
|
+
hostedView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
|
|
38
|
+
hostedView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
|
39
|
+
])
|
|
40
|
+
|
|
41
|
+
// Observational tap reporting. The SDK owns presentation, so this recognizer must not consume
|
|
42
|
+
// the touch: `cancelsTouchesInView = false` lets SwiftUI still receive it and open the sheet.
|
|
43
|
+
// It reports any tap inside this view's frame, which is the bell when the view is sized to it.
|
|
44
|
+
let tapObserver = UITapGestureRecognizer(target: self, action: #selector(handleObservedTap))
|
|
45
|
+
tapObserver.cancelsTouchesInView = false
|
|
46
|
+
tapObserver.delaysTouchesEnded = false
|
|
47
|
+
containerView.addGestureRecognizer(tapObserver)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@objc
|
|
51
|
+
func setEventEmitter(_ eventEmitter: AnyObject?) {
|
|
52
|
+
self.eventEmitter = eventEmitter
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// Adds the hosting controller to the view-controller hierarchy once the view is in a window.
|
|
56
|
+
///
|
|
57
|
+
/// Without this the controller is orphaned, and the sheet it presents resolves its safe-area insets
|
|
58
|
+
/// against the wrong container — which showed up as a phantom top margin when dragging the sheet.
|
|
59
|
+
@objc
|
|
60
|
+
func attachToParentViewController() {
|
|
61
|
+
InboxHostContainment.attach(hostingController, hostedIn: containerView)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@objc
|
|
65
|
+
func detachFromParentViewController() {
|
|
66
|
+
InboxHostContainment.detach(hostingController)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@objc
|
|
70
|
+
func updateLayout(_ boundsValue: NSValue) {
|
|
71
|
+
hostingController.view.frame = boundsValue.cgRectValue
|
|
72
|
+
hostingController.view.setNeedsLayout()
|
|
73
|
+
hostingController.view.layoutIfNeeded()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@objc
|
|
77
|
+
func prepareForRecycle() {
|
|
78
|
+
// Deliberately does NOT remove the hosted view from its container.
|
|
79
|
+
//
|
|
80
|
+
// Fabric recycles the component view, and detaching the SwiftUI view here with nothing to
|
|
81
|
+
// re-attach it made a reused view come back blank. `ReactInlineMessageView` does not touch the
|
|
82
|
+
// hierarchy either. Containment is released here because a recycled view is leaving its parent.
|
|
83
|
+
detachFromParentViewController()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// MARK: - Event Emission
|
|
87
|
+
|
|
88
|
+
@objc
|
|
89
|
+
private func handleObservedTap() {
|
|
90
|
+
emitEvent("emitOnTapEvent:", payload: [:])
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/// Mirrors `ReactInlineMessageView.emitEvent`: asserts rather than returning silently, so a
|
|
94
|
+
/// mis-wired emitter surfaces in debug instead of the tap simply never reaching JS.
|
|
95
|
+
private func emitEvent(_ selectorName: String, payload: [String: Any?]) {
|
|
96
|
+
guard let emitter = eventEmitter else {
|
|
97
|
+
assertionFailure("Event emitter is nil when trying to emit \(selectorName)")
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let selector = Selector((selectorName))
|
|
102
|
+
guard emitter.responds(to: selector) else {
|
|
103
|
+
assertionFailure("Event emitter does not respond to selector: \(selectorName)")
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
_ = emitter.perform(selector, with: payload as NSDictionary)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
|
|
3
|
+
@class UIView;
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Objective-C forward declaration for the Swift `ReactNotificationInboxView` class.
|
|
9
|
+
* See `ReactNotificationInboxOverlayView.h` for the rationale behind runtime resolution.
|
|
10
|
+
*/
|
|
11
|
+
@interface ReactNotificationInboxView : NSObject
|
|
12
|
+
|
|
13
|
+
- (instancetype)initWithContainerView:(UIView *)containerView;
|
|
14
|
+
- (void)setEventEmitter:(id)eventEmitter;
|
|
15
|
+
- (void)updateLayout:(NSValue *)boundsValue;
|
|
16
|
+
- (void)attachToParentViewController;
|
|
17
|
+
- (void)detachFromParentViewController;
|
|
18
|
+
- (void)prepareForRecycle;
|
|
19
|
+
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import ZixflowMessagingInbox
|
|
2
|
+
import Foundation
|
|
3
|
+
import SwiftUI
|
|
4
|
+
import UIKit
|
|
5
|
+
|
|
6
|
+
/// React Native wrapper hosting the SwiftUI `NotificationInboxView` (the Jist-rendered message
|
|
7
|
+
/// list) inside a `UIHostingController`. No events; sizing is driven by the JS `style` prop.
|
|
8
|
+
/// Message actions are handled by the existing global InboxEventListener.
|
|
9
|
+
/// No `@available` annotation, matching `ReactInlineMessageView`: the native list view is iOS 13+,
|
|
10
|
+
/// so the pod's own floor (`min_ios_version_supported`) governs.
|
|
11
|
+
@objc(ReactNotificationInboxView)
|
|
12
|
+
class ReactNotificationInboxView: NSObject {
|
|
13
|
+
private weak var containerView: UIView?
|
|
14
|
+
private let hostingController: UIHostingController<NotificationInboxView>
|
|
15
|
+
|
|
16
|
+
@objc
|
|
17
|
+
init(containerView: UIView) {
|
|
18
|
+
self.containerView = containerView
|
|
19
|
+
self.hostingController = UIHostingController(rootView: NotificationInboxView())
|
|
20
|
+
super.init()
|
|
21
|
+
|
|
22
|
+
let hostedView = hostingController.view!
|
|
23
|
+
hostedView.backgroundColor = .clear
|
|
24
|
+
hostedView.translatesAutoresizingMaskIntoConstraints = false
|
|
25
|
+
containerView.addSubview(hostedView)
|
|
26
|
+
NSLayoutConstraint.activate([
|
|
27
|
+
hostedView.topAnchor.constraint(equalTo: containerView.topAnchor),
|
|
28
|
+
hostedView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),
|
|
29
|
+
hostedView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
|
|
30
|
+
hostedView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor)
|
|
31
|
+
])
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Accepts the emitter for API symmetry with the other inbox views; this view emits no events.
|
|
35
|
+
@objc
|
|
36
|
+
func setEventEmitter(_ eventEmitter: AnyObject?) {}
|
|
37
|
+
|
|
38
|
+
/// Adds the hosting controller to the view-controller hierarchy once the view is in a window, so the
|
|
39
|
+
/// hosted SwiftUI gets a correct trait/safe-area chain and lifecycle callbacks instead of being
|
|
40
|
+
/// driven by an orphaned controller.
|
|
41
|
+
@objc
|
|
42
|
+
func attachToParentViewController() {
|
|
43
|
+
InboxHostContainment.attach(hostingController, hostedIn: containerView)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@objc
|
|
47
|
+
func detachFromParentViewController() {
|
|
48
|
+
InboxHostContainment.detach(hostingController)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@objc
|
|
52
|
+
func updateLayout(_ boundsValue: NSValue) {
|
|
53
|
+
hostingController.view.frame = boundsValue.cgRectValue
|
|
54
|
+
hostingController.view.setNeedsLayout()
|
|
55
|
+
hostingController.view.layoutIfNeeded()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@objc
|
|
59
|
+
func prepareForRecycle() {
|
|
60
|
+
detachFromParentViewController()
|
|
61
|
+
// Deliberately does NOT remove the hosted view from its container.
|
|
62
|
+
//
|
|
63
|
+
// Fabric recycles the component view, and the previous version detached the SwiftUI view here
|
|
64
|
+
// with nothing to re-attach it, so a reused view came back blank. `ReactInlineMessageView`
|
|
65
|
+
// does not touch the hierarchy either — it detaches observers (`onViewDetached`) and
|
|
66
|
+
// re-attaches in `setupForReuse`. These hosts have no props and no observers to reset, so
|
|
67
|
+
// there is nothing to undo: the hosted view stays mounted and is reused as-is.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#import <React/RCTBridgeModule.h>
|
|
2
|
+
#import <RNZixflowSpec/RNZixflowSpec.h>
|
|
3
|
+
|
|
4
|
+
// Objective-C wrapper for new architecture TurboModule implementation
|
|
5
|
+
@interface RCTNativeLiveActivities : NSObject <NativeZixflowLiveActivitiesSpec>
|
|
6
|
+
// Bridge to Swift implementation for cross-language compatibility
|
|
7
|
+
@property(nonatomic, strong) id<NativeZixflowLiveActivitiesSpec> swiftBridge;
|
|
8
|
+
@end
|
|
9
|
+
|
|
10
|
+
@implementation RCTNativeLiveActivities
|
|
11
|
+
|
|
12
|
+
RCT_EXPORT_MODULE()
|
|
13
|
+
|
|
14
|
+
// Create TurboModule instance for new architecture JSI integration
|
|
15
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
16
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params {
|
|
17
|
+
return std::make_shared<facebook::react::NativeZixflowLiveActivitiesSpecJSI>(params);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
- (instancetype)init {
|
|
21
|
+
if (self = [super init]) {
|
|
22
|
+
// Runtime class lookup - the Swift class only exists when the liveactivities subspec is installed.
|
|
23
|
+
Class swiftClass = NSClassFromString(@"NativeZixflowLiveActivities");
|
|
24
|
+
if (swiftClass) {
|
|
25
|
+
_swiftBridge = [[swiftClass alloc] init];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return self;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Module initialization can happen on background thread
|
|
32
|
+
+ (BOOL)requiresMainQueueSetup {
|
|
33
|
+
return NO;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
- (void)start:(NSDictionary *)payload
|
|
37
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
38
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
39
|
+
if (!_swiftBridge) {
|
|
40
|
+
reject(@"live_activity_module_unavailable", @"Live Activities are unavailable.", nil);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
[_swiftBridge start:payload resolve:resolve reject:reject];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
- (void)update:(NSString *)activityId
|
|
47
|
+
payload:(NSDictionary *)payload
|
|
48
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
49
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
50
|
+
if (!_swiftBridge) {
|
|
51
|
+
reject(@"live_activity_module_unavailable", @"Live Activities are unavailable.", nil);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
[_swiftBridge update:activityId payload:payload resolve:resolve reject:reject];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (void)end:(NSString *)activityId
|
|
58
|
+
payload:(NSDictionary *)payload
|
|
59
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
60
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
61
|
+
if (!_swiftBridge) {
|
|
62
|
+
reject(@"live_activity_module_unavailable", @"Live Activities are unavailable.", nil);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
[_swiftBridge end:activityId payload:payload resolve:resolve reject:reject];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- (void)handleWidgetUrl:(NSString *)url
|
|
69
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
70
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
71
|
+
if (!_swiftBridge) {
|
|
72
|
+
resolve(url);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
[_swiftBridge handleWidgetUrl:url resolve:resolve reject:reject];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Export class factory function for React Native component registration
|
|
79
|
+
Class<RCTBridgeModule> NativeZixflowLiveActivitiesCls(void) {
|
|
80
|
+
return RCTNativeLiveActivities.class;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@end
|