rampkit-expo-dev 0.0.77 → 0.0.78
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/build/RampkitOverlay.js +156 -15
- package/package.json +1 -1
package/build/RampkitOverlay.js
CHANGED
|
@@ -1041,6 +1041,84 @@ function Overlay(props) {
|
|
|
1041
1041
|
const screenActivationTimeRef = (0, react_1.useRef)({ 0: Date.now() });
|
|
1042
1042
|
// Settling period - ignore variable updates from a screen for this long after activation
|
|
1043
1043
|
const SCREEN_SETTLING_MS = 300;
|
|
1044
|
+
// Queue of pending actions per screen - actions are queued when screen is inactive
|
|
1045
|
+
// and executed when the screen becomes active (matches iOS SDK behavior)
|
|
1046
|
+
const pendingActionsRef = (0, react_1.useRef)({});
|
|
1047
|
+
// Check if a screen is currently active
|
|
1048
|
+
const isScreenActive = (screenIndex) => {
|
|
1049
|
+
return screenIndex === activeScreenIndexRef.current;
|
|
1050
|
+
};
|
|
1051
|
+
// Queue an action to be executed when screen becomes active
|
|
1052
|
+
const queueAction = (screenIndex, action) => {
|
|
1053
|
+
if (__DEV__) {
|
|
1054
|
+
console.log(`[Rampkit] 📥 Queuing action for screen ${screenIndex}`);
|
|
1055
|
+
}
|
|
1056
|
+
if (!pendingActionsRef.current[screenIndex]) {
|
|
1057
|
+
pendingActionsRef.current[screenIndex] = [];
|
|
1058
|
+
}
|
|
1059
|
+
pendingActionsRef.current[screenIndex].push(action);
|
|
1060
|
+
};
|
|
1061
|
+
// Process any pending actions for a screen
|
|
1062
|
+
const processPendingActions = (screenIndex) => {
|
|
1063
|
+
const actions = pendingActionsRef.current[screenIndex];
|
|
1064
|
+
if (!actions || actions.length === 0)
|
|
1065
|
+
return;
|
|
1066
|
+
if (__DEV__) {
|
|
1067
|
+
console.log(`[Rampkit] ⚡ Processing ${actions.length} pending action(s) for screen ${screenIndex}`);
|
|
1068
|
+
}
|
|
1069
|
+
for (const action of actions) {
|
|
1070
|
+
try {
|
|
1071
|
+
action();
|
|
1072
|
+
}
|
|
1073
|
+
catch (e) {
|
|
1074
|
+
console.warn('[Rampkit] Error executing pending action:', e);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
// Clear the queue
|
|
1078
|
+
pendingActionsRef.current[screenIndex] = [];
|
|
1079
|
+
};
|
|
1080
|
+
// Activate a screen (set visibility flag and dispatch event)
|
|
1081
|
+
const activateScreen = (screenIndex) => {
|
|
1082
|
+
var _a;
|
|
1083
|
+
const wv = webviewsRef.current[screenIndex];
|
|
1084
|
+
if (!wv)
|
|
1085
|
+
return;
|
|
1086
|
+
if (__DEV__) {
|
|
1087
|
+
console.log(`[Rampkit] 🔓 Activating screen ${screenIndex}`);
|
|
1088
|
+
}
|
|
1089
|
+
const screenId = ((_a = props.screens[screenIndex]) === null || _a === void 0 ? void 0 : _a.id) || '';
|
|
1090
|
+
const activateScript = `(function() {
|
|
1091
|
+
window.__rampkitScreenVisible = true;
|
|
1092
|
+
window.__rampkitScreenIndex = ${screenIndex};
|
|
1093
|
+
console.log('🔓 Screen ${screenIndex} ACTIVATED');
|
|
1094
|
+
|
|
1095
|
+
// Dispatch custom event that HTML can listen to
|
|
1096
|
+
try {
|
|
1097
|
+
document.dispatchEvent(new CustomEvent('rampkit:screen-visible', {
|
|
1098
|
+
detail: { screenIndex: ${screenIndex}, screenId: '${screenId}' }
|
|
1099
|
+
}));
|
|
1100
|
+
} catch(e) {}
|
|
1101
|
+
})();`;
|
|
1102
|
+
// @ts-ignore: injectJavaScript exists on WebView instance
|
|
1103
|
+
wv.injectJavaScript(activateScript);
|
|
1104
|
+
// Process any pending actions for this screen
|
|
1105
|
+
processPendingActions(screenIndex);
|
|
1106
|
+
};
|
|
1107
|
+
// Deactivate a screen (clear visibility flag)
|
|
1108
|
+
const deactivateScreen = (screenIndex) => {
|
|
1109
|
+
const wv = webviewsRef.current[screenIndex];
|
|
1110
|
+
if (!wv)
|
|
1111
|
+
return;
|
|
1112
|
+
if (__DEV__) {
|
|
1113
|
+
console.log(`[Rampkit] 🔒 Deactivating screen ${screenIndex}`);
|
|
1114
|
+
}
|
|
1115
|
+
const deactivateScript = `(function() {
|
|
1116
|
+
window.__rampkitScreenVisible = false;
|
|
1117
|
+
console.log('🔒 Screen ${screenIndex} DEACTIVATED');
|
|
1118
|
+
})();`;
|
|
1119
|
+
// @ts-ignore: injectJavaScript exists on WebView instance
|
|
1120
|
+
wv.injectJavaScript(deactivateScript);
|
|
1121
|
+
};
|
|
1044
1122
|
// ============================================================================
|
|
1045
1123
|
// Navigation Resolution Helpers (matches iOS SDK behavior)
|
|
1046
1124
|
// ============================================================================
|
|
@@ -1208,8 +1286,14 @@ function Overlay(props) {
|
|
|
1208
1286
|
(_a = props.onRegisterClose) === null || _a === void 0 ? void 0 : _a.call(props, null);
|
|
1209
1287
|
};
|
|
1210
1288
|
}, [handleRequestClose, props.onRegisterClose]);
|
|
1211
|
-
// Helper to complete a screen transition - updates state and sends data
|
|
1212
|
-
const completeTransition = (nextIndex) => {
|
|
1289
|
+
// Helper to complete a screen transition - updates state, activates/deactivates screens, and sends data
|
|
1290
|
+
const completeTransition = (nextIndex, prevIndex) => {
|
|
1291
|
+
// Deactivate previous screen and activate new screen (matches iOS SDK behavior)
|
|
1292
|
+
// This ensures actions like review/notification requests only fire on the active screen
|
|
1293
|
+
if (prevIndex !== nextIndex) {
|
|
1294
|
+
deactivateScreen(prevIndex);
|
|
1295
|
+
activateScreen(nextIndex);
|
|
1296
|
+
}
|
|
1213
1297
|
setIndex(nextIndex);
|
|
1214
1298
|
sendVarsToWebView(nextIndex);
|
|
1215
1299
|
sendOnboardingStateToWebView(nextIndex);
|
|
@@ -1264,7 +1348,7 @@ function Overlay(props) {
|
|
|
1264
1348
|
// Hide old screen and reset its position
|
|
1265
1349
|
currentScreenAnim.opacity.setValue(0);
|
|
1266
1350
|
currentScreenAnim.translateX.setValue(0);
|
|
1267
|
-
completeTransition(nextIndex);
|
|
1351
|
+
completeTransition(nextIndex, index);
|
|
1268
1352
|
setIsTransitioning(false);
|
|
1269
1353
|
});
|
|
1270
1354
|
return;
|
|
@@ -1307,7 +1391,7 @@ function Overlay(props) {
|
|
|
1307
1391
|
]).start(() => {
|
|
1308
1392
|
// Reset old screen position
|
|
1309
1393
|
currentScreenAnim.translateX.setValue(0);
|
|
1310
|
-
completeTransition(nextIndex);
|
|
1394
|
+
completeTransition(nextIndex, index);
|
|
1311
1395
|
setIsTransitioning(false);
|
|
1312
1396
|
});
|
|
1313
1397
|
return;
|
|
@@ -1324,7 +1408,7 @@ function Overlay(props) {
|
|
|
1324
1408
|
currentScreenAnim.opacity.setValue(0);
|
|
1325
1409
|
nextScreenAnim.opacity.setValue(1);
|
|
1326
1410
|
requestAnimationFrame(() => {
|
|
1327
|
-
completeTransition(nextIndex);
|
|
1411
|
+
completeTransition(nextIndex, index);
|
|
1328
1412
|
// Fade curtain out to reveal new screen
|
|
1329
1413
|
react_native_1.Animated.timing(fadeOpacity, {
|
|
1330
1414
|
toValue: 0,
|
|
@@ -1661,6 +1745,25 @@ function Overlay(props) {
|
|
|
1661
1745
|
// By sending state to all screens upfront, the DOM is already in its final state
|
|
1662
1746
|
// before any navigation occurs.
|
|
1663
1747
|
sendOnboardingStateToWebView(i);
|
|
1748
|
+
// Set initial visibility flag (matches iOS SDK behavior).
|
|
1749
|
+
// Only screen 0 starts as active - all others start inactive.
|
|
1750
|
+
// This prevents actions like review requests from firing on all screens at startup.
|
|
1751
|
+
if (i === 0) {
|
|
1752
|
+
// First screen is immediately active
|
|
1753
|
+
activateScreen(i);
|
|
1754
|
+
}
|
|
1755
|
+
else {
|
|
1756
|
+
// Other screens start inactive - inject the flag but don't dispatch event
|
|
1757
|
+
const wv = webviewsRef.current[i];
|
|
1758
|
+
if (wv) {
|
|
1759
|
+
// @ts-ignore: injectJavaScript exists on WebView instance
|
|
1760
|
+
wv.injectJavaScript(`(function() {
|
|
1761
|
+
window.__rampkitScreenVisible = false;
|
|
1762
|
+
window.__rampkitScreenIndex = ${i};
|
|
1763
|
+
console.log('🔒 Screen ${i} loaded but INACTIVE');
|
|
1764
|
+
})();`);
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1664
1767
|
}, onMessage: (ev) => {
|
|
1665
1768
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1666
1769
|
const raw = ev.nativeEvent.data;
|
|
@@ -1746,7 +1849,7 @@ function Overlay(props) {
|
|
|
1746
1849
|
// 3) A page requested an in-app review prompt
|
|
1747
1850
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-review" ||
|
|
1748
1851
|
(data === null || data === void 0 ? void 0 : data.type) === "rampkit:review") {
|
|
1749
|
-
|
|
1852
|
+
const executeReview = async () => {
|
|
1750
1853
|
try {
|
|
1751
1854
|
const available = await RampKitNative_1.StoreReview.isAvailableAsync();
|
|
1752
1855
|
if (available) {
|
|
@@ -1754,16 +1857,36 @@ function Overlay(props) {
|
|
|
1754
1857
|
}
|
|
1755
1858
|
}
|
|
1756
1859
|
catch (_) { }
|
|
1757
|
-
}
|
|
1860
|
+
};
|
|
1861
|
+
// Only execute if screen is active, otherwise queue for later
|
|
1862
|
+
if (isScreenActive(i)) {
|
|
1863
|
+
executeReview();
|
|
1864
|
+
}
|
|
1865
|
+
else {
|
|
1866
|
+
if (__DEV__)
|
|
1867
|
+
console.log(`[Rampkit] Queuing review request from inactive screen ${i}`);
|
|
1868
|
+
queueAction(i, executeReview);
|
|
1869
|
+
}
|
|
1758
1870
|
return;
|
|
1759
1871
|
}
|
|
1760
1872
|
// 4) A page requested notification permission
|
|
1761
1873
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:request-notification-permission") {
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1874
|
+
const executeNotification = () => {
|
|
1875
|
+
handleNotificationPermissionRequest({
|
|
1876
|
+
ios: data === null || data === void 0 ? void 0 : data.ios,
|
|
1877
|
+
android: data === null || data === void 0 ? void 0 : data.android,
|
|
1878
|
+
behavior: data === null || data === void 0 ? void 0 : data.behavior,
|
|
1879
|
+
});
|
|
1880
|
+
};
|
|
1881
|
+
// Only execute if screen is active, otherwise queue for later
|
|
1882
|
+
if (isScreenActive(i)) {
|
|
1883
|
+
executeNotification();
|
|
1884
|
+
}
|
|
1885
|
+
else {
|
|
1886
|
+
if (__DEV__)
|
|
1887
|
+
console.log(`[Rampkit] Queuing notification request from inactive screen ${i}`);
|
|
1888
|
+
queueAction(i, executeNotification);
|
|
1889
|
+
}
|
|
1767
1890
|
return;
|
|
1768
1891
|
}
|
|
1769
1892
|
// 5) Onboarding finished event from page
|
|
@@ -1850,7 +1973,7 @@ function Overlay(props) {
|
|
|
1850
1973
|
return;
|
|
1851
1974
|
}
|
|
1852
1975
|
if (raw === "rampkit:request-review" || raw === "rampkit:review") {
|
|
1853
|
-
|
|
1976
|
+
const executeReview = async () => {
|
|
1854
1977
|
try {
|
|
1855
1978
|
const available = await RampKitNative_1.StoreReview.isAvailableAsync();
|
|
1856
1979
|
if (available) {
|
|
@@ -1858,11 +1981,29 @@ function Overlay(props) {
|
|
|
1858
1981
|
}
|
|
1859
1982
|
}
|
|
1860
1983
|
catch (_) { }
|
|
1861
|
-
}
|
|
1984
|
+
};
|
|
1985
|
+
// Only execute if screen is active, otherwise queue for later
|
|
1986
|
+
if (isScreenActive(i)) {
|
|
1987
|
+
executeReview();
|
|
1988
|
+
}
|
|
1989
|
+
else {
|
|
1990
|
+
if (__DEV__)
|
|
1991
|
+
console.log(`[Rampkit] Queuing review request (raw) from inactive screen ${i}`);
|
|
1992
|
+
queueAction(i, executeReview);
|
|
1993
|
+
}
|
|
1862
1994
|
return;
|
|
1863
1995
|
}
|
|
1864
1996
|
if (raw === "rampkit:request-notification-permission") {
|
|
1865
|
-
handleNotificationPermissionRequest(undefined);
|
|
1997
|
+
const executeNotification = () => handleNotificationPermissionRequest(undefined);
|
|
1998
|
+
// Only execute if screen is active, otherwise queue for later
|
|
1999
|
+
if (isScreenActive(i)) {
|
|
2000
|
+
executeNotification();
|
|
2001
|
+
}
|
|
2002
|
+
else {
|
|
2003
|
+
if (__DEV__)
|
|
2004
|
+
console.log(`[Rampkit] Queuing notification request (raw) from inactive screen ${i}`);
|
|
2005
|
+
queueAction(i, executeNotification);
|
|
2006
|
+
}
|
|
1866
2007
|
return;
|
|
1867
2008
|
}
|
|
1868
2009
|
if (raw === "rampkit:onboarding-finished") {
|
package/package.json
CHANGED