rampkit-expo-dev 0.0.83 → 0.0.85
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 +2 -2
- package/build/RampkitOverlay.js +97 -306
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@ import { RampKitContext, NavigationData } from "./types";
|
|
|
2
2
|
export declare const injectedHardening = "\n(function(){\n try {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) { meta = document.createElement('meta'); meta.name = 'viewport'; document.head.appendChild(meta); }\n meta.setAttribute('content','width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover');\n var style = document.createElement('style');\n style.textContent='html,body{overflow-x:hidden!important;} html,body,*{-webkit-user-select:none!important;user-select:none!important;-webkit-touch-callout:none!important;-ms-user-select:none!important;touch-action: pan-y;} *{-webkit-tap-highlight-color: rgba(0,0,0,0)!important;} ::selection{background: transparent!important;} ::-moz-selection{background: transparent!important;} a,img{-webkit-user-drag:none!important;user-drag:none!important;-webkit-touch-callout:none!important} input,textarea{caret-color:transparent!important;-webkit-user-select:none!important;user-select:none!important}';\n document.head.appendChild(style);\n var prevent=function(e){e.preventDefault&&e.preventDefault();};\n document.addEventListener('gesturestart',prevent,{passive:false});\n document.addEventListener('gesturechange',prevent,{passive:false});\n document.addEventListener('gestureend',prevent,{passive:false});\n document.addEventListener('dblclick',prevent,{passive:false});\n document.addEventListener('wheel',function(e){ if(e.ctrlKey) e.preventDefault(); },{passive:false});\n document.addEventListener('touchmove',function(e){ if(e.scale && e.scale !== 1) e.preventDefault(); },{passive:false});\n document.addEventListener('selectstart',prevent,{passive:false,capture:true});\n document.addEventListener('contextmenu',prevent,{passive:false,capture:true});\n document.addEventListener('copy',prevent,{passive:false,capture:true});\n document.addEventListener('cut',prevent,{passive:false,capture:true});\n document.addEventListener('paste',prevent,{passive:false,capture:true});\n document.addEventListener('dragstart',prevent,{passive:false,capture:true});\n // Belt-and-suspenders: aggressively clear any attempted selection\n var clearSel=function(){\n try{var sel=window.getSelection&&window.getSelection(); if(sel&&sel.removeAllRanges) sel.removeAllRanges();}catch(_){} }\n document.addEventListener('selectionchange',clearSel,{passive:true,capture:true});\n document.onselectstart=function(){ clearSel(); return false; };\n try{ document.documentElement.style.webkitUserSelect='none'; document.documentElement.style.userSelect='none'; }catch(_){ }\n try{ document.body.style.webkitUserSelect='none'; document.body.style.userSelect='none'; }catch(_){ }\n var __selTimer = setInterval(clearSel, 160);\n window.addEventListener('pagehide',function(){ try{ clearInterval(__selTimer); }catch(_){} });\n // Continuously enforce no-select on all elements and new nodes\n var enforceNoSelect = function(el){\n try{\n el.style && (el.style.webkitUserSelect='none', el.style.userSelect='none', el.style.webkitTouchCallout='none');\n el.setAttribute && (el.setAttribute('unselectable','on'), el.setAttribute('contenteditable','false'));\n }catch(_){}\n }\n try{\n var all=document.getElementsByTagName('*');\n for(var i=0;i<all.length;i++){ enforceNoSelect(all[i]); }\n var obs = new MutationObserver(function(muts){\n for(var j=0;j<muts.length;j++){\n var m=muts[j];\n if(m.type==='childList'){\n m.addedNodes && m.addedNodes.forEach && m.addedNodes.forEach(function(n){ if(n && n.nodeType===1){ enforceNoSelect(n); var q=n.getElementsByTagName? n.getElementsByTagName('*'): []; for(var k=0;k<q.length;k++){ enforceNoSelect(q[k]); }}});\n } else if(m.type==='attributes'){\n enforceNoSelect(m.target);\n }\n }\n });\n obs.observe(document.documentElement,{ childList:true, subtree:true, attributes:true, attributeFilter:['contenteditable','style'] });\n }catch(_){ }\n } catch(_) {}\n})(); true;\n";
|
|
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
|
-
export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========\n var isBuggyScreen = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId === 'phone-21' || screenIndex === 18;\n };\n\n var debugBuggyScreen = function(source, msg, data) {\n if (isBuggyScreen()) {\n var logData = { source: source, msg: msg, data: data };\n console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));\n // Send to React Native via postMessage for visibility in RN console\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'rampkit:debug-buggy-screen',\n source: source,\n message: msg,\n data: data\n }));\n }\n } catch(e) {}\n }\n };\n // ========== END DEBUG ==========\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 var searchTrail = []; // DEBUG: Track search path\n\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n // DEBUG: Build search trail for Screen 19\n var trailInfo = {\n depth: depth,\n tag: current.tagName,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'\n };\n searchTrail.push(trailInfo);\n\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 var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugBuggyScreen('DynamicTap', 'FOUND data-tap-dynamic', {\n attrName: attrNames[i],\n depth: depth,\n element: trailInfo,\n size: rect.width + 'x' + rect.height,\n configPreview: attr.substring(0, 100) + '...',\n trail: searchTrail\n });\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugBuggyScreen('DynamicTap', 'FOUND dataset.tapDynamic', {\n depth: depth,\n element: trailInfo,\n size: rect2.width + 'x' + rect2.height,\n trail: searchTrail\n });\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n debugBuggyScreen('DynamicTap', 'NO data-tap-dynamic found', { trail: searchTrail });\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 // ========== DEBUG: phone-21 click logging ==========\n if (isBuggyScreen()) {\n var clickX = event.clientX;\n var clickY = event.clientY;\n var originalTarget = event.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n debugBuggyScreen('Click', 'Click at (' + clickX + ',' + clickY + ')', {\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n });\n }\n // ========== END DEBUG ==========\n\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n // ========== DEBUG: phone-21 - log when dynamic tap is found ==========\n if (isBuggyScreen()) {\n var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);\n debugBuggyScreen('Click', 'DYNAMIC TAP WILL BE HANDLED', {\n element: {\n tag: result.element.tagName,\n id: result.element.id || '(none)',\n class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',\n size: rect.width + 'x' + rect.height\n },\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'\n });\n }\n // ========== END DEBUG ==========\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n\n // ========== DEBUG: phone-21 - log parsed config ==========\n if (isBuggyScreen()) {\n debugBuggyScreen('Click', 'Parsed config', {\n hasValues: !!(config && config.values),\n valuesCount: config && config.values ? config.values.length : 0,\n firstCondition: config && config.values && config.values[0] ? {\n conditionType: config.values[0].conditionType,\n rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,\n actionsCount: config.values[0].actions ? config.values[0].actions.length : 0\n } : null\n });\n }\n // ========== END DEBUG ==========\n\n var handled = evalDynamicTap(config);\n if (handled) {\n debugBuggyScreen('Click', 'HANDLED by dynamic tap - event stopped', { handled: true });\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n if (isBuggyScreen()) {\n debugBuggyScreen('Click', 'Dynamic tap parse error', { error: e.message });\n }\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 // ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========\n var isBuggyScreenAnim = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId === 'phone-21' || screenIndex === 18;\n };\n\n var debugBuggyScreenAnim = function(source, msg, data) {\n if (isBuggyScreenAnim()) {\n console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));\n // Send to React Native via postMessage for visibility\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'rampkit:debug-buggy-screen',\n source: source,\n message: msg,\n data: data\n }));\n }\n } catch(e) {}\n }\n };\n // ========== END DEBUG ==========\n\n // Find interactive element - very permissive, looks for any clickable-looking element\n function findInteractive(el) {\n var current = el;\n var debugTrail = []; // DEBUG: Track search path for Screen 19\n\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 // DEBUG: Build trail for Screen 19\n var debugInfo = {\n depth: i,\n tag: tag,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',\n size: rect.width + 'x' + rect.height\n };\n debugTrail.push(debugInfo);\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with any data attribute containing action/navigate/tap/click\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 if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: onclick', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with role=\"button\" or tabindex\n if (current.getAttribute('role') === 'button') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: role=button', { element: debugInfo, trail: debugTrail });\n return current;\n }\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)) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });\n return current;\n }\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 debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });\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') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });\n return current;\n }\n } catch(e) {}\n\n current = current.parentElement;\n }\n debugBuggyScreenAnim('ButtonAnim', 'NO MATCH found', { originalTag: el.tagName, trail: debugTrail });\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 // ========== DEBUG: phone-21 touch logging ==========\n if (isBuggyScreenAnim()) {\n var touchX = e.touches ? e.touches[0].clientX : e.clientX;\n var touchY = e.touches ? e.touches[0].clientY : e.clientY;\n var originalTarget = e.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n debugBuggyScreenAnim('TouchStart', 'Touch at (' + touchX + ',' + touchY + ')', {\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n });\n }\n // ========== END DEBUG ==========\n\n var target = findInteractive(e.target);\n if (!target) return;\n\n // ========== DEBUG: phone-21 - log what element was found interactive ==========\n if (isBuggyScreenAnim() && target) {\n var targetRect = target.getBoundingClientRect();\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);\n debugBuggyScreenAnim('TouchStart', 'INTERACTIVE ELEMENT FOUND', {\n tag: target.tagName,\n id: target.id || '(none)',\n class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',\n size: targetRect.width + 'x' + targetRect.height,\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'\n });\n }\n // ========== END DEBUG ==========\n\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";
|
|
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 // 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
|
@@ -182,32 +182,6 @@ exports.injectedDynamicTapHandler = `
|
|
|
182
182
|
if (window.__rampkitClickInterceptorInstalled) return;
|
|
183
183
|
window.__rampkitClickInterceptorInstalled = true;
|
|
184
184
|
|
|
185
|
-
// ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========
|
|
186
|
-
var isBuggyScreen = function() {
|
|
187
|
-
var screenId = window.__rampkitScreenId || '';
|
|
188
|
-
var screenIndex = window.__rampkitScreenIndex;
|
|
189
|
-
return screenId === 'phone-21' || screenIndex === 18;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
var debugBuggyScreen = function(source, msg, data) {
|
|
193
|
-
if (isBuggyScreen()) {
|
|
194
|
-
var logData = { source: source, msg: msg, data: data };
|
|
195
|
-
console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));
|
|
196
|
-
// Send to React Native via postMessage for visibility in RN console
|
|
197
|
-
try {
|
|
198
|
-
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
199
|
-
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
200
|
-
type: 'rampkit:debug-buggy-screen',
|
|
201
|
-
source: source,
|
|
202
|
-
message: msg,
|
|
203
|
-
data: data
|
|
204
|
-
}));
|
|
205
|
-
}
|
|
206
|
-
} catch(e) {}
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
// ========== END DEBUG ==========
|
|
210
|
-
|
|
211
185
|
// Decode HTML entities
|
|
212
186
|
function decodeHtml(str) {
|
|
213
187
|
if (!str) return str;
|
|
@@ -221,49 +195,21 @@ exports.injectedDynamicTapHandler = `
|
|
|
221
195
|
var current = el;
|
|
222
196
|
var depth = 0;
|
|
223
197
|
var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];
|
|
224
|
-
var searchTrail = []; // DEBUG: Track search path
|
|
225
|
-
|
|
226
198
|
while (current && current !== document.body && current !== document.documentElement && depth < 20) {
|
|
227
|
-
// DEBUG: Build search trail for Screen 19
|
|
228
|
-
var trailInfo = {
|
|
229
|
-
depth: depth,
|
|
230
|
-
tag: current.tagName,
|
|
231
|
-
id: current.id || '(none)',
|
|
232
|
-
class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'
|
|
233
|
-
};
|
|
234
|
-
searchTrail.push(trailInfo);
|
|
235
|
-
|
|
236
199
|
if (current.getAttribute) {
|
|
237
200
|
for (var i = 0; i < attrNames.length; i++) {
|
|
238
201
|
var attr = current.getAttribute(attrNames[i]);
|
|
239
202
|
if (attr && attr.length > 2) {
|
|
240
|
-
var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
|
|
241
|
-
debugBuggyScreen('DynamicTap', 'FOUND data-tap-dynamic', {
|
|
242
|
-
attrName: attrNames[i],
|
|
243
|
-
depth: depth,
|
|
244
|
-
element: trailInfo,
|
|
245
|
-
size: rect.width + 'x' + rect.height,
|
|
246
|
-
configPreview: attr.substring(0, 100) + '...',
|
|
247
|
-
trail: searchTrail
|
|
248
|
-
});
|
|
249
203
|
return { element: current, config: attr };
|
|
250
204
|
}
|
|
251
205
|
}
|
|
252
206
|
if (current.dataset && current.dataset.tapDynamic) {
|
|
253
|
-
var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
|
|
254
|
-
debugBuggyScreen('DynamicTap', 'FOUND dataset.tapDynamic', {
|
|
255
|
-
depth: depth,
|
|
256
|
-
element: trailInfo,
|
|
257
|
-
size: rect2.width + 'x' + rect2.height,
|
|
258
|
-
trail: searchTrail
|
|
259
|
-
});
|
|
260
207
|
return { element: current, config: current.dataset.tapDynamic };
|
|
261
208
|
}
|
|
262
209
|
}
|
|
263
210
|
current = current.parentElement;
|
|
264
211
|
depth++;
|
|
265
212
|
}
|
|
266
|
-
debugBuggyScreen('DynamicTap', 'NO data-tap-dynamic found', { trail: searchTrail });
|
|
267
213
|
return null;
|
|
268
214
|
}
|
|
269
215
|
|
|
@@ -403,75 +349,20 @@ exports.injectedDynamicTapHandler = `
|
|
|
403
349
|
|
|
404
350
|
// Click interceptor - capture phase, runs BEFORE onclick handlers
|
|
405
351
|
function interceptClick(event) {
|
|
406
|
-
// ========== DEBUG: phone-21 click logging ==========
|
|
407
|
-
if (isBuggyScreen()) {
|
|
408
|
-
var clickX = event.clientX;
|
|
409
|
-
var clickY = event.clientY;
|
|
410
|
-
var originalTarget = event.target;
|
|
411
|
-
var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
|
|
412
|
-
debugBuggyScreen('Click', 'Click at (' + clickX + ',' + clickY + ')', {
|
|
413
|
-
originalTarget: {
|
|
414
|
-
tag: originalTarget.tagName,
|
|
415
|
-
id: originalTarget.id || '(none)',
|
|
416
|
-
class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
|
|
417
|
-
size: originalRect.width + 'x' + originalRect.height
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
// ========== END DEBUG ==========
|
|
422
|
-
|
|
423
352
|
var result = findDynamicTap(event.target);
|
|
424
353
|
if (!result) return;
|
|
425
354
|
|
|
426
|
-
// ========== DEBUG: phone-21 - log when dynamic tap is found ==========
|
|
427
|
-
if (isBuggyScreen()) {
|
|
428
|
-
var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};
|
|
429
|
-
var screenWidth = window.innerWidth;
|
|
430
|
-
var screenHeight = window.innerHeight;
|
|
431
|
-
var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);
|
|
432
|
-
debugBuggyScreen('Click', 'DYNAMIC TAP WILL BE HANDLED', {
|
|
433
|
-
element: {
|
|
434
|
-
tag: result.element.tagName,
|
|
435
|
-
id: result.element.id || '(none)',
|
|
436
|
-
class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',
|
|
437
|
-
size: rect.width + 'x' + rect.height
|
|
438
|
-
},
|
|
439
|
-
isFullScreen: isFullScreen,
|
|
440
|
-
WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
// ========== END DEBUG ==========
|
|
444
|
-
|
|
445
355
|
try {
|
|
446
356
|
var configStr = decodeHtml(result.config);
|
|
447
357
|
var config = JSON.parse(configStr);
|
|
448
|
-
|
|
449
|
-
// ========== DEBUG: phone-21 - log parsed config ==========
|
|
450
|
-
if (isBuggyScreen()) {
|
|
451
|
-
debugBuggyScreen('Click', 'Parsed config', {
|
|
452
|
-
hasValues: !!(config && config.values),
|
|
453
|
-
valuesCount: config && config.values ? config.values.length : 0,
|
|
454
|
-
firstCondition: config && config.values && config.values[0] ? {
|
|
455
|
-
conditionType: config.values[0].conditionType,
|
|
456
|
-
rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,
|
|
457
|
-
actionsCount: config.values[0].actions ? config.values[0].actions.length : 0
|
|
458
|
-
} : null
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
// ========== END DEBUG ==========
|
|
462
|
-
|
|
463
358
|
var handled = evalDynamicTap(config);
|
|
464
359
|
if (handled) {
|
|
465
|
-
debugBuggyScreen('Click', 'HANDLED by dynamic tap - event stopped', { handled: true });
|
|
466
360
|
event.stopImmediatePropagation();
|
|
467
361
|
event.preventDefault();
|
|
468
362
|
return false;
|
|
469
363
|
}
|
|
470
364
|
} catch (e) {
|
|
471
365
|
console.log('[RampKit] Dynamic tap error:', e);
|
|
472
|
-
if (isBuggyScreen()) {
|
|
473
|
-
debugBuggyScreen('Click', 'Dynamic tap parse error', { error: e.message });
|
|
474
|
-
}
|
|
475
366
|
}
|
|
476
367
|
}
|
|
477
368
|
|
|
@@ -494,36 +385,9 @@ exports.injectedButtonAnimations = `
|
|
|
494
385
|
var pressedOriginalTransition = '';
|
|
495
386
|
var releaseTimer = null;
|
|
496
387
|
|
|
497
|
-
//
|
|
498
|
-
var isBuggyScreenAnim = function() {
|
|
499
|
-
var screenId = window.__rampkitScreenId || '';
|
|
500
|
-
var screenIndex = window.__rampkitScreenIndex;
|
|
501
|
-
return screenId === 'phone-21' || screenIndex === 18;
|
|
502
|
-
};
|
|
503
|
-
|
|
504
|
-
var debugBuggyScreenAnim = function(source, msg, data) {
|
|
505
|
-
if (isBuggyScreenAnim()) {
|
|
506
|
-
console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));
|
|
507
|
-
// Send to React Native via postMessage for visibility
|
|
508
|
-
try {
|
|
509
|
-
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
510
|
-
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
511
|
-
type: 'rampkit:debug-buggy-screen',
|
|
512
|
-
source: source,
|
|
513
|
-
message: msg,
|
|
514
|
-
data: data
|
|
515
|
-
}));
|
|
516
|
-
}
|
|
517
|
-
} catch(e) {}
|
|
518
|
-
}
|
|
519
|
-
};
|
|
520
|
-
// ========== END DEBUG ==========
|
|
521
|
-
|
|
522
|
-
// Find interactive element - very permissive, looks for any clickable-looking element
|
|
388
|
+
// Find interactive element - looks for clickable-looking elements
|
|
523
389
|
function findInteractive(el) {
|
|
524
390
|
var current = el;
|
|
525
|
-
var debugTrail = []; // DEBUG: Track search path for Screen 19
|
|
526
|
-
|
|
527
391
|
for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {
|
|
528
392
|
if (!current || !current.tagName) { current = current.parentElement; continue; }
|
|
529
393
|
var tag = current.tagName.toLowerCase();
|
|
@@ -532,54 +396,42 @@ exports.injectedButtonAnimations = `
|
|
|
532
396
|
var rect = current.getBoundingClientRect();
|
|
533
397
|
if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }
|
|
534
398
|
|
|
535
|
-
// DEBUG: Build trail for Screen 19
|
|
536
|
-
var debugInfo = {
|
|
537
|
-
depth: i,
|
|
538
|
-
tag: tag,
|
|
539
|
-
id: current.id || '(none)',
|
|
540
|
-
class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',
|
|
541
|
-
size: rect.width + 'x' + rect.height
|
|
542
|
-
};
|
|
543
|
-
debugTrail.push(debugInfo);
|
|
544
|
-
|
|
545
399
|
// Match standard interactive elements
|
|
546
|
-
if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select')
|
|
547
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });
|
|
548
|
-
return current;
|
|
549
|
-
}
|
|
400
|
+
if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;
|
|
550
401
|
|
|
551
|
-
// Match elements with
|
|
402
|
+
// Match elements with tap/click-related data attributes
|
|
403
|
+
// Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions
|
|
552
404
|
var attrs = current.attributes;
|
|
553
405
|
if (attrs) {
|
|
554
406
|
for (var j = 0; j < attrs.length; j++) {
|
|
555
407
|
var attrName = attrs[j].name.toLowerCase();
|
|
408
|
+
// Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)
|
|
409
|
+
// These are for screen lifecycle events, not user tap interactions
|
|
410
|
+
var isLifecycleAttr = (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||
|
|
411
|
+
attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||
|
|
412
|
+
attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||
|
|
413
|
+
attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1);
|
|
414
|
+
if (isLifecycleAttr) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
// Match tap/click interaction attributes
|
|
556
418
|
if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||
|
|
557
419
|
attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||
|
|
558
420
|
attrName.indexOf('press') !== -1) {
|
|
559
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });
|
|
560
421
|
return current;
|
|
561
422
|
}
|
|
562
423
|
}
|
|
563
424
|
}
|
|
564
425
|
|
|
565
426
|
// Match elements with onclick
|
|
566
|
-
if (current.onclick || current.hasAttribute('onclick'))
|
|
567
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: onclick', { element: debugInfo, trail: debugTrail });
|
|
568
|
-
return current;
|
|
569
|
-
}
|
|
427
|
+
if (current.onclick || current.hasAttribute('onclick')) return current;
|
|
570
428
|
|
|
571
|
-
// Match elements with role="button"
|
|
572
|
-
if (current.getAttribute('role') === 'button')
|
|
573
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: role=button', { element: debugInfo, trail: debugTrail });
|
|
574
|
-
return current;
|
|
575
|
-
}
|
|
429
|
+
// Match elements with role="button"
|
|
430
|
+
if (current.getAttribute('role') === 'button') return current;
|
|
576
431
|
|
|
577
432
|
// Match any element with an ID containing button/btn/cta
|
|
578
433
|
var id = current.id || '';
|
|
579
|
-
if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1))
|
|
580
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });
|
|
581
|
-
return current;
|
|
582
|
-
}
|
|
434
|
+
if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;
|
|
583
435
|
|
|
584
436
|
// Match elements with button-like classes
|
|
585
437
|
var className = current.className;
|
|
@@ -587,7 +439,6 @@ exports.injectedButtonAnimations = `
|
|
|
587
439
|
var cls = className.toLowerCase();
|
|
588
440
|
if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||
|
|
589
441
|
cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {
|
|
590
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });
|
|
591
442
|
return current;
|
|
592
443
|
}
|
|
593
444
|
}
|
|
@@ -595,18 +446,14 @@ exports.injectedButtonAnimations = `
|
|
|
595
446
|
// Match elements with cursor pointer
|
|
596
447
|
try {
|
|
597
448
|
var computed = window.getComputedStyle(current);
|
|
598
|
-
if (computed && computed.cursor === 'pointer')
|
|
599
|
-
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });
|
|
600
|
-
return current;
|
|
601
|
-
}
|
|
449
|
+
if (computed && computed.cursor === 'pointer') return current;
|
|
602
450
|
} catch(e) {}
|
|
603
451
|
|
|
604
452
|
current = current.parentElement;
|
|
605
453
|
}
|
|
606
|
-
debugBuggyScreenAnim('ButtonAnim', 'NO MATCH found', { originalTag: el.tagName, trail: debugTrail });
|
|
607
454
|
return null;
|
|
608
455
|
}
|
|
609
|
-
|
|
456
|
+
|
|
610
457
|
function applyPressedStyle(el) {
|
|
611
458
|
if (!el || !el.style) return;
|
|
612
459
|
// Save original styles
|
|
@@ -618,7 +465,7 @@ exports.injectedButtonAnimations = `
|
|
|
618
465
|
el.style.transform = 'scale(0.97)';
|
|
619
466
|
el.style.opacity = '0.8';
|
|
620
467
|
}
|
|
621
|
-
|
|
468
|
+
|
|
622
469
|
function applyReleasedStyle(el) {
|
|
623
470
|
if (!el || !el.style) return;
|
|
624
471
|
// Apply spring-back animation
|
|
@@ -626,53 +473,18 @@ exports.injectedButtonAnimations = `
|
|
|
626
473
|
el.style.transform = pressedOriginalTransform || 'scale(1)';
|
|
627
474
|
el.style.opacity = pressedOriginalOpacity || '1';
|
|
628
475
|
}
|
|
629
|
-
|
|
476
|
+
|
|
630
477
|
function resetStyle(el) {
|
|
631
478
|
if (!el || !el.style) return;
|
|
632
479
|
el.style.transform = pressedOriginalTransform;
|
|
633
480
|
el.style.opacity = pressedOriginalOpacity;
|
|
634
481
|
el.style.transition = pressedOriginalTransition;
|
|
635
482
|
}
|
|
636
|
-
|
|
483
|
+
|
|
637
484
|
function onTouchStart(e) {
|
|
638
485
|
try {
|
|
639
|
-
// ========== DEBUG: phone-21 touch logging ==========
|
|
640
|
-
if (isBuggyScreenAnim()) {
|
|
641
|
-
var touchX = e.touches ? e.touches[0].clientX : e.clientX;
|
|
642
|
-
var touchY = e.touches ? e.touches[0].clientY : e.clientY;
|
|
643
|
-
var originalTarget = e.target;
|
|
644
|
-
var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
|
|
645
|
-
debugBuggyScreenAnim('TouchStart', 'Touch at (' + touchX + ',' + touchY + ')', {
|
|
646
|
-
originalTarget: {
|
|
647
|
-
tag: originalTarget.tagName,
|
|
648
|
-
id: originalTarget.id || '(none)',
|
|
649
|
-
class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
|
|
650
|
-
size: originalRect.width + 'x' + originalRect.height
|
|
651
|
-
}
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
// ========== END DEBUG ==========
|
|
655
|
-
|
|
656
486
|
var target = findInteractive(e.target);
|
|
657
487
|
if (!target) return;
|
|
658
|
-
|
|
659
|
-
// ========== DEBUG: phone-21 - log what element was found interactive ==========
|
|
660
|
-
if (isBuggyScreenAnim() && target) {
|
|
661
|
-
var targetRect = target.getBoundingClientRect();
|
|
662
|
-
var screenWidth = window.innerWidth;
|
|
663
|
-
var screenHeight = window.innerHeight;
|
|
664
|
-
var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);
|
|
665
|
-
debugBuggyScreenAnim('TouchStart', 'INTERACTIVE ELEMENT FOUND', {
|
|
666
|
-
tag: target.tagName,
|
|
667
|
-
id: target.id || '(none)',
|
|
668
|
-
class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',
|
|
669
|
-
size: targetRect.width + 'x' + targetRect.height,
|
|
670
|
-
isFullScreen: isFullScreen,
|
|
671
|
-
WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
|
-
// ========== END DEBUG ==========
|
|
675
|
-
|
|
676
488
|
if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }
|
|
677
489
|
if (pressed && pressed !== target) { resetStyle(pressed); }
|
|
678
490
|
applyPressedStyle(target);
|
|
@@ -2017,29 +1829,9 @@ function Overlay(props) {
|
|
|
2017
1829
|
}
|
|
2018
1830
|
}
|
|
2019
1831
|
}, onMessage: (ev) => {
|
|
2020
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k
|
|
1832
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
2021
1833
|
const raw = ev.nativeEvent.data;
|
|
2022
1834
|
console.log("raw", raw);
|
|
2023
|
-
// ========== DEBUG: phone-21 onMessage logging (REMOVE AFTER BUG FIX) ==========
|
|
2024
|
-
const screenId = ((_a = props.screens[i]) === null || _a === void 0 ? void 0 : _a.id) || "";
|
|
2025
|
-
const isBuggyScreenOnMsg = screenId === 'phone-21' || i === 18;
|
|
2026
|
-
if (isBuggyScreenOnMsg) {
|
|
2027
|
-
console.log(`[BUGGY-SCREEN][onMessage] Received message from screen ${i} (ID: ${screenId})`, JSON.stringify({
|
|
2028
|
-
rawPreview: raw.substring(0, 200),
|
|
2029
|
-
isActiveScreen: i === activeScreenIndexRef.current,
|
|
2030
|
-
activeScreenIndex: activeScreenIndexRef.current
|
|
2031
|
-
}));
|
|
2032
|
-
}
|
|
2033
|
-
// Also handle debug messages from WebView
|
|
2034
|
-
try {
|
|
2035
|
-
const debugData = JSON.parse(raw);
|
|
2036
|
-
if ((debugData === null || debugData === void 0 ? void 0 : debugData.type) === 'rampkit:debug-buggy-screen') {
|
|
2037
|
-
console.log(`[BUGGY-SCREEN][${debugData.source}] ${debugData.message}`, JSON.stringify(debugData.data || {}));
|
|
2038
|
-
return; // Don't process further, it's just a debug message
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
catch (_) { }
|
|
2042
|
-
// ========== END DEBUG ==========
|
|
2043
1835
|
// Accept either raw strings or JSON payloads from your editor
|
|
2044
1836
|
try {
|
|
2045
1837
|
// JSON path
|
|
@@ -2165,7 +1957,7 @@ function Overlay(props) {
|
|
|
2165
1957
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:onboarding-finished") {
|
|
2166
1958
|
setOnboardingCompleted(true);
|
|
2167
1959
|
try {
|
|
2168
|
-
(
|
|
1960
|
+
(_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
|
|
2169
1961
|
}
|
|
2170
1962
|
catch (_) { }
|
|
2171
1963
|
handleRequestClose({ completed: true });
|
|
@@ -2174,7 +1966,7 @@ function Overlay(props) {
|
|
|
2174
1966
|
// 6) Request to show paywall
|
|
2175
1967
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
|
|
2176
1968
|
try {
|
|
2177
|
-
(
|
|
1969
|
+
(_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props, data === null || data === void 0 ? void 0 : data.payload);
|
|
2178
1970
|
}
|
|
2179
1971
|
catch (_) { }
|
|
2180
1972
|
return;
|
|
@@ -2185,9 +1977,9 @@ function Overlay(props) {
|
|
|
2185
1977
|
if (questionId) {
|
|
2186
1978
|
const response = {
|
|
2187
1979
|
questionId,
|
|
2188
|
-
answer: (
|
|
1980
|
+
answer: (_c = data === null || data === void 0 ? void 0 : data.answer) !== null && _c !== void 0 ? _c : "",
|
|
2189
1981
|
questionText: data === null || data === void 0 ? void 0 : data.questionText,
|
|
2190
|
-
screenName: (
|
|
1982
|
+
screenName: (_d = props.screens[i]) === null || _d === void 0 ? void 0 : _d.id,
|
|
2191
1983
|
answeredAt: new Date().toISOString(),
|
|
2192
1984
|
};
|
|
2193
1985
|
OnboardingResponseStorage_1.OnboardingResponseStorage.saveResponse(response);
|
|
@@ -2196,71 +1988,62 @@ function Overlay(props) {
|
|
|
2196
1988
|
}
|
|
2197
1989
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:continue" ||
|
|
2198
1990
|
(data === null || data === void 0 ? void 0 : data.type) === "continue") {
|
|
2199
|
-
|
|
1991
|
+
const executeContinue = () => handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
1992
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2200
1993
|
if (!isScreenActive(i)) {
|
|
2201
1994
|
if (__DEV__)
|
|
2202
|
-
console.log(`[
|
|
1995
|
+
console.log(`[Rampkit] Queuing continue from inactive screen ${i}`);
|
|
1996
|
+
queueAction(i, executeContinue);
|
|
2203
1997
|
return;
|
|
2204
1998
|
}
|
|
2205
|
-
|
|
2206
|
-
if (isBuggyScreenOnMsg) {
|
|
2207
|
-
console.log(`[BUGGY-SCREEN][onMessage] CONTINUE action triggered from screen ${i}`, JSON.stringify({
|
|
2208
|
-
animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
|
|
2209
|
-
screenId: screenId
|
|
2210
|
-
}));
|
|
2211
|
-
}
|
|
2212
|
-
// ========== END DEBUG ==========
|
|
2213
|
-
handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
1999
|
+
executeContinue();
|
|
2214
2000
|
return;
|
|
2215
2001
|
}
|
|
2216
2002
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:navigate") {
|
|
2217
|
-
|
|
2003
|
+
const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
|
|
2004
|
+
const executeNavigate = () => {
|
|
2005
|
+
if (target === "__goBack__") {
|
|
2006
|
+
handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
if (!target || target === "__continue__") {
|
|
2010
|
+
handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2011
|
+
return;
|
|
2012
|
+
}
|
|
2013
|
+
const targetIndex = props.screens.findIndex((s) => s.id === target);
|
|
2014
|
+
if (targetIndex >= 0) {
|
|
2015
|
+
navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2016
|
+
}
|
|
2017
|
+
else {
|
|
2018
|
+
handleAdvance(i);
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
2021
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2218
2022
|
if (!isScreenActive(i)) {
|
|
2219
2023
|
if (__DEV__)
|
|
2220
|
-
console.log(`[
|
|
2024
|
+
console.log(`[Rampkit] Queuing navigate from inactive screen ${i}`);
|
|
2025
|
+
queueAction(i, executeNavigate);
|
|
2221
2026
|
return;
|
|
2222
2027
|
}
|
|
2223
|
-
|
|
2224
|
-
// ========== DEBUG: phone-21 navigate logging ==========
|
|
2225
|
-
if (isBuggyScreenOnMsg) {
|
|
2226
|
-
console.log(`[BUGGY-SCREEN][onMessage] NAVIGATE action triggered from screen ${i}`, JSON.stringify({
|
|
2227
|
-
target: target,
|
|
2228
|
-
animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
|
|
2229
|
-
screenId: screenId
|
|
2230
|
-
}));
|
|
2231
|
-
}
|
|
2232
|
-
// ========== END DEBUG ==========
|
|
2233
|
-
if (target === "__goBack__") {
|
|
2234
|
-
handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2235
|
-
return;
|
|
2236
|
-
}
|
|
2237
|
-
if (!target || target === "__continue__") {
|
|
2238
|
-
handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2239
|
-
return;
|
|
2240
|
-
}
|
|
2241
|
-
const targetIndex = props.screens.findIndex((s) => s.id === target);
|
|
2242
|
-
if (targetIndex >= 0) {
|
|
2243
|
-
navigateToIndex(targetIndex, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2244
|
-
}
|
|
2245
|
-
else {
|
|
2246
|
-
handleAdvance(i);
|
|
2247
|
-
}
|
|
2028
|
+
executeNavigate();
|
|
2248
2029
|
return;
|
|
2249
2030
|
}
|
|
2250
2031
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:goBack") {
|
|
2251
|
-
|
|
2032
|
+
const executeGoBack = () => handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
|
|
2033
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2252
2034
|
if (!isScreenActive(i)) {
|
|
2253
2035
|
if (__DEV__)
|
|
2254
|
-
console.log(`[
|
|
2036
|
+
console.log(`[Rampkit] Queuing goBack from inactive screen ${i}`);
|
|
2037
|
+
queueAction(i, executeGoBack);
|
|
2255
2038
|
return;
|
|
2256
2039
|
}
|
|
2257
|
-
|
|
2040
|
+
executeGoBack();
|
|
2258
2041
|
return;
|
|
2259
2042
|
}
|
|
2260
2043
|
if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
|
|
2261
2044
|
// Track close action for onboarding completion
|
|
2262
2045
|
try {
|
|
2263
|
-
(
|
|
2046
|
+
(_e = props.onCloseAction) === null || _e === void 0 ? void 0 : _e.call(props, i, ((_f = props.screens[i]) === null || _f === void 0 ? void 0 : _f.id) || "");
|
|
2264
2047
|
}
|
|
2265
2048
|
catch (_) { }
|
|
2266
2049
|
handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
|
|
@@ -2271,18 +2054,20 @@ function Overlay(props) {
|
|
|
2271
2054
|
return;
|
|
2272
2055
|
}
|
|
2273
2056
|
}
|
|
2274
|
-
catch (
|
|
2057
|
+
catch (_l) {
|
|
2275
2058
|
// String path
|
|
2276
2059
|
if (raw === "rampkit:tap" ||
|
|
2277
2060
|
raw === "next" ||
|
|
2278
2061
|
raw === "continue") {
|
|
2279
|
-
|
|
2062
|
+
const executeAdvance = () => handleAdvance(i);
|
|
2063
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2280
2064
|
if (!isScreenActive(i)) {
|
|
2281
2065
|
if (__DEV__)
|
|
2282
|
-
console.log(`[
|
|
2066
|
+
console.log(`[Rampkit] Queuing ${raw} from inactive screen ${i}`);
|
|
2067
|
+
queueAction(i, executeAdvance);
|
|
2283
2068
|
return;
|
|
2284
2069
|
}
|
|
2285
|
-
|
|
2070
|
+
executeAdvance();
|
|
2286
2071
|
return;
|
|
2287
2072
|
}
|
|
2288
2073
|
if (raw === "rampkit:request-review" || raw === "rampkit:review") {
|
|
@@ -2322,7 +2107,7 @@ function Overlay(props) {
|
|
|
2322
2107
|
if (raw === "rampkit:onboarding-finished") {
|
|
2323
2108
|
setOnboardingCompleted(true);
|
|
2324
2109
|
try {
|
|
2325
|
-
(
|
|
2110
|
+
(_g = props.onOnboardingFinished) === null || _g === void 0 ? void 0 : _g.call(props, undefined);
|
|
2326
2111
|
}
|
|
2327
2112
|
catch (_) { }
|
|
2328
2113
|
handleRequestClose({ completed: true });
|
|
@@ -2330,50 +2115,56 @@ function Overlay(props) {
|
|
|
2330
2115
|
}
|
|
2331
2116
|
if (raw === "rampkit:show-paywall") {
|
|
2332
2117
|
try {
|
|
2333
|
-
(
|
|
2118
|
+
(_h = props.onShowPaywall) === null || _h === void 0 ? void 0 : _h.call(props);
|
|
2334
2119
|
}
|
|
2335
2120
|
catch (_) { }
|
|
2336
2121
|
return;
|
|
2337
2122
|
}
|
|
2338
2123
|
if (raw === "rampkit:goBack") {
|
|
2339
|
-
|
|
2124
|
+
const executeGoBack = () => handleGoBack(i);
|
|
2125
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2340
2126
|
if (!isScreenActive(i)) {
|
|
2341
2127
|
if (__DEV__)
|
|
2342
|
-
console.log(`[
|
|
2128
|
+
console.log(`[Rampkit] Queuing goBack (raw) from inactive screen ${i}`);
|
|
2129
|
+
queueAction(i, executeGoBack);
|
|
2343
2130
|
return;
|
|
2344
2131
|
}
|
|
2345
|
-
|
|
2132
|
+
executeGoBack();
|
|
2346
2133
|
return;
|
|
2347
2134
|
}
|
|
2348
2135
|
if (raw.startsWith("rampkit:navigate:")) {
|
|
2349
|
-
|
|
2136
|
+
const target = raw.slice("rampkit:navigate:".length);
|
|
2137
|
+
const executeNavigate = () => {
|
|
2138
|
+
if (target === "__goBack__") {
|
|
2139
|
+
handleGoBack(i);
|
|
2140
|
+
return;
|
|
2141
|
+
}
|
|
2142
|
+
if (!target || target === "__continue__") {
|
|
2143
|
+
handleAdvance(i);
|
|
2144
|
+
return;
|
|
2145
|
+
}
|
|
2146
|
+
const targetIndex = props.screens.findIndex((s) => s.id === target);
|
|
2147
|
+
if (targetIndex >= 0) {
|
|
2148
|
+
navigateToIndex(targetIndex);
|
|
2149
|
+
}
|
|
2150
|
+
else {
|
|
2151
|
+
handleAdvance(i);
|
|
2152
|
+
}
|
|
2153
|
+
};
|
|
2154
|
+
// Queue if screen is not active (e.g., on-open actions during preload)
|
|
2350
2155
|
if (!isScreenActive(i)) {
|
|
2351
2156
|
if (__DEV__)
|
|
2352
|
-
console.log(`[
|
|
2353
|
-
|
|
2354
|
-
}
|
|
2355
|
-
const target = raw.slice("rampkit:navigate:".length);
|
|
2356
|
-
if (target === "__goBack__") {
|
|
2357
|
-
handleGoBack(i);
|
|
2157
|
+
console.log(`[Rampkit] Queuing navigate (raw) from inactive screen ${i}`);
|
|
2158
|
+
queueAction(i, executeNavigate);
|
|
2358
2159
|
return;
|
|
2359
2160
|
}
|
|
2360
|
-
|
|
2361
|
-
handleAdvance(i);
|
|
2362
|
-
return;
|
|
2363
|
-
}
|
|
2364
|
-
const targetIndex = props.screens.findIndex((s) => s.id === target);
|
|
2365
|
-
if (targetIndex >= 0) {
|
|
2366
|
-
navigateToIndex(targetIndex);
|
|
2367
|
-
}
|
|
2368
|
-
else {
|
|
2369
|
-
handleAdvance(i);
|
|
2370
|
-
}
|
|
2161
|
+
executeNavigate();
|
|
2371
2162
|
return;
|
|
2372
2163
|
}
|
|
2373
2164
|
if (raw === "rampkit:close") {
|
|
2374
2165
|
// Track close action for onboarding completion
|
|
2375
2166
|
try {
|
|
2376
|
-
(
|
|
2167
|
+
(_j = props.onCloseAction) === null || _j === void 0 ? void 0 : _j.call(props, i, ((_k = props.screens[i]) === null || _k === void 0 ? void 0 : _k.id) || "");
|
|
2377
2168
|
}
|
|
2378
2169
|
catch (_) { }
|
|
2379
2170
|
handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
|
package/package.json
CHANGED