zixflow-reactnative 1.1.3 → 1.1.5
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 +631 -261
- 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 +41 -5
- 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 -0
- 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/messaginginapp/NativeMessagingInAppModule.kt +150 -0
- 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 +15 -2
- 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 +91 -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/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 +13 -1
- 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 +76 -1
- package/lib/commonjs/utils/param-validation.js.map +1 -1
- package/lib/commonjs/zixflow-cdp.js +99 -1
- 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/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 +13 -0
- 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 +76 -1
- package/lib/module/utils/param-validation.js.map +1 -1
- package/lib/module/zixflow-cdp.js +99 -1
- 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/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 +53 -1
- 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/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 +53 -1
- 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/package.json +11 -2
- 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 +54 -1
- 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 +103 -0
- package/src/zixflow-cdp.ts +117 -1
- package/src/zixflow-geofence.ts +56 -0
- package/src/zixflow-inapp.ts +125 -2
- package/src/zixflow-liveactivities.ts +86 -0
- package/zixflow-reactnative-richpush.podspec +4 -1
- package/zixflow-reactnative.podspec +26 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { InboxMessage } from './in-app';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Enum representing the type of event triggered by an inbox event callback.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors the native `InboxEventListener` contract on iOS and Android.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export enum InboxEventType {
|
|
11
|
+
/** A non-dismiss action (e.g. a button/link) was taken on an inbox message. */
|
|
12
|
+
messageActionTaken = 'messageActionTaken',
|
|
13
|
+
/** An inbox message was first shown/rendered in the visible inbox view. */
|
|
14
|
+
messageShown = 'messageShown',
|
|
15
|
+
/** An inbox message was marked opened (e.g. when the panel opens). */
|
|
16
|
+
messageOpened = 'messageOpened',
|
|
17
|
+
/** An inbox message was dismissed/removed from the inbox. */
|
|
18
|
+
messageDismissed = 'messageDismissed',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Event delivered to a registered inbox event listener.
|
|
23
|
+
*
|
|
24
|
+
* `messageActionTaken` carries `actionName`/`actionValue`; the observational
|
|
25
|
+
* events (`messageShown`, `messageOpened`, `messageDismissed`) carry only the
|
|
26
|
+
* message.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export class InboxMessageEvent {
|
|
31
|
+
/** The type of inbox event. */
|
|
32
|
+
eventType: InboxEventType;
|
|
33
|
+
/** The inbox message the event relates to. */
|
|
34
|
+
message: InboxMessage;
|
|
35
|
+
/** The Jist action name (only present for `messageActionTaken`). */
|
|
36
|
+
actionName?: string;
|
|
37
|
+
/** The resolved action value, typically a url (only present for `messageActionTaken`). */
|
|
38
|
+
actionValue?: string;
|
|
39
|
+
|
|
40
|
+
constructor(
|
|
41
|
+
eventType: InboxEventType,
|
|
42
|
+
message: InboxMessage,
|
|
43
|
+
actionName?: string,
|
|
44
|
+
actionValue?: string
|
|
45
|
+
) {
|
|
46
|
+
this.eventType = eventType;
|
|
47
|
+
this.message = message;
|
|
48
|
+
this.actionName = actionName;
|
|
49
|
+
this.actionValue = actionValue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Host-provided accessibility labels for the Visual Notification Inbox UI.
|
|
55
|
+
*
|
|
56
|
+
* The SDK ships no text of its own in the visual inbox — the empty state is an icon and the
|
|
57
|
+
* loading state is a spinner — so accessibility labels are the one place a string is still
|
|
58
|
+
* needed. Because the SDK cannot know your app's language, every label is optional and unset by
|
|
59
|
+
* default, and an omitted label leaves that element unlabeled rather than falling back to
|
|
60
|
+
* English. Pass strings already localized for the user's language.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* Zixflow.initialize({
|
|
65
|
+
* apiKey: '...',
|
|
66
|
+
* inApp: {
|
|
67
|
+
* siteId: '...',
|
|
68
|
+
* notificationInboxAccessibilityLabels: {
|
|
69
|
+
* bell: t('inbox.bell'),
|
|
70
|
+
* bellWithUnreadCount: t('inbox.unread'), // e.g. "{count} unread notifications"
|
|
71
|
+
* loadingIndicator: t('inbox.loading'),
|
|
72
|
+
* emptyState: t('inbox.empty'),
|
|
73
|
+
* },
|
|
74
|
+
* },
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
export type NotificationInboxAccessibilityLabels = {
|
|
81
|
+
/**
|
|
82
|
+
* Label for the inbox bell button. Also used when the bell shows an unread badge but
|
|
83
|
+
* `bellWithUnreadCount` is not provided. Unset → the bell is announced as an unnamed button
|
|
84
|
+
* (it stays focusable and tappable; hiding it would leave screen reader users no way in).
|
|
85
|
+
*/
|
|
86
|
+
bell?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Label for the bell while it shows an unread badge. Include `{count}` where the number of
|
|
89
|
+
* unread messages should appear; it is substituted at render time. Unset → falls back to `bell`.
|
|
90
|
+
*
|
|
91
|
+
* The badge itself is always hidden from assistive technologies, so the count is announced
|
|
92
|
+
* only through this label, never as bare digits appended to the button.
|
|
93
|
+
*
|
|
94
|
+
* This is a template rather than a function because configuration crosses the native bridge,
|
|
95
|
+
* which carries data but not callbacks. One template cannot express languages whose plural
|
|
96
|
+
* rules need a distinct form per count.
|
|
97
|
+
*/
|
|
98
|
+
bellWithUnreadCount?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Label announced for the loading spinner.
|
|
101
|
+
*
|
|
102
|
+
* Unset behaves differently per platform: on Android the spinner keeps its indeterminate
|
|
103
|
+
* progress role, which TalkBack describes in the device's own language, while on iOS it is not
|
|
104
|
+
* an accessibility element at all, so VoiceOver skips it rather than focusing an unnamed
|
|
105
|
+
* control. Set a label if you want the loading state announced on both.
|
|
106
|
+
*/
|
|
107
|
+
loadingIndicator?: string;
|
|
108
|
+
/** Label announced for the empty-state icon. Unset → the icon is treated as decorative. */
|
|
109
|
+
emptyState?: string;
|
|
110
|
+
};
|
package/src/types/index.ts
CHANGED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the Live Activities module.
|
|
3
|
+
*
|
|
4
|
+
* Live Activities (iOS) / Live Notifications (Android) render live, updating
|
|
5
|
+
* notifications from built-in templates. Two templates ship today: Segments and
|
|
6
|
+
* Countdown Timer. Field names and identifiers are identical across platforms.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Built-in activity type identifiers usable from the wrapper.
|
|
11
|
+
*
|
|
12
|
+
* The values are the reverse-DNS identifiers Zixflow uses everywhere — the
|
|
13
|
+
* `notificationType` on the wire, Android's `LiveNotificationType`, and iOS's
|
|
14
|
+
* `CIOSegmentsAttributes.identifier` — so JS, both native SDKs, and the backend
|
|
15
|
+
* share one vocabulary.
|
|
16
|
+
*
|
|
17
|
+
* Use these enum members (not raw strings) for `LiveActivitiesConfig.types` and a
|
|
18
|
+
* payload's `type` to avoid typos.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export enum LiveActivityTemplate {
|
|
23
|
+
Segments = 'com.zixflow.livenotifications.segments',
|
|
24
|
+
CountdownTimer = 'com.zixflow.livenotifications.countdowntimer',
|
|
25
|
+
/**
|
|
26
|
+
* Your own activity type, rendered by SwiftUI you write.
|
|
27
|
+
*
|
|
28
|
+
* Unlike the members above, this value is a marker rather than an identifier — your activity is
|
|
29
|
+
* named by {@link LiveActivitiesConfig.customType}, and the SDK reports it under that name. It
|
|
30
|
+
* belongs in a payload's `type`, never in {@link LiveActivitiesConfig.types}.
|
|
31
|
+
*/
|
|
32
|
+
Custom = 'custom',
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Segments template — a progress activity split into N segments.
|
|
37
|
+
* `header` is a static attribute (fixed at start); the rest are content-state.
|
|
38
|
+
*
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export interface LiveActivitySegmentsPayload {
|
|
42
|
+
type: LiveActivityTemplate.Segments;
|
|
43
|
+
/** Static header line (set at start, never changes). */
|
|
44
|
+
header: string;
|
|
45
|
+
/** Primary status line. */
|
|
46
|
+
status: string;
|
|
47
|
+
/** Optional secondary status line. */
|
|
48
|
+
substatus?: string;
|
|
49
|
+
/** Total number of segments. */
|
|
50
|
+
segmentsTotal: number;
|
|
51
|
+
/** Number of completed segments (clamped to 0..segmentsTotal). */
|
|
52
|
+
segmentsComplete: number;
|
|
53
|
+
/** Optional trailing text (e.g. an ETA). */
|
|
54
|
+
trailingText?: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Custom template — your own activity type, rendered by SwiftUI you write.
|
|
59
|
+
*
|
|
60
|
+
* Unlike the built-in templates there is no schema: `data` is an untyped map, because a bridge
|
|
61
|
+
* payload carries nothing for the SDK to validate against. Every value is a string, so your widget
|
|
62
|
+
* parses whichever ones it needs.
|
|
63
|
+
*
|
|
64
|
+
* Requires {@link LiveActivitiesConfig.customType} to be set. On iOS you must also render
|
|
65
|
+
* `CIOCustomAttributes` in your Widget Extension; on Android your `createLiveNotification`
|
|
66
|
+
* callback receives the same map.
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export interface LiveActivityCustomPayload {
|
|
71
|
+
type: LiveActivityTemplate.Custom;
|
|
72
|
+
/**
|
|
73
|
+
* The full content-state, re-sent in its entirety on every update. Neither platform keeps a
|
|
74
|
+
* static/dynamic split for custom types, so include anything your widget needs each time.
|
|
75
|
+
*
|
|
76
|
+
* Values must be strings. Numbers and booleans are coerced, but nested objects and arrays are
|
|
77
|
+
* not supported and the platforms disagree on them — iOS drops them, Android stringifies them —
|
|
78
|
+
* so flatten anything structured before sending it.
|
|
79
|
+
*/
|
|
80
|
+
data: Record<string, string>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Countdown Timer template — a live countdown to a target time.
|
|
85
|
+
* `header` is a static attribute (fixed at start); the rest are content-state.
|
|
86
|
+
*
|
|
87
|
+
* @public
|
|
88
|
+
*/
|
|
89
|
+
export interface LiveActivityCountdownTimerPayload {
|
|
90
|
+
type: LiveActivityTemplate.CountdownTimer;
|
|
91
|
+
/** Static header line (set at start, never changes). */
|
|
92
|
+
header: string;
|
|
93
|
+
/** Primary title line. */
|
|
94
|
+
title: string;
|
|
95
|
+
/** Optional status message. */
|
|
96
|
+
statusMessage?: string;
|
|
97
|
+
/** Target time as epoch **seconds**. Omit to render the finished state. */
|
|
98
|
+
endTime?: number;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Payload for {@link ZixflowLiveActivities.start} and
|
|
103
|
+
* {@link ZixflowLiveActivities.update}.
|
|
104
|
+
*
|
|
105
|
+
* Because ActivityKit replaces content-state wholesale on update, `update` takes the
|
|
106
|
+
* same full payload as `start` — pass the complete desired state each time.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
export type LiveActivityPayload =
|
|
111
|
+
| LiveActivitySegmentsPayload
|
|
112
|
+
| LiveActivityCountdownTimerPayload
|
|
113
|
+
| LiveActivityCustomPayload;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Live Activities branding (Android only). On iOS, branding is compiled into the
|
|
117
|
+
* widget extension's SwiftUI, so these values are ignored there.
|
|
118
|
+
*
|
|
119
|
+
* @public
|
|
120
|
+
*/
|
|
121
|
+
export interface LiveActivitiesBranding {
|
|
122
|
+
/** Reserved for future use. */
|
|
123
|
+
companyName?: string;
|
|
124
|
+
/** Accent color as "#RRGGBB". */
|
|
125
|
+
accentColorHex?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Bundled Android drawable resource name for the logo, resolved natively.
|
|
128
|
+
* Preferred over {@link LiveActivitiesBranding.logoUrl} when both are set — it
|
|
129
|
+
* needs no network.
|
|
130
|
+
*/
|
|
131
|
+
logoResource?: string;
|
|
132
|
+
/** Remote logo URL (downloaded and cached natively). */
|
|
133
|
+
logoUrl?: string;
|
|
134
|
+
/** Android drawable resource name, resolved natively. */
|
|
135
|
+
smallIconResource?: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Live Activities configuration, passed under the `liveNotifications` key of the SDK config.
|
|
140
|
+
*
|
|
141
|
+
* @public
|
|
142
|
+
*/
|
|
143
|
+
export interface LiveActivitiesConfig {
|
|
144
|
+
/**
|
|
145
|
+
* Built-in activity types to enable. Enables the matching native type on each
|
|
146
|
+
* platform and registers push-to-start for it. Unrecognized identifiers are
|
|
147
|
+
* ignored, so a newer native template can't break an older wrapper build.
|
|
148
|
+
*
|
|
149
|
+
* `Custom` is excluded on purpose — it is enabled by {@link LiveActivitiesConfig.customType},
|
|
150
|
+
* and both platforms would silently drop it from this list.
|
|
151
|
+
*/
|
|
152
|
+
types?: Exclude<LiveActivityTemplate, LiveActivityTemplate.Custom>[];
|
|
153
|
+
/**
|
|
154
|
+
* Your own reverse-DNS identifier for the custom activity type, e.g.
|
|
155
|
+
* `'com.myapp.rideshare'`. Setting it enables the custom template on both platforms.
|
|
156
|
+
*
|
|
157
|
+
* Start one with `{ type: LiveActivityTemplate.Custom, data: { … } }`; the SDK reports it
|
|
158
|
+
* under this identifier, and your campaigns target it by the same name.
|
|
159
|
+
*
|
|
160
|
+
* Singular by design: iOS resolves an activity's type from its Swift attributes type, and
|
|
161
|
+
* every custom activity shares one. A second identifier could not be told apart, so one
|
|
162
|
+
* identifier is the limit rather than a silent mis-attribution.
|
|
163
|
+
*
|
|
164
|
+
* You must also render it yourself — `CIOCustomAttributes` in an iOS Widget Extension, and
|
|
165
|
+
* the `createLiveNotification` callback on Android.
|
|
166
|
+
*/
|
|
167
|
+
customType?: string;
|
|
168
|
+
/** Android Live Notification branding (ignored on iOS). */
|
|
169
|
+
branding?: LiveActivitiesBranding;
|
|
170
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Argument validation utilities for SDK internal use
|
|
2
2
|
// Ensures input safety and throws clear errors when validation fails
|
|
3
3
|
|
|
4
|
+
import { ZixflowColorScheme } from '../types';
|
|
4
5
|
import type { ZixflowConfig, CustomAttributes } from '../types';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -32,6 +33,16 @@ function failIf(condition: boolean, message: () => string): void {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Logs a warning if the condition is true.
|
|
38
|
+
* Use this for misconfigurations that degrade behavior but must not fail initialization.
|
|
39
|
+
*/
|
|
40
|
+
function warnIf(condition: boolean, message: () => string): void {
|
|
41
|
+
if (__DEV__ && condition) {
|
|
42
|
+
console.warn(`[Zixflow] ${message()}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
/**
|
|
36
47
|
* Validates that a value is defined (not undefined or null).
|
|
37
48
|
* Useful for checking required fields.
|
|
@@ -137,6 +148,92 @@ function validateAttributes(
|
|
|
137
148
|
return attributes as CustomAttributes;
|
|
138
149
|
}
|
|
139
150
|
|
|
151
|
+
/**
|
|
152
|
+
* The placeholder the SDK substitutes with the unread count when rendering
|
|
153
|
+
* `bellWithUnreadCount`.
|
|
154
|
+
*/
|
|
155
|
+
const COUNT_PLACEHOLDER = '{count}';
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Warns when `bellWithUnreadCount` is missing its `{count}` placeholder.
|
|
159
|
+
*
|
|
160
|
+
* The label is a template, not a finished string. A misspelled placeholder (`{COUNT}`,
|
|
161
|
+
* `{{count}}`, `%d`) matches nothing, so the template is announced verbatim — braces and all —
|
|
162
|
+
* and the count is never spoken. The check lives here rather than in either native layer
|
|
163
|
+
* because neither can report it usefully: Android logs at `debug`, which the default `ERROR`
|
|
164
|
+
* level discards, and iOS does not check at all. Warning from JavaScript reaches the
|
|
165
|
+
* developer's console on both platforms, whatever the SDK log level.
|
|
166
|
+
*/
|
|
167
|
+
function validateInboxAccessibilityLabels(value: unknown): void {
|
|
168
|
+
if (isUndefined(value) || typeof value !== 'object') {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const template = (value as { bellWithUnreadCount?: unknown })
|
|
173
|
+
.bellWithUnreadCount;
|
|
174
|
+
warnIf(
|
|
175
|
+
typeof template === 'string' && !template.includes(COUNT_PLACEHOLDER),
|
|
176
|
+
() =>
|
|
177
|
+
`"inApp.notificationInboxAccessibilityLabels.bellWithUnreadCount" has no ` +
|
|
178
|
+
`"${COUNT_PLACEHOLDER}" placeholder, so the unread count will not be announced.`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Warns when a value is not one of the `ZixflowColorScheme` values.
|
|
184
|
+
*
|
|
185
|
+
* TypeScript rejects a bad value already, but JavaScript callers reach both entry points
|
|
186
|
+
* untyped, and neither native layer reports the mistake at the default log level. The
|
|
187
|
+
* failure mode is a message rendered in the wrong theme with no error attached, so
|
|
188
|
+
* JavaScript is the only place the developer reliably sees it.
|
|
189
|
+
*
|
|
190
|
+
* `consequence` differs per entry point because the native fallback does: an unrecognized
|
|
191
|
+
* value at initialization resolves to `auto`, while the runtime setter leaves whatever
|
|
192
|
+
* scheme the app already chose in place.
|
|
193
|
+
*/
|
|
194
|
+
function warnIfNotColorScheme(
|
|
195
|
+
value: unknown,
|
|
196
|
+
fieldName: string,
|
|
197
|
+
consequence: string
|
|
198
|
+
): void {
|
|
199
|
+
const allowed: string[] = Object.values(ZixflowColorScheme);
|
|
200
|
+
warnIf(
|
|
201
|
+
!(typeof value === 'string' && allowed.includes(value)),
|
|
202
|
+
() =>
|
|
203
|
+
`"${fieldName}" is not a valid ZixflowColorScheme (expected one of ` +
|
|
204
|
+
`${allowed.join(', ')}), so ${consequence}.`
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Validates `inApp.colorScheme`. An absent value is legitimate here — the native SDKs
|
|
210
|
+
* already default to `auto` — so only a value the host actually set is checked.
|
|
211
|
+
*/
|
|
212
|
+
function validateConfigColorScheme(value: unknown): void {
|
|
213
|
+
if (isUndefined(value)) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
warnIfNotColorScheme(
|
|
218
|
+
value,
|
|
219
|
+
'inApp.colorScheme',
|
|
220
|
+
'in-app messages will follow the device appearance'
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Validates the argument to `setColorScheme`. Unlike the config field, an absent value is
|
|
226
|
+
* itself the mistake: the caller asked for a scheme change and named none, and there is no
|
|
227
|
+
* default to fall back to, so null and undefined are reported rather than skipped.
|
|
228
|
+
*/
|
|
229
|
+
function validateColorSchemeArgument(value: unknown): void {
|
|
230
|
+
warnIfNotColorScheme(
|
|
231
|
+
value,
|
|
232
|
+
'colorScheme',
|
|
233
|
+
'the color scheme will be left unchanged'
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
140
237
|
/**
|
|
141
238
|
* Validates that the given value is a valid ZixflowConfig object.
|
|
142
239
|
* Throws if required fields are missing or incorrectly typed.
|
|
@@ -155,6 +252,10 @@ function validateConfig(value: unknown): asserts value is ZixflowConfig {
|
|
|
155
252
|
allowEmpty: false,
|
|
156
253
|
usage: usage,
|
|
157
254
|
});
|
|
255
|
+
validateConfigColorScheme(obj.inApp?.colorScheme);
|
|
256
|
+
validateInboxAccessibilityLabels(
|
|
257
|
+
obj.inApp?.notificationInboxAccessibilityLabels
|
|
258
|
+
);
|
|
158
259
|
}
|
|
159
260
|
|
|
160
261
|
// For type safety, we define a ConfigValidator type that asserts the value is a ZixflowConfig
|
|
@@ -166,11 +267,13 @@ export const assert: {
|
|
|
166
267
|
record: typeof validateRecord;
|
|
167
268
|
attributes: typeof validateAttributes;
|
|
168
269
|
config: ConfigValidator;
|
|
270
|
+
colorScheme: typeof validateColorSchemeArgument;
|
|
169
271
|
} = {
|
|
170
272
|
string: validateString,
|
|
171
273
|
record: validateRecord,
|
|
172
274
|
attributes: validateAttributes,
|
|
173
275
|
config: validateConfig,
|
|
276
|
+
colorScheme: validateColorSchemeArgument,
|
|
174
277
|
};
|
|
175
278
|
|
|
176
279
|
export const validate = {
|
package/src/zixflow-cdp.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { ZixflowGeofence } from './zixflow-geofence';
|
|
1
2
|
import { ZixflowInAppMessaging } from './zixflow-inapp';
|
|
3
|
+
import { ZixflowLiveActivities } from './zixflow-liveactivities';
|
|
2
4
|
import { ZixflowLocation } from './zixflow-location';
|
|
3
5
|
import { ZixflowPushMessaging } from './zixflow-push';
|
|
4
6
|
import { NativeLoggerListener } from './native-logger-listener';
|
|
@@ -17,10 +19,26 @@ import type { NativeSDKArgs } from './types/internal';
|
|
|
17
19
|
import { callNativeModule, ensureNativeModule } from './utils/native-bridge';
|
|
18
20
|
import { assert, validate } from './utils/param-validation';
|
|
19
21
|
|
|
20
|
-
const packageJson = require('
|
|
22
|
+
const packageJson = require('../package.json');
|
|
21
23
|
|
|
22
24
|
// Track whether Zixflow SDK has been initialized to prevent usage before setup
|
|
23
25
|
let _initialized = false;
|
|
26
|
+
let deepLinkHandlerSubscription: DeepLinkHandlerSubscription | undefined;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Handles a Zixflow deep-link destination delivered from iOS.
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export type DeepLinkHandler = (url: string) => boolean | Promise<boolean>;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Removes a Zixflow deep-link handler.
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export interface DeepLinkHandlerSubscription {
|
|
39
|
+
/** Stop routing Zixflow deep links through this handler. */
|
|
40
|
+
remove(): void;
|
|
41
|
+
}
|
|
24
42
|
|
|
25
43
|
// Reference to the native Zixflow Data Pipelines module for SDK operations
|
|
26
44
|
const nativeModule = ensureNativeModule(NativeModule);
|
|
@@ -58,6 +76,102 @@ export class Zixflow {
|
|
|
58
76
|
});
|
|
59
77
|
};
|
|
60
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Signal that the app's React Native Linking listener is ready to receive Zixflow URLs.
|
|
81
|
+
*
|
|
82
|
+
* This is only needed by UIScene hosts that initialize Zixflow natively, such as Expo
|
|
83
|
+
* config-plugin auto-initialization. Call it after registering the Linking listener.
|
|
84
|
+
*/
|
|
85
|
+
static readonly setDeepLinkRoutingReady = () => {
|
|
86
|
+
return withNativeModule<void>((native) => native.setDeepLinkRoutingReady());
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register an acknowledged deep-link handler for an iOS UIScene host.
|
|
91
|
+
*
|
|
92
|
+
* This API only handles Zixflow destinations delivered through an iOS UIScene lifecycle.
|
|
93
|
+
* In a native React Native scene host, pair this with
|
|
94
|
+
* `NativeZixflow.configureAcknowledgedSceneDeepLinkRouting()` in the SceneDelegate. Register
|
|
95
|
+
* this before `initialize` when possible. Return `true` after routing a URL. Returning `false`,
|
|
96
|
+
* throwing, or rejecting lets the native SDK try the host AppDelegate, then React Native Linking
|
|
97
|
+
* for a host-owned custom scheme or the system for other URLs. Cold URLs are buffered until this
|
|
98
|
+
* handler is registered, subject to the native timeout. After delivery, the handler has ten
|
|
99
|
+
* seconds to settle. Once that timeout runs the native fallback, a late handler cannot cancel it
|
|
100
|
+
* and may cause a second navigation if it also routes the URL.
|
|
101
|
+
*/
|
|
102
|
+
static readonly setDeepLinkHandler = (
|
|
103
|
+
handler: DeepLinkHandler
|
|
104
|
+
): DeepLinkHandlerSubscription => {
|
|
105
|
+
if (typeof handler !== 'function') {
|
|
106
|
+
throw new Error('[Zixflow] "handler" must be a function.');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Native unregister is tokenless and removes the current native handler. Remove the old
|
|
110
|
+
// subscription first so its cleanup cannot unregister the replacement.
|
|
111
|
+
deepLinkHandlerSubscription?.remove();
|
|
112
|
+
|
|
113
|
+
return withNativeModule<DeepLinkHandlerSubscription>((native) => {
|
|
114
|
+
const nativeSubscription = native.onDeepLinkReceived(async (data) => {
|
|
115
|
+
const event = data as { id?: unknown; url?: unknown };
|
|
116
|
+
if (typeof event.id !== 'string' || typeof event.url !== 'string') {
|
|
117
|
+
NativeLoggerListener.warn(
|
|
118
|
+
'Received an invalid native deep-link event.'
|
|
119
|
+
);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let handled = false;
|
|
124
|
+
try {
|
|
125
|
+
handled = (await handler(event.url)) === true;
|
|
126
|
+
} catch (error) {
|
|
127
|
+
NativeLoggerListener.warn('Deep-link handler failed:', error);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
native.acknowledgeDeepLink(event.id, handled);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
NativeLoggerListener.warn(
|
|
134
|
+
'Failed to acknowledge a deep-link result:',
|
|
135
|
+
error
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
let removed = false;
|
|
141
|
+
const subscription: DeepLinkHandlerSubscription = {
|
|
142
|
+
remove: () => {
|
|
143
|
+
if (removed) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
removed = true;
|
|
147
|
+
try {
|
|
148
|
+
native.unregisterDeepLinkHandler();
|
|
149
|
+
} finally {
|
|
150
|
+
nativeSubscription.remove();
|
|
151
|
+
if (deepLinkHandlerSubscription === subscription) {
|
|
152
|
+
deepLinkHandlerSubscription = undefined;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
native.registerDeepLinkHandler();
|
|
160
|
+
} catch (error) {
|
|
161
|
+
try {
|
|
162
|
+
native.unregisterDeepLinkHandler();
|
|
163
|
+
} catch {
|
|
164
|
+
// Preserve the registration error; the native timeout still owns pending URLs.
|
|
165
|
+
}
|
|
166
|
+
nativeSubscription.remove();
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
deepLinkHandlerSubscription = subscription;
|
|
171
|
+
return subscription;
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
|
|
61
175
|
/** Identify a user to start tracking their activity. Requires userId, traits, or both. */
|
|
62
176
|
static readonly identify = async ({
|
|
63
177
|
userId,
|
|
@@ -182,7 +296,9 @@ export class Zixflow {
|
|
|
182
296
|
*/
|
|
183
297
|
static readonly isInitialized = () => _initialized;
|
|
184
298
|
|
|
299
|
+
static readonly geofence = new ZixflowGeofence();
|
|
185
300
|
static readonly inAppMessaging = new ZixflowInAppMessaging();
|
|
301
|
+
static readonly liveActivities = new ZixflowLiveActivities();
|
|
186
302
|
static readonly location = new ZixflowLocation();
|
|
187
303
|
static readonly pushMessaging = new ZixflowPushMessaging();
|
|
188
304
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
import {
|
|
3
|
+
default as NativeModule,
|
|
4
|
+
type Spec as CodegenSpec,
|
|
5
|
+
} from './specs/modules/NativeZixflowGeofence';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Ensures all methods defined in codegen spec are implemented by the public module
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
interface NativeGeofenceSpec extends Omit<CodegenSpec, keyof TurboModule> {}
|
|
13
|
+
|
|
14
|
+
// Geofence is an optional module — NativeModule may be null when geofence is not enabled.
|
|
15
|
+
// Methods silently no-op when the native module is unavailable, with a one-time dev warning.
|
|
16
|
+
let hasWarnedNotEnabled = false;
|
|
17
|
+
const withNativeModule = (fn: (native: CodegenSpec) => void): void => {
|
|
18
|
+
if (NativeModule) {
|
|
19
|
+
fn(NativeModule);
|
|
20
|
+
} else if (__DEV__ && !hasWarnedNotEnabled) {
|
|
21
|
+
hasWarnedNotEnabled = true;
|
|
22
|
+
console.warn(
|
|
23
|
+
'Zixflow: Geofence module is not enabled. ' +
|
|
24
|
+
'To use geofence features, set zixflow_geofence_enabled=true in ' +
|
|
25
|
+
'gradle.properties (Android) or add the geofence subspec to your Podfile (iOS).'
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Public entry point for the optional Geofence module.
|
|
32
|
+
*
|
|
33
|
+
* Geofence runs automatically once enabled. Apps opt in by passing a `geofence` config to
|
|
34
|
+
* `initialize` and enabling the module at build time: set `zixflow_geofence_enabled=true`
|
|
35
|
+
* in `gradle.properties` (Android) or add the `geofence` subspec to your Podfile (iOS).
|
|
36
|
+
* Enabling geofence also enables the Location module, which geofence depends on.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export class ZixflowGeofence implements NativeGeofenceSpec {
|
|
41
|
+
/**
|
|
42
|
+
* Requests a one-shot location fix and refreshes the nearby geofence set from it,
|
|
43
|
+
* without sending a location analytics event (unlike
|
|
44
|
+
* `Zixflow.location.requestLocationUpdate()`) and without caching the fix.
|
|
45
|
+
*
|
|
46
|
+
* Call this after the host app has been granted location permission — the SDK never
|
|
47
|
+
* requests permission itself. It is the primary way to drive geofencing when the module
|
|
48
|
+
* is configured with `MANUAL` location mode; with the default `AUTOMATIC` the SDK acquires
|
|
49
|
+
* location on its own and this only forces an immediate refresh.
|
|
50
|
+
*
|
|
51
|
+
* No-ops if the geofence module is not enabled or a user has not been identified.
|
|
52
|
+
*/
|
|
53
|
+
refreshFromCurrentLocation(): void {
|
|
54
|
+
return withNativeModule((native) => native.refreshFromCurrentLocation());
|
|
55
|
+
}
|
|
56
|
+
}
|