@digia-engage/core 2.2.1 → 2.3.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/DigiaEngageReactNative.podspec +1 -1
- package/LICENSE +77 -0
- package/README.md +1 -1
- package/lib/commonjs/Digia.js +1 -1
- package/lib/commonjs/DigiaAnchorView.js +42 -25
- package/lib/commonjs/DigiaAnchorView.js.map +1 -1
- package/lib/commonjs/DigiaHealthReporter.js +1 -1
- package/lib/commonjs/DigiaProvider.js +38 -6
- package/lib/commonjs/DigiaProvider.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/Digia.js +1 -1
- package/lib/module/DigiaAnchorView.js +42 -25
- package/lib/module/DigiaAnchorView.js.map +1 -1
- package/lib/module/DigiaHealthReporter.js +1 -1
- package/lib/module/DigiaProvider.js +38 -6
- package/lib/module/DigiaProvider.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/DigiaAnchorView.d.ts +17 -1
- package/lib/typescript/DigiaAnchorView.d.ts.map +1 -1
- package/lib/typescript/DigiaProvider.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/templateTypes.d.ts +2 -0
- package/lib/typescript/templateTypes.d.ts.map +1 -1
- package/package.json +2 -8
- package/src/Digia.ts +1 -1
- package/src/DigiaAnchorView.tsx +74 -41
- package/src/DigiaHealthReporter.ts +1 -1
- package/src/DigiaProvider.tsx +36 -6
- package/src/index.ts +1 -0
- package/src/templateTypes.ts +2 -0
- package/android/.project +0 -28
- package/android/bin/.gradle/8.13/fileHashes/fileHashes.lock +0 -0
- package/android/bin/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/bin/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/bin/.project +0 -34
- package/android/bin/build/generated/source/buildConfig/debug/com/digia/engage/rn/BuildConfig.class +0 -0
- package/android/bin/build/generated/source/codegen/java/com/digia/engage/rn/NativeDigiaEngageSpec.class +0 -0
- package/android/bin/build.gradle +0 -97
- package/android/bin/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/bin/gradle/wrapper/gradle-wrapper.properties +0 -5
- package/android/bin/gradle.properties +0 -2
- package/android/bin/gradlew +0 -185
- package/android/bin/gradlew.bat +0 -89
- package/android/bin/local.properties +0 -1
- package/android/bin/settings.gradle +0 -25
- package/android/bin/src/main/AndroidManifest.xml +0 -2
- package/android/bin/src/main/java/com/digia/engage/rn/DigiaAnchorViewManager.kt +0 -90
- package/android/bin/src/main/java/com/digia/engage/rn/DigiaModule.kt +0 -309
- package/android/bin/src/main/java/com/digia/engage/rn/DigiaPackage.kt +0 -70
- package/android/bin/src/main/java/com/digia/engage/rn/DigiaSlotViewManager.kt +0 -183
- package/android/bin/src/main/java/com/digia/engage/rn/DigiaViewManager.kt +0 -64
- package/android/local.properties +0 -1
package/src/DigiaAnchorView.tsx
CHANGED
|
@@ -1,54 +1,87 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef } from 'react';
|
|
1
|
+
import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import type { ViewProps } from 'react-native';
|
|
4
4
|
import { Digia } from './Digia';
|
|
5
5
|
import { nativeDigiaModule } from './NativeDigiaEngage';
|
|
6
6
|
import { digiaAnchorRegistry } from './digiaAnchorRegistry';
|
|
7
7
|
|
|
8
|
+
export interface DigiaAnchorViewRef {
|
|
9
|
+
/**
|
|
10
|
+
* Tell the anchor that the entrance/layout animation wrapping it has
|
|
11
|
+
* finished. The anchor then captures its final, resting position and
|
|
12
|
+
* publishes it to the registry so tooltips can attach to it.
|
|
13
|
+
*
|
|
14
|
+
* Attaching a ref is itself the signal that this anchor is animated: until
|
|
15
|
+
* the first `animationCompleted()` call the anchor publishes NOTHING, so a
|
|
16
|
+
* guide that triggers mid-animation simply finds no layout and stays
|
|
17
|
+
* invisible instead of painting at a transient (wrong) position.
|
|
18
|
+
*
|
|
19
|
+
* If you never attach a ref, none of this applies — the anchor measures on
|
|
20
|
+
* layout exactly as a static anchor always has.
|
|
21
|
+
*/
|
|
22
|
+
animationCompleted: () => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
interface Props extends ViewProps {
|
|
9
26
|
anchorKey: string;
|
|
10
27
|
children?: React.ReactNode;
|
|
11
28
|
}
|
|
12
29
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Digia.unregisterAnchor(anchorKey);
|
|
18
|
-
digiaAnchorRegistry.remove(anchorKey);
|
|
19
|
-
};
|
|
20
|
-
}, [anchorKey]);
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<JsMeasureAnchor anchorKey={anchorKey} style={style} {...rest}>
|
|
24
|
-
{children}
|
|
25
|
-
</JsMeasureAnchor>
|
|
26
|
-
);
|
|
27
|
-
}
|
|
30
|
+
export const DigiaAnchorView = forwardRef<DigiaAnchorViewRef, Props>(
|
|
31
|
+
function DigiaAnchorView({ anchorKey, children, style, ...rest }, ref) {
|
|
32
|
+
// The native View we read the on-screen position from.
|
|
33
|
+
const viewRef = useRef<View>(null);
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
// A ref attached by the consumer means "this anchor is animated, wait
|
|
36
|
+
// for me to call animationCompleted()". No ref means a plain static
|
|
37
|
+
// anchor that should measure as soon as it lays out.
|
|
38
|
+
const isAnimated = ref != null;
|
|
39
|
+
|
|
40
|
+
// The gate that decides whether measure() is allowed to publish.
|
|
41
|
+
// Static anchors start open (true) and behave exactly as before.
|
|
42
|
+
// Animated anchors start closed (false) and open on animationCompleted().
|
|
43
|
+
const canMeasure = useRef(!isAnimated);
|
|
44
|
+
|
|
45
|
+
// Read the View's current position and publish it to the registry.
|
|
46
|
+
// No-op while the gate is closed (animation still in flight).
|
|
47
|
+
const measure = useCallback(() => {
|
|
48
|
+
if (!canMeasure.current) return;
|
|
49
|
+
viewRef.current?.measure((_x, _y, width, height, pageX, pageY) => {
|
|
50
|
+
if (width === 0 && height === 0) return;
|
|
51
|
+
nativeDigiaModule.registerAnchor(anchorKey, Math.round(pageX), Math.round(pageY), Math.round(width), Math.round(height));
|
|
52
|
+
digiaAnchorRegistry.setLayout(anchorKey, { pageX, pageY, width, height });
|
|
53
|
+
});
|
|
54
|
+
}, [anchorKey]);
|
|
55
|
+
|
|
56
|
+
// What the consumer calls from their animation's completion callback.
|
|
57
|
+
// Open the gate, then measure on the frame after the animation's final
|
|
58
|
+
// commit so the position we capture is the resting one.
|
|
59
|
+
const animationCompleted = useCallback(() => {
|
|
60
|
+
canMeasure.current = true;
|
|
61
|
+
requestAnimationFrame(() => requestAnimationFrame(measure));
|
|
62
|
+
}, [measure]);
|
|
63
|
+
|
|
64
|
+
// Expose animationCompleted() on the ref. When no ref is attached this
|
|
65
|
+
// is a no-op, so static anchors carry zero extra behaviour.
|
|
66
|
+
useImperativeHandle(ref, () => ({ animationCompleted }), [animationCompleted]);
|
|
67
|
+
|
|
68
|
+
// Register the anchor (and its measure callback) with the SDK on mount,
|
|
69
|
+
// and tear everything down on unmount.
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
Digia.registerAnchor(anchorKey);
|
|
72
|
+
digiaAnchorRegistry.registerMeasure(anchorKey, measure);
|
|
73
|
+
return () => {
|
|
74
|
+
Digia.unregisterAnchor(anchorKey);
|
|
75
|
+
digiaAnchorRegistry.unregisterMeasure(anchorKey, measure);
|
|
76
|
+
nativeDigiaModule.unregisterAnchor(anchorKey);
|
|
77
|
+
digiaAnchorRegistry.remove(anchorKey);
|
|
78
|
+
};
|
|
79
|
+
}, [anchorKey, measure]);
|
|
54
80
|
|
|
81
|
+
return (
|
|
82
|
+
<View ref={viewRef} onLayout={measure} style={style} {...rest}>
|
|
83
|
+
{children}
|
|
84
|
+
</View>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
);
|
|
@@ -27,7 +27,7 @@ export class DigiaHealthReporter {
|
|
|
27
27
|
|
|
28
28
|
report(eventType: HealthEventType, detail: Record<string, unknown>): void {
|
|
29
29
|
if (!this._projectId) return;
|
|
30
|
-
//
|
|
30
|
+
// Health-event reporting is currently disabled.
|
|
31
31
|
// fetch(`${this._baseUrl}/engage/sdk/recordHealthEvent`, {
|
|
32
32
|
// method: 'POST',
|
|
33
33
|
// headers: {
|
package/src/DigiaProvider.tsx
CHANGED
|
@@ -220,6 +220,8 @@ function TooltipOverlay({
|
|
|
220
220
|
const [floatPos, setFloatPos] = useState<FloatPos | null>(null);
|
|
221
221
|
const [resolvedPlacement, setResolvedPlacement] = useState<string>('bottom');
|
|
222
222
|
const [floatingSize, setFloatingSize] = useState<{ w: number; h: number } | null>(null);
|
|
223
|
+
const [readyStep, setReadyStep] = useState(-1);
|
|
224
|
+
const ready = readyStep === stepIndex;
|
|
223
225
|
const step = config.steps[stepIndex];
|
|
224
226
|
const { width: screenW } = useWindowDimensions();
|
|
225
227
|
const opacityAnim = useRef(new Animated.Value(1)).current;
|
|
@@ -230,9 +232,21 @@ function TooltipOverlay({
|
|
|
230
232
|
const showArrow = step.showArrow !== false;
|
|
231
233
|
const gap = showArrow ? arrowSize + 4 : 8;
|
|
232
234
|
|
|
235
|
+
// Wait for the step's delayInMs before marking it ready. Re-runs on every step entry.
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
const delay = step.delayInMs ?? 0;
|
|
238
|
+
if (delay <= 0) {
|
|
239
|
+
setReadyStep(stepIndex);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const timer = setTimeout(() => setReadyStep(stepIndex), delay);
|
|
243
|
+
return () => clearTimeout(timer);
|
|
244
|
+
}, [stepIndex]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
245
|
+
|
|
233
246
|
useEffect(() => {
|
|
234
247
|
setLayout(null);
|
|
235
248
|
setFloatPos(null);
|
|
249
|
+
if (!ready) return;
|
|
236
250
|
let skipCached = false;
|
|
237
251
|
const unsub = digiaAnchorRegistry.subscribe(step.anchorKey, (l) => {
|
|
238
252
|
if (!skipCached) return;
|
|
@@ -246,7 +260,7 @@ function TooltipOverlay({
|
|
|
246
260
|
skipCached = true;
|
|
247
261
|
digiaAnchorRegistry.remeasure(step.anchorKey);
|
|
248
262
|
return unsub;
|
|
249
|
-
}, [step.anchorKey]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
263
|
+
}, [step.anchorKey, ready]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
250
264
|
|
|
251
265
|
useEffect(() => {
|
|
252
266
|
if (!layout || !floatingSize) return;
|
|
@@ -273,8 +287,9 @@ function TooltipOverlay({
|
|
|
273
287
|
}
|
|
274
288
|
}, [floatPos, opacityAnim]);
|
|
275
289
|
|
|
276
|
-
// Fire viewed/step_viewed when the step renders.
|
|
290
|
+
// Fire viewed/step_viewed when the step renders (after any delay has elapsed).
|
|
277
291
|
useEffect(() => {
|
|
292
|
+
if (!ready) return;
|
|
278
293
|
const isMultiStep = config.steps.length > 1;
|
|
279
294
|
if (stepIndex === 0) {
|
|
280
295
|
request.onExperienceEvent({ type: 'viewed', stepIndex: 0, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'tooltip' });
|
|
@@ -283,7 +298,7 @@ function TooltipOverlay({
|
|
|
283
298
|
request.onExperienceEvent({ type: 'step_viewed', stepIndex, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'tooltip' });
|
|
284
299
|
}
|
|
285
300
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
286
|
-
}, [stepIndex]);
|
|
301
|
+
}, [stepIndex, ready]);
|
|
287
302
|
|
|
288
303
|
// Closes guide without firing analytics — used after CTA actions have already fired clicked events.
|
|
289
304
|
const closeFromCTA = useCallback(() => {
|
|
@@ -596,13 +611,27 @@ function SpotlightOverlay({
|
|
|
596
611
|
}) {
|
|
597
612
|
const [stepIndex, setStepIndex] = useState(0);
|
|
598
613
|
const [layout, setLayout] = useState<AnchorLayout | null>(null);
|
|
614
|
+
const [readyStep, setReadyStep] = useState(-1);
|
|
615
|
+
const ready = readyStep === stepIndex;
|
|
599
616
|
const step = config.steps[stepIndex];
|
|
600
617
|
const { width: screenW, height: screenH } = useWindowDimensions();
|
|
601
618
|
const opacityAnim = useRef(new Animated.Value(1)).current;
|
|
602
619
|
const pendingFadeIn = useRef(false);
|
|
603
620
|
|
|
621
|
+
// Wait for the step's delayInMs before marking it ready. Re-runs on every step entry.
|
|
622
|
+
useEffect(() => {
|
|
623
|
+
const delay = step.delayInMs ?? 0;
|
|
624
|
+
if (delay <= 0) {
|
|
625
|
+
setReadyStep(stepIndex);
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
const timer = setTimeout(() => setReadyStep(stepIndex), delay);
|
|
629
|
+
return () => clearTimeout(timer);
|
|
630
|
+
}, [stepIndex]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
631
|
+
|
|
604
632
|
useEffect(() => {
|
|
605
633
|
setLayout(null);
|
|
634
|
+
if (!ready) return; // hold off measuring/showing until the delay has elapsed
|
|
606
635
|
let skipCached = false;
|
|
607
636
|
const unsub = digiaAnchorRegistry.subscribe(step.anchorKey, (l) => {
|
|
608
637
|
if (!skipCached) return;
|
|
@@ -616,7 +645,7 @@ function SpotlightOverlay({
|
|
|
616
645
|
skipCached = true;
|
|
617
646
|
digiaAnchorRegistry.remeasure(step.anchorKey);
|
|
618
647
|
return unsub;
|
|
619
|
-
}, [step.anchorKey]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
648
|
+
}, [step.anchorKey, ready]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
620
649
|
|
|
621
650
|
useEffect(() => {
|
|
622
651
|
if (layout && pendingFadeIn.current) {
|
|
@@ -625,8 +654,9 @@ function SpotlightOverlay({
|
|
|
625
654
|
}
|
|
626
655
|
}, [layout, opacityAnim]);
|
|
627
656
|
|
|
628
|
-
// Fire viewed/step_viewed when the step renders.
|
|
657
|
+
// Fire viewed/step_viewed when the step renders (after any delay has elapsed).
|
|
629
658
|
useEffect(() => {
|
|
659
|
+
if (!ready) return;
|
|
630
660
|
const isMultiStep = config.steps.length > 1;
|
|
631
661
|
if (stepIndex === 0) {
|
|
632
662
|
request.onExperienceEvent({ type: 'viewed', stepIndex: 0, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'spotlight' });
|
|
@@ -635,7 +665,7 @@ function SpotlightOverlay({
|
|
|
635
665
|
request.onExperienceEvent({ type: 'step_viewed', stepIndex, stepTotal: config.steps.length, anchorKey: step.anchorKey, displayStyle: 'spotlight' });
|
|
636
666
|
}
|
|
637
667
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
638
|
-
}, [stepIndex]);
|
|
668
|
+
}, [stepIndex, ready]);
|
|
639
669
|
|
|
640
670
|
const closeFromCTA = useCallback(() => {
|
|
641
671
|
Animated.timing(opacityAnim, { toValue: 0, duration: 150, useNativeDriver: true }).start(() => {
|
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export { DigiaHostView } from './DigiaHostView';
|
|
|
14
14
|
export { DigiaHost } from './DigiaProvider';
|
|
15
15
|
export { DigiaSlotView } from './DigiaSlotView';
|
|
16
16
|
export { DigiaAnchorView } from './DigiaAnchorView';
|
|
17
|
+
export type { DigiaAnchorViewRef } from './DigiaAnchorView';
|
|
17
18
|
export type { ActionContext, ActionResult, CampaignType, DigiaAction, DigiaConfig, DigiaDelegate, DigiaExperienceEvent, DigiaPlugin, InAppBrowserAdapter, InAppPayload, OnAction } from './types';
|
|
18
19
|
export { defaultInAppBrowser } from './defaultInAppBrowser';
|
|
19
20
|
export { DigiaHealthReporter, HealthEventType, digiaHealthReporter } from './DigiaHealthReporter';
|
package/src/templateTypes.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type Action =
|
|
|
9
9
|
|
|
10
10
|
export type TooltipStep = {
|
|
11
11
|
anchorKey: string
|
|
12
|
+
delayInMs?: number
|
|
12
13
|
title: string
|
|
13
14
|
body: string
|
|
14
15
|
placement: 'top' | 'bottom' | 'left' | 'right' | 'auto'
|
|
@@ -36,6 +37,7 @@ export type TooltipStep = {
|
|
|
36
37
|
|
|
37
38
|
export type SpotlightStep = {
|
|
38
39
|
anchorKey: string
|
|
40
|
+
delayInMs?: number
|
|
39
41
|
title: string
|
|
40
42
|
body: string
|
|
41
43
|
calloutPosition: 'above' | 'below' | 'left' | 'right' | 'auto'
|
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>1780322402778</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>
|
|
Binary file
|
|
Binary file
|
package/android/bin/.project
DELETED
|
@@ -1,34 +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.jdt.core.javabuilder</name>
|
|
10
|
-
<arguments>
|
|
11
|
-
</arguments>
|
|
12
|
-
</buildCommand>
|
|
13
|
-
<buildCommand>
|
|
14
|
-
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
|
15
|
-
<arguments>
|
|
16
|
-
</arguments>
|
|
17
|
-
</buildCommand>
|
|
18
|
-
</buildSpec>
|
|
19
|
-
<natures>
|
|
20
|
-
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
21
|
-
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
|
22
|
-
</natures>
|
|
23
|
-
<filteredResources>
|
|
24
|
-
<filter>
|
|
25
|
-
<id>1780322402778</id>
|
|
26
|
-
<name></name>
|
|
27
|
-
<type>30</type>
|
|
28
|
-
<matcher>
|
|
29
|
-
<id>org.eclipse.core.resources.regexFilterMatcher</id>
|
|
30
|
-
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
|
|
31
|
-
</matcher>
|
|
32
|
-
</filter>
|
|
33
|
-
</filteredResources>
|
|
34
|
-
</projectDescription>
|
package/android/bin/build/generated/source/buildConfig/debug/com/digia/engage/rn/BuildConfig.class
DELETED
|
Binary file
|
|
Binary file
|
package/android/bin/build.gradle
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Android Gradle build file for the @digia/engage-react-native library module.
|
|
3
|
-
*
|
|
4
|
-
* This module is a thin bridge layer that:
|
|
5
|
-
* • Depends on the Digia Engage Android AAR
|
|
6
|
-
* • Depends on the React Native SDK
|
|
7
|
-
* • Exposes a ReactPackage (DigiaPackage) that registers the native module
|
|
8
|
-
* and native view to React Native's bridge
|
|
9
|
-
*
|
|
10
|
-
* The Compose runtime/tooling dependencies are inherited transitively from
|
|
11
|
-
* the Digia Engage AAR via `api` declarations; we only add what is needed for
|
|
12
|
-
* the bridge code itself.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
def isNewArchitectureEnabled() {
|
|
16
|
-
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
plugins {
|
|
20
|
-
id 'com.android.library'
|
|
21
|
-
id 'org.jetbrains.kotlin.android'
|
|
22
|
-
id 'org.jetbrains.kotlin.plugin.compose' version '2.1.20'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (isNewArchitectureEnabled()) {
|
|
26
|
-
apply plugin: 'com.facebook.react'
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (isNewArchitectureEnabled()) {
|
|
30
|
-
react {
|
|
31
|
-
jsRootDir = file("../src/")
|
|
32
|
-
libraryName = "DigiaEngageSpec"
|
|
33
|
-
codegenJavaPackageName = "com.digia.engage.rn"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
android {
|
|
38
|
-
compileSdk 35
|
|
39
|
-
namespace 'com.digia.engage.rn'
|
|
40
|
-
|
|
41
|
-
defaultConfig {
|
|
42
|
-
minSdk 24
|
|
43
|
-
targetSdk 35
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
buildTypes {
|
|
47
|
-
release {
|
|
48
|
-
minifyEnabled false
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
compileOptions {
|
|
53
|
-
sourceCompatibility JavaVersion.VERSION_17
|
|
54
|
-
targetCompatibility JavaVersion.VERSION_17
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
kotlinOptions {
|
|
58
|
-
jvmTarget = '17'
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
buildFeatures {
|
|
62
|
-
compose true
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
sourceSets {
|
|
66
|
-
main {
|
|
67
|
-
java.srcDirs += 'src/main/java'
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
dependencies {
|
|
73
|
-
// Digia Engage Android library
|
|
74
|
-
implementation 'tech.digia:engage:2.1.0-Local'
|
|
75
|
-
|
|
76
|
-
// ── React Native ─────────────────────────────────────────────────────────
|
|
77
|
-
// React Native is provided by the host app; mark as compileOnly so it is
|
|
78
|
-
// NOT bundled into this library.
|
|
79
|
-
compileOnly "com.facebook.react:react-android"
|
|
80
|
-
|
|
81
|
-
// ── Jetpack Compose ───────────────────────────────────────────────────────
|
|
82
|
-
// Compose UI is transitively provided by digia-ui; we only need the
|
|
83
|
-
// platform BOM for version alignment.
|
|
84
|
-
implementation platform('androidx.compose:compose-bom:2023.03.00')
|
|
85
|
-
|
|
86
|
-
// UI tooling annotations (used by AbstractComposeView / preview)
|
|
87
|
-
implementation 'androidx.compose.ui:ui'
|
|
88
|
-
|
|
89
|
-
// Lifecycle: ViewTreeLifecycleOwner / setViewTreeLifecycleOwner
|
|
90
|
-
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
|
|
91
|
-
|
|
92
|
-
// SavedState: setViewTreeSavedStateRegistryOwner
|
|
93
|
-
implementation 'androidx.savedstate:savedstate-ktx:1.2.1'
|
|
94
|
-
|
|
95
|
-
// Activity: ComponentActivity needed for lifecycle owner detection
|
|
96
|
-
implementation 'androidx.activity:activity-compose:1.7.2'
|
|
97
|
-
}
|
|
Binary file
|
package/android/bin/gradlew
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
# Copyright 2015 the original author or authors.
|
|
5
|
-
#
|
|
6
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
-
# you may not use this file except in compliance with the License.
|
|
8
|
-
# You may obtain a copy of the License at
|
|
9
|
-
#
|
|
10
|
-
# https://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
-
#
|
|
12
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
-
# See the License for the specific language governing permissions and
|
|
16
|
-
# limitations under the License.
|
|
17
|
-
#
|
|
18
|
-
|
|
19
|
-
##############################################################################
|
|
20
|
-
##
|
|
21
|
-
## Gradle start up script for UN*X
|
|
22
|
-
##
|
|
23
|
-
##############################################################################
|
|
24
|
-
|
|
25
|
-
# Attempt to set APP_HOME
|
|
26
|
-
# Resolve links: $0 may be a link
|
|
27
|
-
PRG="$0"
|
|
28
|
-
# Need this for relative symlinks.
|
|
29
|
-
while [ -h "$PRG" ] ; do
|
|
30
|
-
ls=`ls -ld "$PRG"`
|
|
31
|
-
link=`expr "$ls" : '.*-> \(.*\)$'`
|
|
32
|
-
if expr "$link" : '/.*' > /dev/null; then
|
|
33
|
-
PRG="$link"
|
|
34
|
-
else
|
|
35
|
-
PRG=`dirname "$PRG"`"/$link"
|
|
36
|
-
fi
|
|
37
|
-
done
|
|
38
|
-
SAVED="`pwd`"
|
|
39
|
-
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
40
|
-
APP_HOME="`pwd -P`"
|
|
41
|
-
cd "$SAVED" >/dev/null
|
|
42
|
-
|
|
43
|
-
APP_NAME="Gradle"
|
|
44
|
-
APP_BASE_NAME=`basename "$0"`
|
|
45
|
-
|
|
46
|
-
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
47
|
-
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
48
|
-
|
|
49
|
-
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
50
|
-
MAX_FD="maximum"
|
|
51
|
-
|
|
52
|
-
warn () {
|
|
53
|
-
echo "$*"
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
die () {
|
|
57
|
-
echo
|
|
58
|
-
echo "$*"
|
|
59
|
-
echo
|
|
60
|
-
exit 1
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
# OS specific support (must be 'true' or 'false').
|
|
64
|
-
cygwin=false
|
|
65
|
-
msys=false
|
|
66
|
-
darwin=false
|
|
67
|
-
nonstop=false
|
|
68
|
-
case "`uname`" in
|
|
69
|
-
CYGWIN* )
|
|
70
|
-
cygwin=true
|
|
71
|
-
;;
|
|
72
|
-
Darwin* )
|
|
73
|
-
darwin=true
|
|
74
|
-
;;
|
|
75
|
-
MINGW* )
|
|
76
|
-
msys=true
|
|
77
|
-
;;
|
|
78
|
-
NONSTOP* )
|
|
79
|
-
nonstop=true
|
|
80
|
-
;;
|
|
81
|
-
esac
|
|
82
|
-
|
|
83
|
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
# Determine the Java command to use to start the JVM.
|
|
87
|
-
if [ -n "$JAVA_HOME" ] ; then
|
|
88
|
-
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
89
|
-
# IBM's JDK on AIX uses strange locations for the executables
|
|
90
|
-
JAVACMD="$JAVA_HOME/jre/sh/java"
|
|
91
|
-
else
|
|
92
|
-
JAVACMD="$JAVA_HOME/bin/java"
|
|
93
|
-
fi
|
|
94
|
-
if [ ! -x "$JAVACMD" ] ; then
|
|
95
|
-
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
96
|
-
|
|
97
|
-
Please set the JAVA_HOME variable in your environment to match the
|
|
98
|
-
location of your Java installation."
|
|
99
|
-
fi
|
|
100
|
-
else
|
|
101
|
-
JAVACMD="java"
|
|
102
|
-
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
103
|
-
|
|
104
|
-
Please set the JAVA_HOME variable in your environment to match the
|
|
105
|
-
location of your Java installation."
|
|
106
|
-
fi
|
|
107
|
-
|
|
108
|
-
# Increase the maximum file descriptors if we can.
|
|
109
|
-
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
|
110
|
-
MAX_FD_LIMIT=`ulimit -H -n`
|
|
111
|
-
if [ $? -eq 0 ] ; then
|
|
112
|
-
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
|
113
|
-
MAX_FD="$MAX_FD_LIMIT"
|
|
114
|
-
fi
|
|
115
|
-
ulimit -n $MAX_FD
|
|
116
|
-
if [ $? -ne 0 ] ; then
|
|
117
|
-
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
|
118
|
-
fi
|
|
119
|
-
else
|
|
120
|
-
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
121
|
-
fi
|
|
122
|
-
fi
|
|
123
|
-
|
|
124
|
-
# For Darwin, add options to specify how the application appears in the dock
|
|
125
|
-
if $darwin; then
|
|
126
|
-
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
130
|
-
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
131
|
-
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
132
|
-
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
133
|
-
|
|
134
|
-
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
135
|
-
|
|
136
|
-
# We build the pattern for arguments to be converted via cygpath
|
|
137
|
-
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
138
|
-
SEP=""
|
|
139
|
-
for dir in $ROOTDIRSRAW ; do
|
|
140
|
-
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
141
|
-
SEP="|"
|
|
142
|
-
done
|
|
143
|
-
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
144
|
-
# Add a user-defined pattern to the cygpath arguments
|
|
145
|
-
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
146
|
-
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
147
|
-
fi
|
|
148
|
-
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
149
|
-
i=0
|
|
150
|
-
for arg in "$@" ; do
|
|
151
|
-
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
152
|
-
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
153
|
-
|
|
154
|
-
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
155
|
-
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
156
|
-
else
|
|
157
|
-
eval `echo args$i`="\"$arg\""
|
|
158
|
-
fi
|
|
159
|
-
i=`expr $i + 1`
|
|
160
|
-
done
|
|
161
|
-
case $i in
|
|
162
|
-
0) set -- ;;
|
|
163
|
-
1) set -- "$args0" ;;
|
|
164
|
-
2) set -- "$args0" "$args1" ;;
|
|
165
|
-
3) set -- "$args0" "$args1" "$args2" ;;
|
|
166
|
-
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
167
|
-
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
168
|
-
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
169
|
-
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
170
|
-
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
171
|
-
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
172
|
-
esac
|
|
173
|
-
fi
|
|
174
|
-
|
|
175
|
-
# Escape application args
|
|
176
|
-
save () {
|
|
177
|
-
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
|
178
|
-
echo " "
|
|
179
|
-
}
|
|
180
|
-
APP_ARGS=`save "$@"`
|
|
181
|
-
|
|
182
|
-
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
|
183
|
-
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
|
184
|
-
|
|
185
|
-
exec "$JAVACMD" "$@"
|