Source

externalCode/pageScreen.js

import * as React from "react";

/**
 * @typedef {Function} PageRenderer
 * @param {Object} props Props which can be used to create a custom page renderer
 * @param {React.ComponentType<any>} component Default component used in the app
 */

/**
 * @typedef {Function} OnNavigationStateChangeCallback
 * @param {Object} navState Navigation state object from React Native WebView's onNavigationStateChange method
 */

/**
 * @typedef {Function} OnShouldStartLoadWithRequestCallback
 * @param {Number} index Web view page index
 * @param {Object} req Request object from React Native WebView's onShouldStartLoadWithRequest method
 * @param {Boolean} isLoading Returns `true` if component is currently loading
 * @param {Boolean} isFocused Returns `true` if webview is focused
 * @param {Object} currentUrl Data of current url
 * @param {Object} nextUrl Data of next url
 * @param {Function} isExternalDeeplink Helper function to determine if deep link url should be opened externally
 * @param {Function} onNext Helper function to render the new WebView and animate the current WebView out of view
 * @param {Boolean} openExternal Returns value of navigation state's `open_external` data
 * @param {Function} shouldOpenInExternalBrowser Helper function to determine if url should open in an external browser
 * @param {Boolean} isSameSite Returns `true` if the url to open has the same host name as app's server url
 * @param {Function} attemptDeepLink Helper function to attempt deep link
 */

/**
 * @class
 * App Pages Screen Hooks.
 * Instance name: pageScreenHooksApi
  
   You can use this hook to customize your app page screens by adding your component for app screens to render, disabling webkit on webview and more.
 * @example
 * externalCodeSetup.pageScreenHooksApi.METHOD_NAME
 */
export class PageScreenHooksApi {
	usePageModeTemplateHeader = true;
	useWebKit = true;

	/**
	 * @deprecated
	 */
	disablePageModeTemplateHeader = () => {
		this.usePageModeTemplateHeader = false;
	};

	/**
	 * Disable web kit on webview.
	 * For more info regarding react native webkit, see {@link https://github.com/react-native-webview/react-native-webview}
	 * @method
	 * @example
	 * externalCodeSetup.pageScreenHooksApi.disableWebKit()
	 */
	disableWebKit = () => {
		this.useWebKit = false;
	};

	// Page Screen Render Component
	PageComponent = (props, component) => component;

	/**
	 * Use your own component to render the `PageScreen` component.
	 * `PageScreen` component is usually rendered whenever a custom link or a Wordpress page is opened.
	 * @method
	 * @param {PageRenderer} PageRenderer
	 * @example <caption> Restrict PageScreen access for a user </caption>
	 * externalCodeSetup.pageScreenHooksApi.setPageComponent((props, Component) => {
	 *
	 *   if (props.user.userObject.id === 1){
	 *
	 *     return <View style={{flex: 1, alignSelf: "ce-nter", justifyContent: "center"}}>
	 *       <Text> Sorry, you do not have access this page </Text>
	 *       <Button title="Tap here to return" onPress={() => props.navigation.goBack()} />
	 *     </View>
	 *   }
	 *
	 *   return Component;
	 *
	 * })
	 */
	setPageComponent = PageRenderer => {
		this.PageComponent = PageRenderer;
	};

	onNavigationStateChange = null;

	/**
	 * You can use this to add a function that is invoked when the WebView loading starts or ends.
	 * @see {@link https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#onnavigationstatechange}
	 * @method
	 * @param {OnNavigationStateChangeCallback} onChange
	 * @example
	 * externalCodeSetup.pageScreenHooksApi.setOnNavigationStateChange(props => {
	 *   if (! props.loading && props.title){
	 *     Alert.alert(`Page title: ${props.title}`)
	 *   }
	 * });
	 */
	setOnNavigationStateChange = onChange => {
		this.onNavigationStateChange = onChange;
	};

	shouldStartLoadWithRequest = null;

	/**
	 * You can use this to add a function that allows custom handling of any web view requests.
	 * Return `true` from the function to continue loading the request and `false` to stop loading.
	 * @see {@link https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md#onshouldstartloadwithrequest}
	 * @method
	 * @param {OnShouldStartLoadWithRequestCallback} request
	 * @example <caption>Use default app's behavior when handling links in WebView </caption>
	 *
	 * externalCodeSetup.pageScreenHooksApi.setOnShouldStartLoadWithRequest(props => {
	 *
	 *   const {
	 *     index,
	 *     req,
	 *     isLoading,
	 *     isFocused,
	 *     currentUrl,
	 *     nextUrl,
	 *     isExternalDeeplink,
	 *     onNext,
	 *     openExternal,
	 *     shouldOpenInExternalBrowser,
	 *     isSameSite,
	 *     attemptDeepLink
	 *    } = props;
	 *
	 *    // If webview was not tapped, handle loading in the active webview
	 *    if (req.navigationType !== "click") {
	 *      return true;
	 *    }
	 *    // If webview is loading, handle redirection in the same webview
	 *    if (isLoading) {
	 *      return true;
	 *    }
	 *
	 *    if (!req.url) {
	 *      return true;
	 *    }
	 *
	 *    if (nextUrl.pathname === null) {
	 *      return true;
	 *    }
	 *
	 *    if (
	 *      currentUrl.pathname === nextUrl.pathname &&
	 *      currentUrl.host === nextUrl.host
	 *    ) {
	 *      return true;
	 *    }
	 *
	 *    if (! isFocused) {
	 *      return false;
	 *    }
	 *
	 *    //Use a helper function to check if url should be opened with external browser
	 *    if (isExternalDeeplink(req.url)) {
	 *      Linking.canOpenURL(req.url).then(check => {
	 *        if (check) {
	 *          Linking.openURL(req.url);
	 *        } else {
	 *          this.onNext(req.url, index);
	 *        }
	 *      });
	 *        return false;
	 *    }
	 *
	 *    if (openExternal || shouldOpenInExternalBrowser(req.url)) {
	 *      Linking.openURL(req.url).catch(err => {
	 *        console.error("An error occurred", err);
	 *        onNext(req.url, index);
	 *      });
	 *      return false;
	 *    } else if (sameSite) {
	 *      attemptDeepLink(event, req.url, index);
	 *      return false;
	 *    } else {
	 *      onNext(req.url, index);
	 *      return false;
	 *    }
	 *
	 * })
	 */
	setOnShouldStartLoadWithRequest = request => {
		this.shouldStartLoadWithRequest = request;
	};
}