Files
ACEquity-wma/App.tsx
Arkaprabha Chakraborty 63747e4692 init
2026-01-14 06:07:55 +05:30

161 lines
4.3 KiB
TypeScript

import React, {useRef, useState, useCallback} from 'react';
import {
View,
StatusBar,
StyleSheet,
Image,
BackHandler,
Platform,
Alert,
ToastAndroid,
} from 'react-native';
import {WebView, WebViewNavigation} from 'react-native-webview';
import type {WebViewProgressEvent} from 'react-native-webview/lib/WebViewTypes';
// Configuration - Change this URL to your target website
const TARGET_URL = 'https://ace.webark.in';
// App Logo - Place your logo.png in the assets folder
const APP_LOGO = require('./assets/logo.png');
const App: React.FC = () => {
const webViewRef = useRef<WebView>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);
const [loadProgress, setLoadProgress] = useState<number>(0);
const [canGoBack, setCanGoBack] = useState<boolean>(false);
const lastBackPress = useRef<number>(0);
// Handle Android hardware back button
React.useEffect(() => {
if (Platform.OS === 'android') {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
if (canGoBack && webViewRef.current) {
webViewRef.current.goBack();
return true; // Prevent default behavior
}
// Handle double-back-to-exit
const currentTime = Date.now();
if (currentTime - lastBackPress.current < 2000) {
// Second press within 2 seconds - exit app
BackHandler.exitApp();
return true;
} else {
// First press - show message
lastBackPress.current = currentTime;
ToastAndroid.show(
'Press back again to exit',
ToastAndroid.SHORT,
);
return true; // Prevent default behavior
}
},
);
return () => backHandler.remove();
}
}, [canGoBack]);
// Handle navigation state changes
const handleNavigationStateChange = useCallback(
(navState: WebViewNavigation) => {
setCanGoBack(navState.canGoBack);
},
[],
);
// Handle load progress
const handleLoadProgress = useCallback((event: WebViewProgressEvent) => {
setLoadProgress(event.nativeEvent.progress);
}, []);
// Handle load start
const handleLoadStart = useCallback(() => {
setIsLoading(true);
}, []);
// Handle load end
const handleLoadEnd = useCallback(() => {
setIsLoading(false);
}, []);
return (
<View style={styles.container}>
<StatusBar
barStyle="light-content"
backgroundColor="#000000"
translucent={false}
/>
{/* WebView */}
<WebView
ref={webViewRef}
source={{uri: TARGET_URL}}
style={styles.webView}
onNavigationStateChange={handleNavigationStateChange}
onLoadProgress={handleLoadProgress}
onLoadStart={handleLoadStart}
onLoadEnd={handleLoadEnd}
// Performance optimizations
javaScriptEnabled={true}
domStorageEnabled={true}
startInLoadingState={true}
scalesPageToFit={true}
// Allow media playback
allowsInlineMediaPlayback={true}
mediaPlaybackRequiresUserAction={false}
// Security settings
originWhitelist={['https://*', 'http://*']}
mixedContentMode="compatibility"
// Caching
cacheEnabled={true}
// User agent (optional - customize if needed)
// userAgent="CustomUserAgent/1.0"
// Error handling
onError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.warn('WebView error:', nativeEvent);
}}
onHttpError={syntheticEvent => {
const {nativeEvent} = syntheticEvent;
console.warn('HTTP error:', nativeEvent.statusCode);
}}
// Render loading indicator
renderLoading={() => (
<View style={styles.loadingContainer}>
<Image source={APP_LOGO} style={styles.logo} resizeMode="contain" />
</View>
)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#ffffff',
},
webView: {
flex: 1,
},
loadingContainer: {
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ffffff',
},
logo: {
width: 120,
height: 120,
},
});
export default App;