Skip to content

Commit

Permalink
feat(MyPortal): [#175114980] Implements check on loading error on Web…
Browse files Browse the repository at this point in the history
…view component (#2264)

* [#175114980] Implements check on loading error on Webview component

* Revert WebPlayground fixed uri

* Improvements

Co-authored-by: Matteo Boschi <[email protected]>
  • Loading branch information
CrisTofani and Undermaken authored Oct 7, 2020
1 parent 6351eff commit 13d2999
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 14 deletions.
110 changes: 97 additions & 13 deletions ts/components/RegionServiceWebView.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { fromNullable } from "fp-ts/lib/Option";
import { Body, Container, Content, Right, View } from "native-base";
import * as React from "react";
import { Alert, StyleSheet } from "react-native";
import { Alert, Image, StyleSheet } from "react-native";
import { heightPercentageToDP } from "react-native-responsive-screen";
import WebView, { WebViewMessageEvent } from "react-native-webview";
import URLParse from "url-parse";
import {
WebViewErrorEvent,
WebViewHttpErrorEvent
} from "react-native-webview/lib/WebViewTypes";
import brokenLinkImage from "../../img/broken-link.png";
import I18n from "../i18n";
import customVariables from "../theme/variables";
import { WebviewMessage } from "../types/WebviewMessage";
Expand All @@ -17,6 +22,7 @@ import {
} from "../utils/webview";
import ButtonDefaultOpacity from "./ButtonDefaultOpacity";
import { Label } from "./core/typography/Label";
import { Body as BodyText } from "./core/typography/Body";
import { withLightModalContext } from "./helpers/withLightModalContext";
import LoadingSpinnerOverlay from "./LoadingSpinnerOverlay";
import AppHeader from "./ui/AppHeader";
Expand All @@ -35,7 +41,29 @@ const styles = StyleSheet.create({
itemsCenter: { alignItems: "center" },
selfCenter: { alignSelf: "center" },
flex1: { flex: 1 },
webViewHeight: { height: heightPercentageToDP("100%") }
webViewHeight: { height: heightPercentageToDP("100%") },
errorContainer: {
flex: 1,
alignItems: "center"
},
errorTitle: {
marginTop: 10
},
errorBody: {
marginTop: 10,
marginBottom: 10,
textAlign: "center"
},
errorButtonsContainer: {
position: "absolute",
bottom: 0,
flex: 1,
flexDirection: "row"
},
cancelButtonStyle: {
flex: 1,
marginEnd: 10
}
});

const injectedJavascript = closeInjectedScript(
Expand All @@ -44,6 +72,7 @@ const injectedJavascript = closeInjectedScript(

const RegionServiceWebView: React.FunctionComponent<Props> = (props: Props) => {
const [loading, setLoading] = React.useState(false);
const [hasError, setHasError] = React.useState(false);
const ref = React.createRef<WebView>();

const urlParsed = new URLParse(props.uri, true);
Expand Down Expand Up @@ -101,6 +130,55 @@ const RegionServiceWebView: React.FunctionComponent<Props> = (props: Props) => {
</Container>
);

const onWebviewError = (_: WebViewErrorEvent) => {
setHasError(true);
setLoading(false);
};

const onWebviewHttpError = (_: WebViewHttpErrorEvent) => {
setHasError(true);
setLoading(false);
};

const renderErrorComponent = () => (
<View style={styles.errorContainer}>
<View spacer={true} extralarge={true} />
<View spacer={true} extralarge={true} />
<Image source={brokenLinkImage} resizeMode="contain" />
<Label style={styles.errorTitle} weight={"Bold"}>
{I18n.t("authentication.errors.network.title")}
</Label>

<View style={styles.errorButtonsContainer}>
<ButtonDefaultOpacity
onPress={props.onWebviewClose}
style={styles.cancelButtonStyle}
block={true}
light={true}
bordered={true}
>
<BodyText>{I18n.t("global.buttons.cancel")}</BodyText>
</ButtonDefaultOpacity>
<ButtonDefaultOpacity
onPress={handleReload}
style={{ flex: 2 }}
block={true}
primary={true}
>
<Label color={"white"}>{I18n.t("global.buttons.retry")}</Label>
</ButtonDefaultOpacity>
</View>
</View>
);

const handleReload = () => {
setHasError(false);
setLoading(true);
if (ref.current) {
ref.current.reload();
}
};

const handleWebviewMessage = (event: WebViewMessageEvent) => {
if (!event.nativeEvent.url.startsWith(urlParsed.origin)) {
return;
Expand Down Expand Up @@ -161,21 +239,27 @@ const RegionServiceWebView: React.FunctionComponent<Props> = (props: Props) => {
fromNullable(ref.current).map(wv =>
wv.injectJavaScript(injectedJavascript)
);
setLoading(false);
};

return (
<LoadingSpinnerOverlay isLoading={loading}>
<View style={{ flex: 1 }}>
<WebView
ref={ref}
source={{ uri: props.uri }}
originWhitelist={[urlParsed.origin]}
textZoom={100}
onLoadEnd={injectJS}
onMessage={handleWebviewMessage}
sharedCookiesEnabled={true}
/>
</View>
{!hasError && (
<View style={{ flex: 1 }}>
<WebView
ref={ref}
source={{ uri: props.uri }}
textZoom={100}
onLoadEnd={injectJS}
onMessage={handleWebviewMessage}
onError={onWebviewError}
onHttpError={onWebviewHttpError}
onLoadStart={() => setLoading(true)}
sharedCookiesEnabled={true}
/>
</View>
)}
{hasError && renderErrorComponent()}
</LoadingSpinnerOverlay>
);
};
Expand Down
3 changes: 2 additions & 1 deletion ts/navigation/MainNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ const NoTabBarRoutes: ReadonlyArray<string> = [
BONUSVACANZE_ROUTES.MAIN,
BPD_ROUTES.MAIN,
ROUTES.MARKDOWN_PLAYGROUND,
ROUTES.WEB_PLAYGROUND
ROUTES.WEB_PLAYGROUND,
ROUTES.SERVICE_WEBVIEW
];

const getTabBarVisibility = (
Expand Down

0 comments on commit 13d2999

Please sign in to comment.