@digia-engage/core 1.0.0 → 1.1.1
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 +64 -177
- package/android/build.gradle +1 -2
- package/android/local.properties +1 -1
- package/android/settings.gradle +2 -1
- package/android/src/main/java/com/digia/engage/rn/DigiaAnchorViewManager.kt +66 -0
- package/android/src/main/java/com/digia/engage/rn/DigiaPackage.kt +1 -0
- package/ios/DigiaAnchorViewManager.swift +43 -0
- package/ios/DigiaEngageModule.m +12 -0
- package/ios/DigiaModule.swift +75 -9
- package/lib/commonjs/DigiaAnchorView.js +22 -0
- package/lib/commonjs/DigiaAnchorView.js.map +1 -0
- package/lib/commonjs/NativeDigiaEngage.js.map +1 -1
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/DigiaAnchorView.js +16 -0
- package/lib/module/DigiaAnchorView.js.map +1 -0
- package/lib/module/NativeDigiaEngage.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/DigiaAnchorView.d.ts +21 -0
- package/lib/typescript/DigiaAnchorView.d.ts.map +1 -0
- package/lib/typescript/NativeDigiaEngage.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/react-native.config.js +23 -0
- package/src/DigiaAnchorView.tsx +22 -0
- package/src/NativeDigiaEngage.ts +1 -0
- package/src/index.ts +1 -0
- package/android/.project +0 -28
package/README.md
CHANGED
|
@@ -1,203 +1,113 @@
|
|
|
1
|
-
# @digia/
|
|
1
|
+
# @digia-engage/core
|
|
2
2
|
|
|
3
|
-
React Native
|
|
4
|
-
Jetpack Compose UI (dialogs, bottom-sheets) inside React Native applications.
|
|
3
|
+
React Native SDK for **Digia Engage** – renders native Android (Jetpack Compose) and iOS campaign UI (bottom sheets, dialogs, inline banners, tooltips, spotlights) inside React Native applications.
|
|
5
4
|
|
|
6
5
|
> **Platform support**
|
|
7
6
|
> | Platform | Status |
|
|
8
7
|
> |---|---|
|
|
9
8
|
> | Android | ✅ Full support |
|
|
10
|
-
> | iOS |
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## How it works
|
|
15
|
-
|
|
16
|
-
The Digia Engage Android SDK is built entirely with Jetpack Compose. In a
|
|
17
|
-
pure-Android app you wrap your content with the `DigiaHost { }` composable; it
|
|
18
|
-
then manages campaign-driven overlays (dialogs, bottom sheets) on top of your
|
|
19
|
-
content.
|
|
20
|
-
|
|
21
|
-
In a React Native app we cannot embed a Composable directly in the JS tree, so
|
|
22
|
-
the bridge uses two complementary mechanisms:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
┌─────────────────────────────────────────┐
|
|
26
|
-
│ Android Activity (ReactActivity) │
|
|
27
|
-
│ │
|
|
28
|
-
│ ┌─────────────────────────────────┐ │
|
|
29
|
-
│ │ Android content FrameLayout │ │
|
|
30
|
-
│ │ │ │
|
|
31
|
-
│ │ ┌─────────────────────────┐ │ │
|
|
32
|
-
│ │ │ React Native RootView │ │ │
|
|
33
|
-
│ │ │ (your JS UI) │ │ │
|
|
34
|
-
│ │ └─────────────────────────┘ │ │
|
|
35
|
-
│ │ │ │
|
|
36
|
-
│ │ ┌─────────────────────────┐ │ │
|
|
37
|
-
│ │ │ DigiaHostComposeView │ │ │
|
|
38
|
-
│ │ │ (AbstractComposeView) │ │ │
|
|
39
|
-
│ │ │ hosts DigiaHost { } │ │ │
|
|
40
|
-
│ │ │ ← transparent, no │ │ │
|
|
41
|
-
│ │ │ touch interception │ │ │
|
|
42
|
-
│ │ └─────────────────────────┘ │ │
|
|
43
|
-
│ └─────────────────────────────────┘ │
|
|
44
|
-
│ │
|
|
45
|
-
│ ┌──────────────────────────────────┐ │
|
|
46
|
-
│ │ Compose Dialog window (overlay) │ │
|
|
47
|
-
│ │ Triggered by CEP campaign │ │
|
|
48
|
-
│ └──────────────────────────────────┘ │
|
|
49
|
-
└─────────────────────────────────────────┘
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
1. **`Digia.initialize()`** initialises the SDK and calls `addContentView()`
|
|
53
|
-
to attach a transparent `DigiaHostComposeView` on top of the React Native
|
|
54
|
-
view hierarchy. This is the anchor for the Compose composition.
|
|
55
|
-
|
|
56
|
-
2. **`DigiaHost { }`** inside the `ComposeView` manages `DialogManager` and
|
|
57
|
-
`BottomSheetManager`. When a CEP plugin triggers a campaign, Compose
|
|
58
|
-
renders a `Dialog` or `ModalBottomSheet` – these are **separate Android
|
|
59
|
-
windows** that appear on top of everything, including React Native content.
|
|
60
|
-
|
|
61
|
-
3. **`<DigiaHostView>`** is an optional React Native component you can place in
|
|
62
|
-
your component tree (e.g. as `StyleSheet.absoluteFill`) if you prefer a
|
|
63
|
-
declarative, component-based mount point instead of the auto-mount.
|
|
9
|
+
> | iOS | ✅ Full support |
|
|
64
10
|
|
|
65
11
|
---
|
|
66
12
|
|
|
67
13
|
## Installation
|
|
68
14
|
|
|
69
15
|
```sh
|
|
70
|
-
|
|
71
|
-
npm install @digia/engage-react-native
|
|
72
|
-
|
|
73
|
-
# yarn
|
|
74
|
-
yarn add @digia/engage-react-native
|
|
16
|
+
npm install @digia-engage/core
|
|
75
17
|
```
|
|
76
18
|
|
|
77
|
-
React Native CLI auto-linking handles the rest.
|
|
19
|
+
React Native CLI auto-linking handles the rest. Rebuild the native app after installing:
|
|
78
20
|
|
|
79
21
|
```sh
|
|
80
|
-
npx react-native
|
|
22
|
+
npx react-native run-android
|
|
81
23
|
# or
|
|
82
24
|
cd android && ./gradlew assembleDebug
|
|
83
25
|
```
|
|
84
26
|
|
|
85
|
-
### Android – host app
|
|
27
|
+
### Android – host app dependency
|
|
86
28
|
|
|
87
|
-
|
|
88
|
-
(or include it via your local Maven / private registry):
|
|
29
|
+
Add the Digia Engage Android SDK to `android/app/build.gradle.kts`:
|
|
89
30
|
|
|
90
|
-
```
|
|
31
|
+
```kotlin
|
|
91
32
|
dependencies {
|
|
92
|
-
implementation
|
|
33
|
+
implementation("tech.digia:engage:1.1.0")
|
|
93
34
|
}
|
|
94
35
|
```
|
|
95
36
|
|
|
96
|
-
If you are working inside the monorepo and building locally, add the `:digia-ui`
|
|
97
|
-
project instead:
|
|
98
|
-
|
|
99
|
-
```groovy
|
|
100
|
-
implementation(project(':digia-ui'))
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### iOS
|
|
104
|
-
|
|
105
|
-
iOS is a no-op stub. All methods resolve immediately without error.
|
|
106
|
-
|
|
107
37
|
---
|
|
108
38
|
|
|
109
39
|
## Usage
|
|
110
40
|
|
|
111
41
|
### 1 – Initialise the SDK
|
|
112
42
|
|
|
113
|
-
Call `Digia.initialize()` once
|
|
114
|
-
`App.tsx`):
|
|
43
|
+
Call `Digia.initialize()` once at app startup, before registering any CEP plugin:
|
|
115
44
|
|
|
116
45
|
```tsx
|
|
117
|
-
import
|
|
118
|
-
import {
|
|
119
|
-
import { Digia } from '@digia/engage-react-native';
|
|
46
|
+
import { useEffect } from 'react';
|
|
47
|
+
import { Digia } from '@digia-engage/core';
|
|
120
48
|
|
|
121
|
-
export
|
|
49
|
+
export function RootApp() {
|
|
122
50
|
useEffect(() => {
|
|
123
|
-
|
|
124
|
-
apiKey: '
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
});
|
|
51
|
+
(async () => {
|
|
52
|
+
await Digia.initialize({ apiKey: 'YOUR_ACCESS_KEY' });
|
|
53
|
+
// Register your CEP plugin here (e.g. DigiaCleverTapPlugin)
|
|
54
|
+
})().catch(console.error);
|
|
128
55
|
}, []);
|
|
129
56
|
|
|
130
|
-
return <
|
|
57
|
+
return <AppNavigator />;
|
|
131
58
|
}
|
|
132
59
|
```
|
|
133
60
|
|
|
134
|
-
|
|
135
|
-
overlay host to the Activity. You do **not** need to add `<DigiaHostView>`
|
|
136
|
-
unless you want an explicit component-based mount point.
|
|
61
|
+
### 2 – Mount the overlay host
|
|
137
62
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
Wire `setCurrentScreen()` to your navigation state so the SDK can trigger
|
|
141
|
-
campaigns based on the active screen:
|
|
63
|
+
Place `<DigiaHostView>` at the app root so nudge campaigns (bottom sheets, dialogs, tooltips, spotlights) render above all content:
|
|
142
64
|
|
|
143
65
|
```tsx
|
|
144
|
-
import {
|
|
145
|
-
import {
|
|
66
|
+
import { StyleSheet, View } from 'react-native';
|
|
67
|
+
import { DigiaHostView } from '@digia-engage/core';
|
|
68
|
+
import { Stack } from 'expo-router';
|
|
146
69
|
|
|
147
|
-
|
|
148
|
-
|
|
70
|
+
export default function RootLayout() {
|
|
71
|
+
return (
|
|
72
|
+
<View style={styles.root}>
|
|
73
|
+
<DigiaHostView style={StyleSheet.absoluteFill} />
|
|
74
|
+
<Stack />
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
149
78
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const currentRoute = navRef.getCurrentRoute();
|
|
154
|
-
if (currentRoute) {
|
|
155
|
-
Digia.setCurrentScreen(currentRoute.name);
|
|
156
|
-
}
|
|
157
|
-
}}
|
|
158
|
-
>
|
|
79
|
+
const styles = StyleSheet.create({
|
|
80
|
+
root: { flex: 1 },
|
|
81
|
+
});
|
|
159
82
|
```
|
|
160
83
|
|
|
161
|
-
### 3 –
|
|
84
|
+
### 3 – Track screen changes
|
|
162
85
|
|
|
163
|
-
|
|
86
|
+
Wire `setCurrentScreen()` to your navigation library so the SDK can trigger screen-scoped campaigns:
|
|
164
87
|
|
|
165
88
|
```tsx
|
|
166
|
-
import { Digia } from '@digia/
|
|
89
|
+
import { Digia } from '@digia-engage/core';
|
|
167
90
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
91
|
+
// React Navigation example:
|
|
92
|
+
<NavigationContainer
|
|
93
|
+
onStateChange={() => {
|
|
94
|
+
const route = navRef.getCurrentRoute();
|
|
95
|
+
if (route) Digia.setCurrentScreen(route.name);
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
176
98
|
```
|
|
177
99
|
|
|
178
|
-
### 4 –
|
|
100
|
+
### 4 – Add inline slots
|
|
179
101
|
|
|
180
|
-
|
|
181
|
-
`initialize()` auto-mount and place `<DigiaHostView>` at the root of your
|
|
182
|
-
component tree:
|
|
102
|
+
Place `<DigiaSlotView>` wherever you want inline campaign content (banners, cards):
|
|
183
103
|
|
|
184
104
|
```tsx
|
|
185
|
-
import
|
|
186
|
-
import { StyleSheet, View } from 'react-native';
|
|
187
|
-
import { DigiaHostView } from '@digia/engage-react-native';
|
|
188
|
-
|
|
189
|
-
export default function App() {
|
|
190
|
-
return (
|
|
191
|
-
<View style={styles.root}>
|
|
192
|
-
{/* DigiaHostView must be above all other content in z-order */}
|
|
193
|
-
<DigiaHostView style={StyleSheet.absoluteFill} />
|
|
105
|
+
import { DigiaSlotView } from '@digia-engage/core';
|
|
194
106
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const styles = StyleSheet.create({ root: { flex: 1 } });
|
|
107
|
+
<DigiaSlotView
|
|
108
|
+
placementKey="home_hero_banner"
|
|
109
|
+
style={{ width: '100%', height: 180 }}
|
|
110
|
+
/>
|
|
201
111
|
```
|
|
202
112
|
|
|
203
113
|
---
|
|
@@ -208,9 +118,10 @@ const styles = StyleSheet.create({ root: { flex: 1 } });
|
|
|
208
118
|
|
|
209
119
|
| Method | Signature | Description |
|
|
210
120
|
|---|---|---|
|
|
211
|
-
| `initialize` | `(config: DigiaConfig) => Promise<void>` | Initialise the SDK
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
121
|
+
| `initialize` | `(config: DigiaConfig) => Promise<void>` | Initialise the SDK. Call once at app startup. |
|
|
122
|
+
| `register` | `(plugin: DigiaPlugin) => void` | Register a CEP plugin (e.g. `DigiaCleverTapPlugin`). |
|
|
123
|
+
| `unregister` | `(plugin: DigiaPlugin \| string) => void` | Unregister a plugin and call its `teardown()`. |
|
|
124
|
+
| `setCurrentScreen` | `(name: string) => void` | Notify the SDK of the current screen name. |
|
|
214
125
|
|
|
215
126
|
### `DigiaConfig`
|
|
216
127
|
|
|
@@ -220,46 +131,22 @@ const styles = StyleSheet.create({ root: { flex: 1 } });
|
|
|
220
131
|
| `environment` | `'production' \| 'sandbox'` | `'production'` | Target environment. |
|
|
221
132
|
| `logLevel` | `'none' \| 'error' \| 'verbose'` | `'error'` | Log verbosity. |
|
|
222
133
|
|
|
223
|
-
### `CreateInitialPageOptions`
|
|
224
|
-
|
|
225
|
-
Empty interface — reserved for future optional arguments.
|
|
226
|
-
|
|
227
134
|
### `<DigiaHostView>`
|
|
228
135
|
|
|
229
|
-
|
|
136
|
+
Transparent overlay that hosts Digia-rendered campaign UI (dialogs, bottom sheets, tooltips, spotlights) above app content. Mount once at the app root.
|
|
230
137
|
|
|
231
138
|
| Prop | Type | Description |
|
|
232
139
|
|---|---|---|
|
|
233
|
-
| `style` | `ViewStyle?` |
|
|
140
|
+
| `style` | `ViewStyle?` | Style for the overlay view. Typically `StyleSheet.absoluteFill`. |
|
|
234
141
|
|
|
235
|
-
|
|
142
|
+
### `<DigiaSlotView>`
|
|
236
143
|
|
|
237
|
-
|
|
144
|
+
Renders inline campaign content (banners, cards) at a named placement. Collapses to zero height when no campaign is active for the slot.
|
|
238
145
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
│ ├── types.ts ← TypeScript interfaces
|
|
244
|
-
│ ├── Digia.ts ← High-level JS SDK wrapper
|
|
245
|
-
│ ├── NativeDigiaEngage.ts ← Low-level native module binding
|
|
246
|
-
│ └── DigiaHostView.tsx ← <DigiaHostView> React component
|
|
247
|
-
│
|
|
248
|
-
├── android/
|
|
249
|
-
│ ├── build.gradle ← Android library build config
|
|
250
|
-
│ └── src/main/java/com/digia/engage/rn/
|
|
251
|
-
│ ├── DigiaPackage.kt ← ReactPackage (registers module + view)
|
|
252
|
-
│ ├── DigiaModule.kt ← NativeModule (initialize, setCurrentScreen, createInitialPage)
|
|
253
|
-
│ ├── DigiaViewManager.kt ← ViewManager for <DigiaHostView>
|
|
254
|
-
│ └── DigiaHostComposeView.kt ← AbstractComposeView hosting DigiaHost { }
|
|
255
|
-
│
|
|
256
|
-
├── ios/
|
|
257
|
-
│ └── DigiaEngageModule.m ← iOS no-op stub
|
|
258
|
-
│
|
|
259
|
-
├── DigiaEngageReactNative.podspec
|
|
260
|
-
├── react-native.config.js ← Auto-linking config
|
|
261
|
-
└── package.json
|
|
262
|
-
```
|
|
146
|
+
| Prop | Type | Description |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `placementKey` | `string` | Must match the placement key in your CEP campaign. |
|
|
149
|
+
| `style` | `ViewStyle?` | An explicit height is required — the slot is not visible without one. |
|
|
263
150
|
|
|
264
151
|
---
|
|
265
152
|
|
package/android/build.gradle
CHANGED
|
@@ -70,8 +70,7 @@ android {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
dependencies {
|
|
73
|
-
|
|
74
|
-
implementation 'tech.digia:engage:1.0.0-beta.04'
|
|
73
|
+
implementation 'tech.digia:engage:1.1.0'
|
|
75
74
|
|
|
76
75
|
// ── React Native ─────────────────────────────────────────────────────────
|
|
77
76
|
// React Native is provided by the host app; mark as compileOnly so it is
|
package/android/local.properties
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
sdk.dir=/Users/
|
|
1
|
+
sdk.dir=/Users/adityachoubey/Library/Android/sdk
|
package/android/settings.gradle
CHANGED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
package com.digia.engage.rn
|
|
2
|
+
|
|
3
|
+
import android.graphics.Color
|
|
4
|
+
import android.graphics.Outline
|
|
5
|
+
import android.view.View
|
|
6
|
+
import android.view.ViewOutlineProvider
|
|
7
|
+
import android.widget.FrameLayout
|
|
8
|
+
import androidx.lifecycle.LifecycleOwner
|
|
9
|
+
import androidx.lifecycle.ViewModelStoreOwner
|
|
10
|
+
import androidx.lifecycle.setViewTreeLifecycleOwner
|
|
11
|
+
import androidx.lifecycle.setViewTreeViewModelStoreOwner
|
|
12
|
+
import androidx.savedstate.SavedStateRegistryOwner
|
|
13
|
+
import androidx.savedstate.setViewTreeSavedStateRegistryOwner
|
|
14
|
+
import com.digia.engage.DigiaAnchorView
|
|
15
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
16
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
17
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
18
|
+
|
|
19
|
+
internal class DigiaAnchorViewManager : ViewGroupManager<DigiaAnchorView>() {
|
|
20
|
+
|
|
21
|
+
override fun getName(): String = VIEW_NAME
|
|
22
|
+
|
|
23
|
+
override fun createViewInstance(context: ThemedReactContext): DigiaAnchorView {
|
|
24
|
+
val activityContext = context.currentActivity ?: context
|
|
25
|
+
val view = DigiaAnchorView(activityContext)
|
|
26
|
+
|
|
27
|
+
val activity = context.currentActivity
|
|
28
|
+
if (activity is LifecycleOwner) view.setViewTreeLifecycleOwner(activity)
|
|
29
|
+
if (activity is ViewModelStoreOwner) view.setViewTreeViewModelStoreOwner(activity)
|
|
30
|
+
if (activity is SavedStateRegistryOwner) view.setViewTreeSavedStateRegistryOwner(activity)
|
|
31
|
+
|
|
32
|
+
view.layoutParams = FrameLayout.LayoutParams(
|
|
33
|
+
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
34
|
+
FrameLayout.LayoutParams.WRAP_CONTENT,
|
|
35
|
+
)
|
|
36
|
+
// Prevent the FrameLayout background from leaking white in spotlight corners.
|
|
37
|
+
view.setBackgroundColor(Color.TRANSPARENT)
|
|
38
|
+
return view
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@ReactProp(name = "anchorKey")
|
|
42
|
+
fun setAnchorKey(view: DigiaAnchorView, anchorKey: String?) {
|
|
43
|
+
view.anchorKey = anchorKey.orEmpty()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@ReactProp(name = "cornerRadius", defaultFloat = 0f)
|
|
47
|
+
fun setCornerRadius(view: DigiaAnchorView, cornerRadius: Float) {
|
|
48
|
+
val px = cornerRadius * view.resources.displayMetrics.density
|
|
49
|
+
view.spotlightCornerRadius = px
|
|
50
|
+
if (px > 0f) {
|
|
51
|
+
view.outlineProvider = object : ViewOutlineProvider() {
|
|
52
|
+
override fun getOutline(v: View, outline: Outline) {
|
|
53
|
+
outline.setRoundRect(0, 0, v.width, v.height, px)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
view.clipToOutline = true
|
|
57
|
+
} else {
|
|
58
|
+
view.clipToOutline = false
|
|
59
|
+
view.outlineProvider = ViewOutlineProvider.BOUNDS
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
companion object {
|
|
64
|
+
const val VIEW_NAME = "DigiaAnchorView"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import React
|
|
2
|
+
import UIKit
|
|
3
|
+
import DigiaEngage
|
|
4
|
+
|
|
5
|
+
@objc(DigiaAnchorView)
|
|
6
|
+
final class DigiaAnchorViewManager: RCTViewManager {
|
|
7
|
+
|
|
8
|
+
override static func requiresMainQueueSetup() -> Bool { true }
|
|
9
|
+
|
|
10
|
+
override func view() -> UIView! {
|
|
11
|
+
return DigiaAnchorUIView()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@objc func setAnchorKey(_ anchorKey: String, forView view: DigiaAnchorUIView) {
|
|
15
|
+
view.anchorKey = anchorKey
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// MARK: - DigiaAnchorUIView
|
|
20
|
+
|
|
21
|
+
final class DigiaAnchorUIView: UIView {
|
|
22
|
+
|
|
23
|
+
var anchorKey: String = "" {
|
|
24
|
+
didSet {
|
|
25
|
+
guard anchorKey != oldValue else { return }
|
|
26
|
+
if !oldValue.isEmpty {
|
|
27
|
+
AnchorRegistry.shared.unregister(key: oldValue)
|
|
28
|
+
}
|
|
29
|
+
if !anchorKey.isEmpty, window != nil {
|
|
30
|
+
AnchorRegistry.shared.register(key: anchorKey, view: self)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override func didMoveToWindow() {
|
|
36
|
+
super.didMoveToWindow()
|
|
37
|
+
if window != nil, !anchorKey.isEmpty {
|
|
38
|
+
AnchorRegistry.shared.register(key: anchorKey, view: self)
|
|
39
|
+
} else if window == nil, !anchorKey.isEmpty {
|
|
40
|
+
AnchorRegistry.shared.unregister(key: anchorKey)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
package/ios/DigiaEngageModule.m
CHANGED
|
@@ -38,6 +38,14 @@ RCT_EXTERN_METHOD(triggerCampaign:(NSString *)id
|
|
|
38
38
|
|
|
39
39
|
RCT_EXTERN_METHOD(invalidateCampaign:(NSString *)campaignId)
|
|
40
40
|
|
|
41
|
+
RCT_EXTERN_METHOD(showAnchoredOverlay:(NSString *)id
|
|
42
|
+
content:(NSDictionary *)content
|
|
43
|
+
cepContext:(NSDictionary *)cepContext
|
|
44
|
+
anchorX:(double)anchorX
|
|
45
|
+
anchorY:(double)anchorY
|
|
46
|
+
anchorWidth:(double)anchorWidth
|
|
47
|
+
anchorHeight:(double)anchorHeight)
|
|
48
|
+
|
|
41
49
|
@end
|
|
42
50
|
|
|
43
51
|
|
|
@@ -50,3 +58,7 @@ RCT_EXTERN_METHOD(invalidateCampaign:(NSString *)campaignId)
|
|
|
50
58
|
RCT_EXPORT_VIEW_PROPERTY(placementKey, NSString)
|
|
51
59
|
RCT_EXPORT_VIEW_PROPERTY(onContentSizeChange, RCTDirectEventBlock)
|
|
52
60
|
@end
|
|
61
|
+
|
|
62
|
+
@interface RCT_EXTERN_MODULE(DigiaAnchorView, RCTViewManager)
|
|
63
|
+
RCT_EXPORT_VIEW_PROPERTY(anchorKey, NSString)
|
|
64
|
+
@end
|
package/ios/DigiaModule.swift
CHANGED
|
@@ -151,6 +151,41 @@ final class DigiaModule: RCTEventEmitter {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
155
|
+
// MARK: - showAnchoredOverlay
|
|
156
|
+
|
|
157
|
+
/// Shows SHOW_TOOLTIP or SHOW_SPOTLIGHT anchored to coordinates measured in JS.
|
|
158
|
+
/// anchorX/Y/Width/Height are screen-pixel values from measureInWindow().
|
|
159
|
+
@objc
|
|
160
|
+
func showAnchoredOverlay(
|
|
161
|
+
_ id: String,
|
|
162
|
+
content contentMap: NSDictionary,
|
|
163
|
+
cepContext cepContextMap: NSDictionary,
|
|
164
|
+
anchorX: Double,
|
|
165
|
+
anchorY: Double,
|
|
166
|
+
anchorWidth: Double,
|
|
167
|
+
anchorHeight: Double
|
|
168
|
+
) {
|
|
169
|
+
let mutable = NSMutableDictionary(dictionary: contentMap)
|
|
170
|
+
// Pack anchor coords into the args sub-dict so buildInAppPayloadContent
|
|
171
|
+
// captures them as JSONValue entries in InAppPayloadContent.args.
|
|
172
|
+
var argsDict = (mutable["args"] as? [String: Any]) ?? [:]
|
|
173
|
+
argsDict["_anchorX"] = anchorX
|
|
174
|
+
argsDict["_anchorY"] = anchorY
|
|
175
|
+
argsDict["_anchorWidth"] = anchorWidth
|
|
176
|
+
argsDict["_anchorHeight"] = anchorHeight
|
|
177
|
+
mutable["args"] = argsDict
|
|
178
|
+
|
|
179
|
+
let content = buildInAppPayloadContent(from: mutable)
|
|
180
|
+
let cepContext = (cepContextMap as? [String: String]) ?? [:]
|
|
181
|
+
let payload = InAppPayload(id: id, content: content, cepContext: cepContext)
|
|
182
|
+
|
|
183
|
+
Task { @MainActor in
|
|
184
|
+
guard let delegate = self.rnPlugin.delegate else { return }
|
|
185
|
+
delegate.onCampaignTriggered(payload)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
154
189
|
// ────────────────────────────────────────────────────────────────────────
|
|
155
190
|
// MARK: - Internal: mount the SwiftUI overlay host
|
|
156
191
|
|
|
@@ -170,22 +205,34 @@ final class DigiaModule: RCTEventEmitter {
|
|
|
170
205
|
let mountTag = 0xD19140
|
|
171
206
|
if rootVC.view.viewWithTag(mountTag) != nil { return }
|
|
172
207
|
|
|
208
|
+
// Container with passthrough hitTest — lets tooltip card taps reach SwiftUI
|
|
209
|
+
// while all other touches fall through to React Native content.
|
|
210
|
+
let container = DigiaPassthroughHostView()
|
|
211
|
+
container.tag = mountTag
|
|
212
|
+
container.translatesAutoresizingMaskIntoConstraints = false
|
|
213
|
+
container.backgroundColor = .clear
|
|
214
|
+
|
|
173
215
|
let hc = UIHostingController(rootView: DigiaHostWrapperView())
|
|
174
|
-
hc.view.tag = mountTag
|
|
175
216
|
hc.view.translatesAutoresizingMaskIntoConstraints = false
|
|
176
217
|
hc.view.backgroundColor = .clear
|
|
177
|
-
|
|
178
|
-
|
|
218
|
+
|
|
219
|
+
container.hostingView = hc.view
|
|
179
220
|
|
|
180
221
|
rootVC.addChild(hc)
|
|
181
|
-
|
|
222
|
+
container.addSubview(hc.view)
|
|
182
223
|
hc.didMove(toParent: rootVC)
|
|
183
224
|
|
|
225
|
+
rootVC.view.addSubview(container)
|
|
226
|
+
|
|
184
227
|
NSLayoutConstraint.activate([
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
228
|
+
container.leadingAnchor.constraint(equalTo: rootVC.view.leadingAnchor),
|
|
229
|
+
container.trailingAnchor.constraint(equalTo: rootVC.view.trailingAnchor),
|
|
230
|
+
container.topAnchor.constraint(equalTo: rootVC.view.topAnchor),
|
|
231
|
+
container.bottomAnchor.constraint(equalTo: rootVC.view.bottomAnchor),
|
|
232
|
+
hc.view.leadingAnchor.constraint(equalTo: container.leadingAnchor),
|
|
233
|
+
hc.view.trailingAnchor.constraint(equalTo: container.trailingAnchor),
|
|
234
|
+
hc.view.topAnchor.constraint(equalTo: container.topAnchor),
|
|
235
|
+
hc.view.bottomAnchor.constraint(equalTo: container.bottomAnchor),
|
|
189
236
|
])
|
|
190
237
|
}
|
|
191
238
|
|
|
@@ -208,6 +255,8 @@ final class DigiaModule: RCTEventEmitter {
|
|
|
208
255
|
return raw.compactMapValues { JSONValue(rawValue: $0) }
|
|
209
256
|
}()
|
|
210
257
|
|
|
258
|
+
let anchorKey = map["anchorKey"] as? String
|
|
259
|
+
|
|
211
260
|
return InAppPayloadContent(
|
|
212
261
|
type: type,
|
|
213
262
|
placementKey: pk,
|
|
@@ -216,11 +265,28 @@ final class DigiaModule: RCTEventEmitter {
|
|
|
216
265
|
viewId: viewId,
|
|
217
266
|
command: command,
|
|
218
267
|
args: args,
|
|
219
|
-
screenId: screenId
|
|
268
|
+
screenId: screenId,
|
|
269
|
+
anchorKey: anchorKey
|
|
220
270
|
)
|
|
221
271
|
}
|
|
222
272
|
}
|
|
223
273
|
|
|
274
|
+
// MARK: - DigiaPassthroughHostView
|
|
275
|
+
|
|
276
|
+
/// Container that delegates hitTest to the SwiftUI hosting view.
|
|
277
|
+
/// When SwiftUI renders nothing interactive (no overlay), hitTest returns nil
|
|
278
|
+
/// so touches fall through to React Native. When an overlay is visible,
|
|
279
|
+
/// taps on it are consumed by SwiftUI.
|
|
280
|
+
private final class DigiaPassthroughHostView: UIView {
|
|
281
|
+
weak var hostingView: UIView?
|
|
282
|
+
|
|
283
|
+
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
|
284
|
+
guard let hv = hostingView else { return nil }
|
|
285
|
+
let converted = convert(point, to: hv)
|
|
286
|
+
return hv.hitTest(converted, with: event)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
224
290
|
// MARK: - JSONValue convenience init from Any
|
|
225
291
|
private extension JSONValue {
|
|
226
292
|
init?(rawValue: Any) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DigiaAnchorView = void 0;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
/**
|
|
9
|
+
* DigiaAnchorView
|
|
10
|
+
*
|
|
11
|
+
* Registers a native Android DigiaAnchorView (FrameLayout) in AnchorRegistry by anchorKey.
|
|
12
|
+
* When a SHOW_TOOLTIP or SHOW_SPOTLIGHT campaign fires, the native SDK looks up this view
|
|
13
|
+
* via AnchorRegistry and uses getLocationOnScreen() for accurate pixel-perfect coordinates.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* <DigiaAnchorView anchorKey="pdp_add_to_cart" style={{ alignSelf: 'flex-start' }}>
|
|
17
|
+
* <TouchableOpacity ...>Add to Cart</TouchableOpacity>
|
|
18
|
+
* </DigiaAnchorView>
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const DigiaAnchorView = exports.DigiaAnchorView = (0, _reactNative.requireNativeComponent)('DigiaAnchorView');
|
|
22
|
+
//# sourceMappingURL=DigiaAnchorView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNative","require","DigiaAnchorView","exports","requireNativeComponent"],"sourceRoot":"../../src","sources":["DigiaAnchorView.tsx"],"mappings":";;;;;;AAaA,IAAAA,YAAA,GAAAC,OAAA;AAbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUO,MAAMC,eAAe,GAAAC,OAAA,CAAAD,eAAA,GAAG,IAAAE,mCAAsB,EAAuB,iBAAiB,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_resolved","getModule","TurboModuleRegistry","get","NativeModules","DigiaEngageModule","__DEV__","console","warn","nativeDigiaModule","exports","initialize","apiKey","environment","logLevel","Promise","resolve","registerBridge","setCurrentScreen","name","triggerCampaign","id","content","cepContext","invalidateCampaign","campaignId","getConstants"],"sourceRoot":"../../src","sources":["NativeDigiaEngage.ts"],"mappings":";;;;;;AAgBA,IAAAA,YAAA,GAAAC,OAAA;AAhBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_resolved","getModule","TurboModuleRegistry","get","NativeModules","DigiaEngageModule","__DEV__","console","warn","nativeDigiaModule","exports","initialize","apiKey","environment","logLevel","Promise","resolve","registerBridge","setCurrentScreen","name","triggerCampaign","id","content","cepContext","invalidateCampaign","campaignId","getConstants"],"sourceRoot":"../../src","sources":["NativeDigiaEngage.ts"],"mappings":";;;;;;AAgBA,IAAAA,YAAA,GAAAC,OAAA;AAhBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA+BA;AACA;AACA;AACA;AACA;AACA;AACA,IAAIC,SAAsB,GAAG,IAAI;AACjC,SAASC,SAASA,CAAA,EAAgB;EAC9B,IAAID,SAAS,KAAK,IAAI,EAAE,OAAOA,SAAS;EACxCA,SAAS,GACLE,gCAAmB,CAACC,GAAG,CAAO,mBAAmB,CAAC,IACjDC,0BAAa,CAACC,iBAAsC,IACrD,IAAI;EACR,IAAIC,OAAO,IAAI,CAACN,SAAS,EAAE;IACvBO,OAAO,CAACC,IAAI,CACR,wCAAwC,GACxC,iEACJ,CAAC;EACL;EACA,OAAOR,SAAS;AACpB;AAEO,MAAMS,iBAAuB,GAAAC,OAAA,CAAAD,iBAAA,GAAG;EACnCE,UAAU,EAAEA,CAACC,MAAM,EAAEC,WAAW,EAAEC,QAAQ,KACtCb,SAAS,CAAC,CAAC,EAAEU,UAAU,CAACC,MAAM,EAAEC,WAAW,EAAEC,QAAQ,CAAC,IAAIC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC/EC,cAAc,EAAEA,CAAA,KAAMhB,SAAS,CAAC,CAAC,EAAEgB,cAAc,CAAC,CAAC;EACnDC,gBAAgB,EAAGC,IAAI,IAAKlB,SAAS,CAAC,CAAC,EAAEiB,gBAAgB,CAACC,IAAI,CAAC;EAC/DC,eAAe,EAAEA,CAACC,EAAE,EAAEC,OAAO,EAAEC,UAAU,KACrCtB,SAAS,CAAC,CAAC,EAAEmB,eAAe,CAACC,EAAE,EAAEC,OAAO,EAAEC,UAAU,CAAC;EACzDC,kBAAkB,EAAGC,UAAU,IAAKxB,SAAS,CAAC,CAAC,EAAEuB,kBAAkB,CAACC,UAAU,CAAC;EAC/EC,YAAY,EAAEA,CAAA,KAAMzB,SAAS,CAAC,CAAC,EAAEyB,YAAY,GAAG,CAAC,IAAI,CAAC;AAC1D,CAAC","ignoreList":[]}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "Digia", {
|
|
|
9
9
|
return _Digia.Digia;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "DigiaAnchorView", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _DigiaAnchorView.DigiaAnchorView;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
12
18
|
Object.defineProperty(exports, "DigiaHostView", {
|
|
13
19
|
enumerable: true,
|
|
14
20
|
get: function () {
|
|
@@ -24,4 +30,5 @@ Object.defineProperty(exports, "DigiaSlotView", {
|
|
|
24
30
|
var _Digia = require("./Digia");
|
|
25
31
|
var _DigiaHostView = require("./DigiaHostView");
|
|
26
32
|
var _DigiaSlotView = require("./DigiaSlotView");
|
|
33
|
+
var _DigiaAnchorView = require("./DigiaAnchorView");
|
|
27
34
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_Digia","require","_DigiaHostView","_DigiaSlotView"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_Digia","require","_DigiaHostView","_DigiaSlotView","_DigiaAnchorView"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AACA,IAAAE,cAAA,GAAAF,OAAA;AACA,IAAAG,gBAAA,GAAAH,OAAA","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaAnchorView
|
|
3
|
+
*
|
|
4
|
+
* Registers a native Android DigiaAnchorView (FrameLayout) in AnchorRegistry by anchorKey.
|
|
5
|
+
* When a SHOW_TOOLTIP or SHOW_SPOTLIGHT campaign fires, the native SDK looks up this view
|
|
6
|
+
* via AnchorRegistry and uses getLocationOnScreen() for accurate pixel-perfect coordinates.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <DigiaAnchorView anchorKey="pdp_add_to_cart" style={{ alignSelf: 'flex-start' }}>
|
|
10
|
+
* <TouchableOpacity ...>Add to Cart</TouchableOpacity>
|
|
11
|
+
* </DigiaAnchorView>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { requireNativeComponent } from 'react-native';
|
|
15
|
+
export const DigiaAnchorView = requireNativeComponent('DigiaAnchorView');
|
|
16
|
+
//# sourceMappingURL=DigiaAnchorView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["requireNativeComponent","DigiaAnchorView"],"sourceRoot":"../../src","sources":["DigiaAnchorView.tsx"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,sBAAsB,QAAwB,cAAc;AAQrE,OAAO,MAAMC,eAAe,GAAGD,sBAAsB,CAAuB,iBAAiB,CAAC","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","TurboModuleRegistry","_resolved","getModule","get","DigiaEngageModule","__DEV__","console","warn","nativeDigiaModule","initialize","apiKey","environment","logLevel","Promise","resolve","registerBridge","setCurrentScreen","name","triggerCampaign","id","content","cepContext","invalidateCampaign","campaignId","getConstants"],"sourceRoot":"../../src","sources":["NativeDigiaEngage.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,aAAa,EAAEC,mBAAmB,QAAQ,cAAc;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;
|
|
1
|
+
{"version":3,"names":["NativeModules","TurboModuleRegistry","_resolved","getModule","get","DigiaEngageModule","__DEV__","console","warn","nativeDigiaModule","initialize","apiKey","environment","logLevel","Promise","resolve","registerBridge","setCurrentScreen","name","triggerCampaign","id","content","cepContext","invalidateCampaign","campaignId","getConstants"],"sourceRoot":"../../src","sources":["NativeDigiaEngage.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,aAAa,EAAEC,mBAAmB,QAAQ,cAAc;;AAEjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA+BA;AACA;AACA;AACA;AACA;AACA;AACA,IAAIC,SAAsB,GAAG,IAAI;AACjC,SAASC,SAASA,CAAA,EAAgB;EAC9B,IAAID,SAAS,KAAK,IAAI,EAAE,OAAOA,SAAS;EACxCA,SAAS,GACLD,mBAAmB,CAACG,GAAG,CAAO,mBAAmB,CAAC,IACjDJ,aAAa,CAACK,iBAAsC,IACrD,IAAI;EACR,IAAIC,OAAO,IAAI,CAACJ,SAAS,EAAE;IACvBK,OAAO,CAACC,IAAI,CACR,wCAAwC,GACxC,iEACJ,CAAC;EACL;EACA,OAAON,SAAS;AACpB;AAEA,OAAO,MAAMO,iBAAuB,GAAG;EACnCC,UAAU,EAAEA,CAACC,MAAM,EAAEC,WAAW,EAAEC,QAAQ,KACtCV,SAAS,CAAC,CAAC,EAAEO,UAAU,CAACC,MAAM,EAAEC,WAAW,EAAEC,QAAQ,CAAC,IAAIC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC/EC,cAAc,EAAEA,CAAA,KAAMb,SAAS,CAAC,CAAC,EAAEa,cAAc,CAAC,CAAC;EACnDC,gBAAgB,EAAGC,IAAI,IAAKf,SAAS,CAAC,CAAC,EAAEc,gBAAgB,CAACC,IAAI,CAAC;EAC/DC,eAAe,EAAEA,CAACC,EAAE,EAAEC,OAAO,EAAEC,UAAU,KACrCnB,SAAS,CAAC,CAAC,EAAEgB,eAAe,CAACC,EAAE,EAAEC,OAAO,EAAEC,UAAU,CAAC;EACzDC,kBAAkB,EAAGC,UAAU,IAAKrB,SAAS,CAAC,CAAC,EAAEoB,kBAAkB,CAACC,UAAU,CAAC;EAC/EC,YAAY,EAAEA,CAAA,KAAMtB,SAAS,CAAC,CAAC,EAAEsB,YAAY,GAAG,CAAC,IAAI,CAAC;AAC1D,CAAC","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Digia","DigiaHostView","DigiaSlotView"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,KAAK,QAAQ,SAAS;AAC/B,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,SAASC,aAAa,QAAQ,iBAAiB","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Digia","DigiaHostView","DigiaSlotView","DigiaAnchorView"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,KAAK,QAAQ,SAAS;AAC/B,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,SAASC,aAAa,QAAQ,iBAAiB;AAC/C,SAASC,eAAe,QAAQ,mBAAmB","ignoreList":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaAnchorView
|
|
3
|
+
*
|
|
4
|
+
* Registers a native Android DigiaAnchorView (FrameLayout) in AnchorRegistry by anchorKey.
|
|
5
|
+
* When a SHOW_TOOLTIP or SHOW_SPOTLIGHT campaign fires, the native SDK looks up this view
|
|
6
|
+
* via AnchorRegistry and uses getLocationOnScreen() for accurate pixel-perfect coordinates.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <DigiaAnchorView anchorKey="pdp_add_to_cart" style={{ alignSelf: 'flex-start' }}>
|
|
10
|
+
* <TouchableOpacity ...>Add to Cart</TouchableOpacity>
|
|
11
|
+
* </DigiaAnchorView>
|
|
12
|
+
*/
|
|
13
|
+
import { type ViewProps } from 'react-native';
|
|
14
|
+
interface DigiaAnchorViewProps extends ViewProps {
|
|
15
|
+
anchorKey: string;
|
|
16
|
+
/** Corner radius in dp — used to round the spotlight cutout to match the wrapped button. */
|
|
17
|
+
cornerRadius?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DigiaAnchorView: import("react-native").HostComponent<DigiaAnchorViewProps>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=DigiaAnchorView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DigiaAnchorView.d.ts","sourceRoot":"","sources":["../../src/DigiaAnchorView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAA0B,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtE,UAAU,oBAAqB,SAAQ,SAAS;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,4FAA4F;IAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,eAAe,4DAAkE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeDigiaEngage.d.ts","sourceRoot":"","sources":["../../src/NativeDigiaEngage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACrC,0DAA0D;IAC1D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;;;OAIG;IACH,cAAc,IAAI,IAAI,CAAC;IAEvB,sDAAsD;IACtD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,eAAe,CACX,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,IAAI,CAAC;IAER,iDAAiD;IACjD,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAEhD;
|
|
1
|
+
{"version":3,"file":"NativeDigiaEngage.d.ts","sourceRoot":"","sources":["../../src/NativeDigiaEngage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD;;;;;;;GAOG;AACH,MAAM,WAAW,IAAK,SAAQ,WAAW;IACrC,0DAA0D;IAC1D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjF;;;;OAIG;IACH,cAAc,IAAI,IAAI,CAAC;IAEvB,sDAAsD;IACtD,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,eAAe,CACX,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACnB,IAAI,CAAC;IAER,iDAAiD;IACjD,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAEhD;AAyBD,eAAO,MAAM,iBAAiB,EAAE,IAS/B,CAAC"}
|
|
@@ -11,5 +11,6 @@
|
|
|
11
11
|
export { Digia } from './Digia';
|
|
12
12
|
export { DigiaHostView } from './DigiaHostView';
|
|
13
13
|
export { DigiaSlotView } from './DigiaSlotView';
|
|
14
|
+
export { DigiaAnchorView } from './DigiaAnchorView';
|
|
14
15
|
export type { DigiaConfig, DigiaDelegate, DigiaExperienceEvent, DigiaPlugin, InAppPayload } from './types';
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,oBAAoB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digia-engage/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "React Native bridge for Digia Engage – renders native Android Compose UI inside React Native apps",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"android",
|
|
14
14
|
"ios",
|
|
15
15
|
"*.podspec",
|
|
16
|
+
"react-native.config.js",
|
|
16
17
|
"!lib/typescript/example",
|
|
17
18
|
"!android/.gradle",
|
|
18
19
|
"!android/build",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* react-native.config.js
|
|
3
|
+
*
|
|
4
|
+
* Configures React Native CLI auto-linking for @digia/engage-react-native.
|
|
5
|
+
* This tells the RN CLI where to find the Android library module and the
|
|
6
|
+
* iOS podspec so that `npx react-native link` / auto-linking works without
|
|
7
|
+
* any manual steps in host app project files.
|
|
8
|
+
*/
|
|
9
|
+
module.exports = {
|
|
10
|
+
dependency: {
|
|
11
|
+
platforms: {
|
|
12
|
+
android: {
|
|
13
|
+
// Path to the Android library module (relative to this package root)
|
|
14
|
+
sourceDir: './android',
|
|
15
|
+
packageImportPath: 'import com.digia.engage.rn.DigiaPackage;',
|
|
16
|
+
packageInstance: 'new DigiaPackage()',
|
|
17
|
+
},
|
|
18
|
+
ios: {
|
|
19
|
+
podspecPath: './DigiaEngageReactNative.podspec',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DigiaAnchorView
|
|
3
|
+
*
|
|
4
|
+
* Registers a native Android DigiaAnchorView (FrameLayout) in AnchorRegistry by anchorKey.
|
|
5
|
+
* When a SHOW_TOOLTIP or SHOW_SPOTLIGHT campaign fires, the native SDK looks up this view
|
|
6
|
+
* via AnchorRegistry and uses getLocationOnScreen() for accurate pixel-perfect coordinates.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* <DigiaAnchorView anchorKey="pdp_add_to_cart" style={{ alignSelf: 'flex-start' }}>
|
|
10
|
+
* <TouchableOpacity ...>Add to Cart</TouchableOpacity>
|
|
11
|
+
* </DigiaAnchorView>
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { requireNativeComponent, type ViewProps } from 'react-native';
|
|
15
|
+
|
|
16
|
+
interface DigiaAnchorViewProps extends ViewProps {
|
|
17
|
+
anchorKey: string;
|
|
18
|
+
/** Corner radius in dp — used to round the spotlight cutout to match the wrapped button. */
|
|
19
|
+
cornerRadius?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const DigiaAnchorView = requireNativeComponent<DigiaAnchorViewProps>('DigiaAnchorView');
|
package/src/NativeDigiaEngage.ts
CHANGED
|
@@ -53,6 +53,7 @@ export interface Spec extends TurboModule {
|
|
|
53
53
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
|
|
56
57
|
// Try TurboModuleRegistry first (New Architecture / JSI).
|
|
57
58
|
// Fall back to NativeModules (bridge interop layer — enabled by default in
|
|
58
59
|
// RN 0.73+ New Architecture when the module is registered with
|
package/src/index.ts
CHANGED
|
@@ -12,4 +12,5 @@
|
|
|
12
12
|
export { Digia } from './Digia';
|
|
13
13
|
export { DigiaHostView } from './DigiaHostView';
|
|
14
14
|
export { DigiaSlotView } from './DigiaSlotView';
|
|
15
|
+
export { DigiaAnchorView } from './DigiaAnchorView';
|
|
15
16
|
export type { DigiaConfig, DigiaDelegate, DigiaExperienceEvent, DigiaPlugin, InAppPayload } from './types';
|
package/android/.project
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<projectDescription>
|
|
3
|
-
<name>digia-engage_core</name>
|
|
4
|
-
<comment>Project digia-engage_core created by Buildship.</comment>
|
|
5
|
-
<projects>
|
|
6
|
-
</projects>
|
|
7
|
-
<buildSpec>
|
|
8
|
-
<buildCommand>
|
|
9
|
-
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
10
|
-
<arguments>
|
|
11
|
-
</arguments>
|
|
12
|
-
</buildCommand>
|
|
13
|
-
</buildSpec>
|
|
14
|
-
<natures>
|
|
15
|
-
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
16
|
-
</natures>
|
|
17
|
-
<filteredResources>
|
|
18
|
-
<filter>
|
|
19
|
-
<id>1775559486270</id>
|
|
20
|
-
<name></name>
|
|
21
|
-
<type>30</type>
|
|
22
|
-
<matcher>
|
|
23
|
-
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
24
|
-
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
25
|
-
</matcher>
|
|
26
|
-
</filter>
|
|
27
|
-
</filteredResources>
|
|
28
|
-
</projectDescription>
|