onboardsync-react-native
Version:
Expo SDK for OnboardSync - Remote onboarding configuration platform with A/B testing
162 lines (156 loc) • 7.43 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebViewScreen = void 0;
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const react_native_webview_1 = require("react-native-webview");
const StoreReview = __importStar(require("expo-store-review"));
const LoadingScreen_1 = require("./LoadingScreen");
const FallbackScreen_1 = require("./FallbackScreen");
const statusBarHelper_1 = require("../utils/statusBarHelper");
const permissionsHandler_1 = require("../utils/permissionsHandler");
const colorUtils_1 = require("../utils/colorUtils");
const constants_1 = require("../constants");
const WebViewScreen = ({ url, testingEnabled, appName, backgroundColor, onClose, onComplete, }) => {
const [isInitialLoadComplete, setIsInitialLoadComplete] = (0, react_1.useState)(false);
const [showFallback, setShowFallback] = (0, react_1.useState)(false);
const webViewRef = (0, react_1.useRef)(null);
const handleMessage = (0, react_1.useCallback)(async (event) => {
const message = event.nativeEvent.data;
console.log(`[WebViewScreen] Received message: ${message}`);
if (message.startsWith('themeStyle:')) {
const style = message.substring('themeStyle:'.length);
console.log(`[WebViewScreen] Theme style: ${style}`);
const needsLightContent = (style === 'light' || style === 'dark');
statusBarHelper_1.StatusBarHelper.updateForTheme(needsLightContent ? 'light' : 'dark');
}
else if (message === 'close_pressed') {
console.log('[WebViewScreen] Close pressed');
onComplete();
}
else if (message === 'request_rating') {
console.log('[WebViewScreen] App rating requested');
try {
const isAvailable = await StoreReview.isAvailableAsync();
if (isAvailable) {
await StoreReview.requestReview();
console.log('[WebViewScreen] Store review requested');
}
else {
console.log('[WebViewScreen] Store review not available');
}
}
catch (error) {
console.error('[WebViewScreen] Error requesting review:', error);
}
}
else if (message.startsWith('request_permission:')) {
const permission = message.substring('request_permission:'.length);
console.log(`[WebViewScreen] Permission requested: ${permission}`);
const granted = await permissionsHandler_1.PermissionsHandler.requestPermission(permission);
console.log(`[WebViewScreen] Permission ${permission} granted: ${granted}`);
}
else if (message === 'initial_load_complete') {
console.log('[WebViewScreen] Initial load complete');
setIsInitialLoadComplete(true);
}
else {
console.log(`[WebViewScreen] Unknown message: ${message}`);
}
}, [onComplete]);
const handleLoadEnd = (0, react_1.useCallback)(() => {
console.log('[WebViewScreen] WebView loaded');
}, []);
const handleError = (0, react_1.useCallback)(() => {
console.error('[WebViewScreen] WebView error, showing fallback');
setShowFallback(true);
}, []);
const handleHttpError = (0, react_1.useCallback)((syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
console.error(`[WebViewScreen] HTTP error: ${nativeEvent.statusCode}`);
if (nativeEvent.statusCode >= 400) {
setShowFallback(true);
}
}, []);
const injectedJavaScript = `
(function() {
// Create the bridge object matching Flutter/Swift
window.${constants_1.Constants.JAVASCRIPT_CHANNEL} = {
postMessage: function(message) {
window.ReactNativeWebView.postMessage(message);
}
};
// Set initial background color
const isDark = ${colorUtils_1.ColorUtils.isDarkColor(backgroundColor)};
const bgColor = isDark ? '#000000' : '#FFFFFF';
const textColor = isDark ? '#FFFFFF' : '#000000';
const style = document.createElement('style');
style.innerHTML = \`
body {
background-color: \${bgColor} !important;
color: \${textColor} !important;
}
\`;
document.head.appendChild(style);
console.log('[OnboardSync] JavaScript bridge initialized');
true; // Required for Android
})();
`;
if (showFallback) {
return (<FallbackScreen_1.FallbackScreen appName={appName} backgroundColor={backgroundColor} textColor={colorUtils_1.ColorUtils.getContrastColor(backgroundColor)} onClose={onClose}/>);
}
return (<react_native_1.View style={[styles.container, { backgroundColor }]}>
<react_native_1.View style={styles.webViewContainer}>
<react_native_webview_1.WebView ref={webViewRef} source={{ uri: url }} style={[styles.webView, { backgroundColor, opacity: isInitialLoadComplete ? 1 : 0 }]} onMessage={handleMessage} onLoadEnd={handleLoadEnd} onError={handleError} onHttpError={handleHttpError} injectedJavaScript={injectedJavaScript} javaScriptEnabled={true} domStorageEnabled={true} startInLoadingState={false} allowsInlineMediaPlayback={true} allowsFullscreenVideo={true} mixedContentMode="compatibility" cacheEnabled={!testingEnabled} incognito={testingEnabled}/>
{!isInitialLoadComplete && (<react_native_1.View style={react_native_1.StyleSheet.absoluteFillObject}>
<LoadingScreen_1.LoadingScreen appName={appName} backgroundColor={backgroundColor}/>
</react_native_1.View>)}
</react_native_1.View>
</react_native_1.View>);
};
exports.WebViewScreen = WebViewScreen;
const styles = react_native_1.StyleSheet.create({
container: {
flex: 1,
},
webViewContainer: {
flex: 1,
},
webView: {
flex: 1,
},
});
//# sourceMappingURL=WebViewScreen.js.map