Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Jalson1982/5f6811d980f01bddab29205a6da9b0d9 to your computer and use it in GitHub Desktop.
Save Jalson1982/5f6811d980f01bddab29205a6da9b0d9 to your computer and use it in GitHub Desktop.
import React, {useCallback, useLayoutEffect, useState} from 'react';
import WebView from 'react-native-webview';
import {StyleSheet, View, ActivityIndicator} from 'react-native';
import {USER_AGENT} from '../../environment';
import {useLoadWithRequest} from '../../hooks/useLoadWithRequest';
import BackButton from '../../components/BackButton';
import {HeaderButtons} from 'react-navigation-header-buttons';
import {useNavigationState} from '@react-navigation/native';
import ShareButton from '../../components/ShareButton';
import Error from '../../components/Error';
import {useDispatch, useSelector} from 'react-redux';
import {setSignInProgessDone} from '../../auth/authSlice';
const CommonScreen = ({navigation, route}) => {
const state = useNavigationState(navState => navState);
const {
webviewRef,
onShouldStartLoadWithRequest,
activeUrl,
headerTitle,
onMessage,
shareButtonVisible,
loggedIn,
allowWebBack,
shareUrl,
hasError,
reloadWeb,
errorHandling,
backgroundColor,
safeAreaInjectedCss,
} = useLoadWithRequest({url: route.params.url});
const dispatch = useDispatch();
const {signInInProgress} = useSelector(rs => rs.auth);
const [refresherEnabled, setEnableRefresher] = useState(true);
const [headerVisible, setHeaderVisible] = useState(true);
const [pageLoading, setPageLoading] = useState(true);
const [canGoBack, setCanGoBack] = useState(false);
const onNavigationStateChange = event => {
handleHeaderVisibility(event);
setCanGoBack(event.canGoBack);
};
const onBackButtonPress = useCallback(() => {
if (canGoBack && allowWebBack) {
webviewRef.current.goBack();
} else {
navigation.goBack();
}
}, [allowWebBack, canGoBack, navigation, webviewRef]);
const headerLeft = useCallback(() => {
return (
<HeaderButtons>
<BackButton
onPressBack={onBackButtonPress}
label={route.params.backTitle ?? state?.routeNames[state.index - 1]}
/>
</HeaderButtons>
);
}, [
onBackButtonPress,
route.params.backTitle,
state.index,
state?.routeNames,
]);
const headerRight = useCallback(() => {
return (
<View style={styles.headerRight}>
{pageLoading ? (
<View style={styles.loader}>
<ActivityIndicator style={styles.activityIndicator} />
</View>
) : (
shareButtonVisible && <ShareButton url={shareUrl} />
)}
</View>
);
}, [pageLoading, shareButtonVisible, shareUrl]);
useLayoutEffect(() => {
navigation.setOptions({
headerStyle: {
backgroundColor: '#012f3e',
shadowColor: 'transparent',
},
headerShadowVisible: false,
headerShown: headerVisible,
headerLeft: headerLeft,
headerRight: headerRight,
headerTintColor: '#fff',
title: headerTitle,
});
}, [
navigation,
headerVisible,
headerTitle,
headerLeft,
headerRight,
canGoBack,
]);
const handleHeaderVisibility = event => {
const {hash} = new URL(event.url);
if (hash === '#map') {
setHeaderVisible(false);
} else {
setHeaderVisible(true);
}
};
const handleScroll = event => {
const yOffset = Number(event.nativeEvent.contentOffset.y);
if (yOffset === 0) {
setEnableRefresher(true);
} else if (refresherEnabled) {
setEnableRefresher(false);
}
};
return (
<View style={[styles.flex1, {backgroundColor}]}>
{hasError && <Error reloadWeb={reloadWeb} />}
<WebView
ref={webviewRef}
key={loggedIn}
webviewDebuggingEnabled
userAgent={USER_AGENT}
cacheEnabled
pullToRefreshEnabled
onScroll={handleScroll}
originWhitelist={['*']}
containerStyle={styles.flex1}
renderLoading={() => null}
thirdPartyCookiesEnabled
sharedCookiesEnabled={signInInProgress}
allowsBackForwardNavigationGestures={allowWebBack}
decelerationRate={'normal'}
onMessage={onMessage}
onError={errorHandling}
onNavigationStateChange={onNavigationStateChange}
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
onContentProcessDidTerminate={() => {
webviewRef.current.reload();
}}
onLoadEnd={() => {
setPageLoading(false);
dispatch(setSignInProgessDone());
}}
style={[styles.webView, {backgroundColor}]}
source={{uri: activeUrl}}
injectedJavaScript={safeAreaInjectedCss}
/>
</View>
);
};
const styles = StyleSheet.create({
webView: {flex: 1},
loader: {width: 44, height: 44, marginRight: -30, justifyContent: 'center'},
headerRight: {
width: 80,
height: 44,
alignItems: 'flex-end',
justifyContent: 'center',
},
flex1: {flex: 1},
animatedContainer: {height: '100%'},
scrollView: {flex: 1, backgroundColor: 'transparent'},
activityIndicator: {marginRight: 30},
});
export default CommonScreen;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment