rampkit-expo-dev 0.0.84 → 0.0.87
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.d.ts +1 -1
- package/build/RampkitOverlay.js +135 -14
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ export declare const injectedHardening = "\n(function(){\n try {\n var meta
|
|
|
3
3
|
export declare const injectedNoSelect = "\n(function(){\n try {\n if (window.__rkNoSelectApplied) return true;\n window.__rkNoSelectApplied = true;\n var style = document.getElementById('rk-no-select-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'rk-no-select-style';\n style.innerHTML = \"\n * {\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-touch-callout: none !important;\n }\n ::selection {\n background: transparent !important;\n }\n \";\n document.head.appendChild(style);\n }\n var prevent = function(e){ if(e && e.preventDefault) e.preventDefault(); return false; };\n document.addEventListener('contextmenu', prevent, { passive: false, capture: true });\n document.addEventListener('selectstart', prevent, { passive: false, capture: true });\n } catch (_) {}\n true;\n})();\n";
|
|
4
4
|
export declare const injectedVarsHandler = "\n(function(){\n try {\n if (window.__rkVarsHandlerApplied) return true;\n window.__rkVarsHandlerApplied = true;\n \n // Handler function that updates variables and notifies the page\n window.__rkHandleVarsUpdate = function(vars) {\n if (!vars || typeof vars !== 'object') return;\n // Update the global variables object\n window.__rampkitVariables = vars;\n // Dispatch a custom event that the page's JS can listen to for re-rendering\n try {\n document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));\n } catch(e) {}\n // Also try calling a global handler if the page defined one\n try {\n if (typeof window.onRampkitVarsUpdate === 'function') {\n window.onRampkitVarsUpdate(vars);\n }\n } catch(e) {}\n };\n \n // Listen for message events from React Native\n document.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n \n // Also listen on window for compatibility\n window.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n } catch (_) {}\n true;\n})();\n";
|
|
5
5
|
export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/"/g, '\"').replace(/"/g, '\"').replace(/"/g, '\"')\n .replace(/'/g, \"'\").replace(/'/g, \"'\").replace(/'/g, \"'\")\n .replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n var handled = evalDynamicTap(config);\n if (handled) {\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
|
|
6
|
-
export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // Find interactive element - looks for clickable-looking elements\n function findInteractive(el) {\n var current = el;\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;\n\n // Match elements with tap/click-related data attributes\n // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)\n
|
|
6
|
+
export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // Find interactive element - looks for clickable-looking elements\n function findInteractive(el) {\n var current = el;\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;\n\n // Match elements with tap/click-related data attributes\n // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)\n // These are for screen lifecycle events, not user tap interactions\n var isLifecycleAttr = (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||\n attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||\n attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||\n attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1);\n if (isLifecycleAttr) {\n continue;\n }\n // Match tap/click interaction attributes\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) return current;\n\n // Match elements with role=\"button\"\n if (current.getAttribute('role') === 'button') return current;\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') return current;\n } catch(e) {}\n\n current = current.parentElement;\n }\n return null;\n }\n\n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n\n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n\n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n\n function onTouchStart(e) {\n try {\n var target = findInteractive(e.target);\n if (!target) return;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
|
|
7
7
|
export type ScreenPayload = {
|
|
8
8
|
id: string;
|
|
9
9
|
html: string;
|
package/build/RampkitOverlay.js
CHANGED
|
@@ -406,10 +406,12 @@ exports.injectedButtonAnimations = `
|
|
|
406
406
|
for (var j = 0; j < attrs.length; j++) {
|
|
407
407
|
var attrName = attrs[j].name.toLowerCase();
|
|
408
408
|
// Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)
|
|
409
|
-
|
|
409
|
+
// These are for screen lifecycle events, not user tap interactions
|
|
410
|
+
var isLifecycleAttr = (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||
|
|
410
411
|
attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||
|
|
411
412
|
attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||
|
|
412
|
-
attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1)
|
|
413
|
+
attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1);
|
|
414
|
+
if (isLifecycleAttr) {
|
|
413
415
|
continue;
|
|
414
416
|
}
|
|
415
417
|
// Match tap/click interaction attributes
|
|
@@ -1125,6 +1127,124 @@ function Overlay(props) {
|
|
|
1125
1127
|
detail: { screenIndex: ${screenIndex}, screenId: '${screenId}' }
|
|
1126
1128
|
}));
|
|
1127
1129
|
} catch(e) {}
|
|
1130
|
+
|
|
1131
|
+
// Process on-open actions (SDK-side handling)
|
|
1132
|
+
// This ensures actions run when screen becomes VISIBLE, not when loaded
|
|
1133
|
+
try {
|
|
1134
|
+
if (window.__rampkitOnOpenActionsProcessed) return; // Only run once per screen visibility
|
|
1135
|
+
window.__rampkitOnOpenActionsProcessed = true;
|
|
1136
|
+
|
|
1137
|
+
var elements = document.querySelectorAll('[data-on-open-actions]');
|
|
1138
|
+
elements.forEach(function(el) {
|
|
1139
|
+
try {
|
|
1140
|
+
var actionsStr = el.getAttribute('data-on-open-actions');
|
|
1141
|
+
if (!actionsStr) return;
|
|
1142
|
+
|
|
1143
|
+
// Decode HTML entities
|
|
1144
|
+
actionsStr = actionsStr.replace(/"/g, '"').replace(/"/g, '"')
|
|
1145
|
+
.replace(/'/g, "'").replace(/'/g, "'")
|
|
1146
|
+
.replace(/</g, '<').replace(/>/g, '>')
|
|
1147
|
+
.replace(/&/g, '&');
|
|
1148
|
+
|
|
1149
|
+
var actions = JSON.parse(actionsStr);
|
|
1150
|
+
if (!Array.isArray(actions)) return;
|
|
1151
|
+
|
|
1152
|
+
console.log('[RampKit] Processing on-open actions:', actions.length);
|
|
1153
|
+
|
|
1154
|
+
// Execute actions in sequence with delays
|
|
1155
|
+
var executeActions = function(actionList, index) {
|
|
1156
|
+
if (index >= actionList.length) return;
|
|
1157
|
+
if (!window.__rampkitScreenVisible) return; // Stop if screen became inactive
|
|
1158
|
+
|
|
1159
|
+
var action = actionList[index];
|
|
1160
|
+
var actionType = action.type || action.actionType;
|
|
1161
|
+
|
|
1162
|
+
console.log('[RampKit] Executing on-open action:', actionType);
|
|
1163
|
+
|
|
1164
|
+
if (actionType === 'wait') {
|
|
1165
|
+
var waitMs = action.waitMs || action.duration || 1000;
|
|
1166
|
+
setTimeout(function() {
|
|
1167
|
+
executeActions(actionList, index + 1);
|
|
1168
|
+
}, waitMs);
|
|
1169
|
+
return;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (actionType === 'navigate' || actionType === 'continue') {
|
|
1173
|
+
var target = action.targetScreenId || action.target || '__continue__';
|
|
1174
|
+
var animation = action.animation || 'fade';
|
|
1175
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1176
|
+
type: 'rampkit:navigate',
|
|
1177
|
+
targetScreenId: target,
|
|
1178
|
+
animation: animation,
|
|
1179
|
+
fromOnOpen: true
|
|
1180
|
+
}));
|
|
1181
|
+
// Don't continue to next action after navigate
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
if (actionType === 'goBack') {
|
|
1186
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1187
|
+
type: 'rampkit:goBack',
|
|
1188
|
+
animation: action.animation || 'fade',
|
|
1189
|
+
fromOnOpen: true
|
|
1190
|
+
}));
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
if (actionType === 'requestReview' || actionType === 'request-review') {
|
|
1195
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1196
|
+
type: 'rampkit:request-review',
|
|
1197
|
+
fromOnOpen: true
|
|
1198
|
+
}));
|
|
1199
|
+
executeActions(actionList, index + 1);
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
if (actionType === 'requestNotificationPermission' || actionType === 'request-notification-permission') {
|
|
1204
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1205
|
+
type: 'rampkit:request-notification-permission',
|
|
1206
|
+
ios: action.ios,
|
|
1207
|
+
android: action.android,
|
|
1208
|
+
behavior: action.behavior,
|
|
1209
|
+
fromOnOpen: true
|
|
1210
|
+
}));
|
|
1211
|
+
executeActions(actionList, index + 1);
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
if (actionType === 'haptic') {
|
|
1216
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1217
|
+
type: 'rampkit:haptic',
|
|
1218
|
+
hapticType: action.hapticType || 'impact',
|
|
1219
|
+
impactStyle: action.impactStyle || 'Medium',
|
|
1220
|
+
fromOnOpen: true
|
|
1221
|
+
}));
|
|
1222
|
+
executeActions(actionList, index + 1);
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
if (actionType === 'close') {
|
|
1227
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
1228
|
+
type: 'rampkit:close',
|
|
1229
|
+
fromOnOpen: true
|
|
1230
|
+
}));
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// Unknown action, continue to next
|
|
1235
|
+
executeActions(actionList, index + 1);
|
|
1236
|
+
};
|
|
1237
|
+
|
|
1238
|
+
// Start executing actions
|
|
1239
|
+
executeActions(actions, 0);
|
|
1240
|
+
|
|
1241
|
+
} catch(e) {
|
|
1242
|
+
console.log('[RampKit] Error processing on-open actions:', e);
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
} catch(e) {
|
|
1246
|
+
console.log('[RampKit] Error finding on-open actions:', e);
|
|
1247
|
+
}
|
|
1128
1248
|
})();`;
|
|
1129
1249
|
// @ts-ignore: injectJavaScript exists on WebView instance
|
|
1130
1250
|
wv.injectJavaScript(activateScript);
|
|
@@ -1141,6 +1261,7 @@ function Overlay(props) {
|
|
|
1141
1261
|
}
|
|
1142
1262
|
const deactivateScript = `(function() {
|
|
1143
1263
|
window.__rampkitScreenVisible = false;
|
|
1264
|
+
window.__rampkitOnOpenActionsProcessed = false; // Reset so on-open can run again if user returns
|
|
1144
1265
|
console.log('🔒 Screen ${screenIndex} DEACTIVATED');
|
|
1145
1266
|
|
|
1146
1267
|
// Pause all Lottie animations
|
|
@@ -1986,20 +2107,20 @@ function Overlay(props) {
|
|
|
1986
2107
|
}
|
|
1987
2108
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
|
|
1988
2109
|
(data === null || data === void 0 ? void 0 : data.type) === "continue") {
|
|
1989
|
-
// Only process
|
|
2110
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
1990
2111
|
if (!isScreenActive(i)) {
|
|
1991
2112
|
if (__DEV__)
|
|
1992
|
-
console.log(`[
|
|
2113
|
+
console.log(`[Rampkit] Ignoring continue from inactive screen ${i} (SDK handles on-open)`);
|
|
1993
2114
|
return;
|
|
1994
2115
|
}
|
|
1995
2116
|
handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
1996
2117
|
return;
|
|
1997
2118
|
}
|
|
1998
2119
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:navigate") {
|
|
1999
|
-
// Only process
|
|
2120
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
2000
2121
|
if (!isScreenActive(i)) {
|
|
2001
2122
|
if (__DEV__)
|
|
2002
|
-
console.log(`[
|
|
2123
|
+
console.log(`[Rampkit] Ignoring navigate from inactive screen ${i} (SDK handles on-open)`);
|
|
2003
2124
|
return;
|
|
2004
2125
|
}
|
|
2005
2126
|
const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
|
|
@@ -2021,10 +2142,10 @@ function Overlay(props) {
|
|
|
2021
2142
|
return;
|
|
2022
2143
|
}
|
|
2023
2144
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:goBack") {
|
|
2024
|
-
// Only process
|
|
2145
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
2025
2146
|
if (!isScreenActive(i)) {
|
|
2026
2147
|
if (__DEV__)
|
|
2027
|
-
console.log(`[
|
|
2148
|
+
console.log(`[Rampkit] Ignoring goBack from inactive screen ${i} (SDK handles on-open)`);
|
|
2028
2149
|
return;
|
|
2029
2150
|
}
|
|
2030
2151
|
handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
@@ -2049,10 +2170,10 @@ function Overlay(props) {
|
|
|
2049
2170
|
if (raw === "rampkit:tap" ||
|
|
2050
2171
|
raw === "next" ||
|
|
2051
2172
|
raw === "continue") {
|
|
2052
|
-
// Only process from
|
|
2173
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
2053
2174
|
if (!isScreenActive(i)) {
|
|
2054
2175
|
if (__DEV__)
|
|
2055
|
-
console.log(`[
|
|
2176
|
+
console.log(`[Rampkit] Ignoring ${raw} from inactive screen ${i} (SDK handles on-open)`);
|
|
2056
2177
|
return;
|
|
2057
2178
|
}
|
|
2058
2179
|
handleAdvance(i);
|
|
@@ -2109,20 +2230,20 @@ function Overlay(props) {
|
|
|
2109
2230
|
return;
|
|
2110
2231
|
}
|
|
2111
2232
|
if (raw === "rampkit:goBack") {
|
|
2112
|
-
// Only process from
|
|
2233
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
2113
2234
|
if (!isScreenActive(i)) {
|
|
2114
2235
|
if (__DEV__)
|
|
2115
|
-
console.log(`[
|
|
2236
|
+
console.log(`[Rampkit] Ignoring goBack (raw) from inactive screen ${i} (SDK handles on-open)`);
|
|
2116
2237
|
return;
|
|
2117
2238
|
}
|
|
2118
2239
|
handleGoBack(i);
|
|
2119
2240
|
return;
|
|
2120
2241
|
}
|
|
2121
2242
|
if (raw.startsWith("rampkit:navigate:")) {
|
|
2122
|
-
// Only process from
|
|
2243
|
+
// Only process from active screen (on-open actions are handled by SDK in activateScreen)
|
|
2123
2244
|
if (!isScreenActive(i)) {
|
|
2124
2245
|
if (__DEV__)
|
|
2125
|
-
console.log(`[
|
|
2246
|
+
console.log(`[Rampkit] Ignoring navigate (raw) from inactive screen ${i} (SDK handles on-open)`);
|
|
2126
2247
|
return;
|
|
2127
2248
|
}
|
|
2128
2249
|
const target = raw.slice("rampkit:navigate:".length);
|
package/package.json
CHANGED