react-native-webview#WebView JavaScript Examples

The following examples show how to use react-native-webview#WebView. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Dictionary.js    From duofolio with GNU General Public License v3.0 6 votes vote down vote up
function Dictionary(props) {
	return (
		<View style={styles.wrapper}>
			<WebView
				style={styles.webview}
				source={{ uri: translateUrl(props.sLang, props.tLang, props.route.params.selected) }}
			/>
		</View>
	);
}
Example #2
Source File: ContractModal.js    From haven with MIT License 6 votes vote down vote up
render() {
    const { show, onClose, orderDetails } = this.props;
    const { copied } = this.state;

    return (
      <OBLightModal
        animationType="slide"
        transparent
        visible={show}
        onRequestClose={onClose}
      >
        <Header
          left={<NavCloseButton />}
          modal
          onLeft={onClose}
          title="View Contract"
        />
        <View style={styles.webviewWrapper}>
          <WebView
            source={{ html: `<div><pre>${JSON.stringify(orderDetails, null, 2)}</pre></div>` }}
            scalesPageToFit={Platform.OS === 'android'}
            useWebKit={false}
          />
        </View>
        <Button
          title="Copy to clipboard"
          wrapperStyle={styles.buttonWrapper}
          onPress={this.handleCopy}
          style={styles.firstButton}
        />
        {copied && (
          <View style={styles.overlay}>
            <Text style={styles.overlayText}>Copied!</Text>
          </View>
        )}
      </OBLightModal>
    );
  }
Example #3
Source File: index.js    From bluezone-app with GNU General Public License v3.0 6 votes vote down vote up
render() {
    const {route} = this.props;
    const item = route.params?.item;
    const data = item?.data;

    return (
      <SafeAreaView style={{flex: 1, backgroundColor: '#ffffff'}}>
        <StatusBar hidden={true} />
        <Header
          colorIcon={'#000000'}
          styleHeader={{marginTop: 20}}
          styleTitle={{paddingHorizontal: 50}}
          title={item.title}
        />
        <WebView
          ref={this.setRef}
          source={{
            uri: data?.Link,
          }}
          javaScriptEnabled={true}
          domStorageEnabled={true}
          startInLoadingState={true}
          scalesPageToFit={false}
          thirdPartyCookiesEnabled={true}
          javaScriptEnabledAndroid={true}
          renderLoading={this.ActivityIndicatorLoadingView}
          onLoad={this.ActivityIndicatorLoadingView}
          geolocationEnabled={true}
          renderError={this.renderError}
        />
      </SafeAreaView>
    );
  }
Example #4
Source File: LocationDetailScreen.js    From react-native-booking-app with MIT License 6 votes vote down vote up
render() {
        return (
            <SafeAreaView style={styles.container}>
                <Spinner visible={this.state.loading}
                         overlayColor={{color: 'white'}}
                         color={'cadetblue'} />
                <WebView style={{ flex: 1, }}
                         source={{ uri: this.state.url }}
                         onLoad={() => (this.hideSpinner())}
                />
            </SafeAreaView>
        )
    }
Example #5
Source File: HybridWebView.js    From RRWallet with MIT License 6 votes vote down vote up
render() {
    const props = {
      ...this.props,
      style: [styles.containerWebView, this.props.webviewStyle],
      ref: this.handleWebViewRef,
      injectedJavaScript: `(${injectedScript})()`,
      userAgent: AppInfo.userAgent + ` RRWallet/${AppInfo.version}`,
      onLoadStart: this._onLoadStart,
      onLoad: this._onLoad,
      onError: this._onError,
    };
    return (
      <View style={[styles.main, this.props.style]}>
        {Platform.select({
          ios: <WebView {...props} useWebKit={true} />,
          android: <WebView {...props} />,
        })}
        <ErrorPage hidden={!this.showErrorPage} onPress={this._onErrorPagePress} />
        <ProgressHUD ref={this.handleHUDRef} />
        <MessageBox ref={ref => (this.messageBox = ref)} />
      </View>
    );
  }
Example #6
Source File: HelpWebView.js    From rakning-c19-app with MIT License 6 votes vote down vote up
HelpWebView = ({ link }) => {
  function handleStateChange({ url }) {
    if (!url) {
      return;
    }

    const isEmail = url.startsWith('mailto:');
    const isDifferent = !url.startsWith(link);
    const isSecure = url.startsWith('https:');

    if (isEmail || (isDifferent && isSecure)) {
      Linking.openURL(url);
    }
  }

  return (
    <WebView
      source={{ uri: link }}
      onNavigationStateChange={handleStateChange}
    />
  );
}
Example #7
Source File: BookingScreen.js    From react-native-booking-app with MIT License 6 votes vote down vote up
render() {
        return (
            <SafeAreaView style={styles.container}>
                <Spinner visible={this.state.loading}
                         overlayColor={{color: 'white'}}
                         color={'cadetblue'} />
                <WebView style={{ flex: 1, }}
                         source={{ uri: this.state.booking_uri }}
                         onLoad={() => (this.hideSpinner())}
                />
            </SafeAreaView>
        )
    }
Example #8
Source File: Profile.js    From devradar with MIT License 5 votes vote down vote up
function Profile({ navigation }) {
    const githubUsername = navigation.getParam('github_username')
    return <WebView style={{ flex: 1}} source={{ uri: `https://github.com/${githubUsername}` }}/>
}
Example #9
Source File: index.js    From cometchat-pro-react-native-ui-kit with MIT License 5 votes vote down vote up
render() {
    return (
      <Modal
        transparent
        animated
        animationType="fade"
        visible={this.props.open}>
        <View style={style.outerContainer}>
          <BottomSheet
            ref={this.sheetRef}
            snapPoints={[Dimensions.get('window').height - 80, 0]}
            borderRadius={30}
            initialSnap={0}
            enabledInnerScrolling={false}
            enabledContentTapInteraction={false}
            overdragResistanceFactor={10}
            renderContent={() => {
              return (
                <View style={style.bottomSheetContainer}>
                  <TouchableOpacity
                    style={style.crossImgContainer}
                    onPress={this.props.close}>
                    <Image
                      source={cross}
                      style={style.crossImg}
                      resizeMode="contain"
                    />
                  </TouchableOpacity>
                  <View style={style.outerImageContainer}>
                    {this.isLoading ? (
                      <View style={style.loaderContainer}>
                        <ActivityIndicator
                          size="large"
                          color={theme.color.primary}
                        />
                        <Text style={{ marginTop: 10 }}>Loading...</Text>
                      </View>
                    ) : null}
                    <View style={[style.mainContainer]}>
                      <WebView
                        javaScriptEnabled={true}
                        domStorageEnabled={true}
                        onError={(syntheticEvent) => {
                          const { nativeEvent } = syntheticEvent;
                          this.isLoading = false;
                          console.warn('WebView error: ', nativeEvent);
                        }}
                        onLoad={(syntheticEvent) => {
                          this.isLoading = false;
                        }}
                        onHttpError={(syntheticEvent) => {
                          const { nativeEvent } = syntheticEvent;
                          this.isLoading = false;
                          console.warn(
                            'WebView received error status code: ',
                            nativeEvent.statusCode,
                          );
                        }}
                        startInLoadingState={true}
                        style={{
                          height: '100%',
                          width: '100%',
                          borderWidth: 3,
                        }}
                        source={{ uri: this.props.url }}
                        renderError={(errorName) => <Text>errorName</Text>}
                      />
                    </View>
                  </View>
                </View>
              );
            }}
            onCloseEnd={() => {
              this.props.close();
            }}
          />
        </View>
      </Modal>
    );
  }
Example #10
Source File: Profile.js    From OmniStack-10.0 with MIT License 5 votes vote down vote up
function Profile({ navigation }) {
const githubUsername = navigation.getParam('github_username')

return <WebView style={{ flex: 1 }} source={{uri: `https://github.com/${githubUsername}` }} />
}
Example #11
Source File: Profile.js    From FinDevs with MIT License 5 votes vote down vote up
function Profile({navigation}){
  const githubUser = navigation.getParam('github_user')
  return <WebView style={{flex: 1}} source={{uri: `https://github.com/${githubUser}`}}/>
}
Example #12
Source File: Profile.js    From semana-omnistack-10 with MIT License 5 votes vote down vote up
function Profile({ navigation }) {
  const githubUsername = navigation.getParam('github_username');

  return <WebView style={{ flex: 1 }} source={{ uri: `https://github.com/${githubUsername}` }} />
}
Example #13
Source File: index.js    From guardioes-app with Apache License 2.0 5 votes vote down vote up
FAQ = () => {
    return (
        <WebView
            source={{ uri: 'https://proepi.org.br/faq-gds/' }}
            startInLoadingState
        />
    )
}
Example #14
Source File: ProductPolicy.js    From haven with MIT License 5 votes vote down vote up
render() {
    const { policy, content } = this.props;
    const { showModal, showSpinner } = this.state;
    return (
      <ProductSection>
        <OptionGroup onPress={this.handleShowModal} noBorder>
          <Text style={styles.title}>{policy}</Text>
        </OptionGroup>
        <OBLightModal
          animationType="slide"
          transparent
          visible={showModal}
          onRequestClose={this.handleHideModal}
        >
          <Header modal left={<NavCloseButton />} onLeft={this.handleHideModal} />
          {_.isEmpty(content) ? (
            this.renderEmptyContent(policy)
          ) : (
            <View style={styles.webviewWrapper}>
              <WebView
                onLoadStart={this.handleHideSpinner}
                onError={this.handleHideSpinner}
                originWhitelist={['*']}
                source={{
                  html: `${cssCode} ${content}`,
                  baseUrl: '',
                }}
                // injectedJavaScript={jsCode}
                // javaScriptEnabled
                scalesPageToFit={Platform.OS === 'android'}
                useWebKit={false}
              />
            </View>
          )}
          {!_.isEmpty(content) && showSpinner && (
            <View style={styles.activityIndicator}>
              <ActivityIndicator size="large" color="#8a8a8f" />
            </View>
          )}
        </OBLightModal>
      </ProductSection>
    );
  }
Example #15
Source File: ProductDescription.js    From haven with MIT License 5 votes vote down vote up
render() {
    const { description } = this.props;
    const { showModal, showSpinner } = this.state;

    if (_.isEmpty(description)) {
      return (
        <ProductSection>
          <Text style={styles.emptyText}>No description provided</Text>
        </ProductSection>
      );
    }

    return (
      <ProductSection>
        <Text style={styles.content} numberOfLines={3}>
          {eatSpaces(he.decode(striptags.default(description)))}
        </Text>
        <TouchableWithoutFeedback onPress={this.handleShowModal}>
          <View style={styles.showAllButton}>
            <Text style={styles.showAllText}>Read more</Text>
          </View>
        </TouchableWithoutFeedback>
        <OBLightModal
          animationType="slide"
          transparent
          visible={showModal}
          onRequestClose={this.handleHideModal}
        >
          <Header modal left={<NavCloseButton />} onLeft={this.handleHideModal} />
          <View style={styles.webviewWrapper}>
            <WebView
              onLoadStart={this.handleHideSpinner}
              onError={this.handleHideSpinner}
              originWhitelist={['*']}
              source={{
                html: `${cssCode} ${this.getHtmlContent()}`,
              }}
              scalesPageToFit={false}
              automaticallyAdjustContentInsets
              useWebKit={false}
              // injectedJavaScript={jsCode}
              // javaScriptEnabled
            />
          </View>
          {showSpinner && (
            <View style={styles.activityIndicator}>
              <ActivityIndicator size="large" color="#8a8a8f" />
            </View>
          )}
        </OBLightModal>
      </ProductSection>
    );
  }
Example #16
Source File: Profile.js    From SemanaOmnistack10 with MIT License 5 votes vote down vote up
function Profile({ navigation }){
    const github = navigation.getParam('github');
    return <WebView style={{ flex:1 }} source={{ uri: `https://github.com/${github}`}}/>;
}
Example #17
Source File: map.js    From Solution-Starter-Kit-Disasters-2020 with Apache License 2.0 5 votes vote down vote up
Map = () => {
  const webView = useRef(null);

  const onMessage = (event) => {
    const message = JSON.parse(event.nativeEvent.data);

    if (message.status && message.status === 'initialized') {
      Geolocation.getCurrentPosition((position) => {
        sendMessage(position);
      });
    }
  };

  const sendMessage = (data) => {
    const message = 
      `(function() {
        document.dispatchEvent(new MessageEvent('message', {data: ${JSON.stringify(data)}}));
      })()`;

    webView.current.injectJavaScript(message);
  }

  const sourceUri = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + 'Web.bundle/loader.html';
  const injectedJS = `
    if (!window.location.search) {
      var link = document.getElementById('progress-bar');
      link.href = './site/here.html?apikey=${hereApikey}';
      link.click();
    }
  `;

  return (
    <View style={styles.mapContainer}>
      <WebView          
        injectedJavaScript={injectedJS}
        source={{ uri: sourceUri }}
        javaScriptEnabled={true}
        originWhitelist={['*']}
        allowFileAccess={true}
        onMessage={onMessage}
        ref={webView}
      />
    </View>
  );
}
Example #18
Source File: map.js    From Solution-Starter-Kit-Cooperation-2020 with Apache License 2.0 5 votes vote down vote up
Map = (props) => {
  const webView = useRef(null);

  const onMessage = (event) => {
    const message = JSON.parse(event.nativeEvent.data);

    if (message.status && message.status === 'initialized') {
      Geolocation.getCurrentPosition((position) => {
        sendMessage(position);
      });

      if (props.route.params && props.route.params.item) {
        sendMessage({ item: props.route.params.item });
      }
    } else if (message.search) {
      search(message.search)
        .then((response) => {
          sendMessage({ search: response });
        })
        .catch(err => {
          console.log(err)
          Alert.alert('ERROR', 'Please try again. If the problem persists contact an administrator.', [{text: 'OK'}]);
        });
    }
  };

  const sendMessage = (data) => {
    const message = 
      `(function() {
        document.dispatchEvent(new MessageEvent('message', {data: ${JSON.stringify(data)}}));
      })()`;

    webView.current.injectJavaScript(message);
  }

  const sourceUri = (Platform.OS === 'android' ? 'file:///android_asset/' : '') + 'Web.bundle/loader.html';
  const injectedJS = `
    if (!window.location.search) {
      var link = document.getElementById('progress-bar');
      link.href = './site/here.html?apikey=${hereApikey}';
      link.click();
    }
  `;

  return (
    <View style={styles.mapContainer}>
      <WebView          
        injectedJavaScript={injectedJS}
        source={{ uri: sourceUri }}
        javaScriptEnabled={true}
        originWhitelist={['*']}
        allowFileAccess={true}
        onMessage={onMessage}
        ref={webView}
      />
    </View>
  );
}
Example #19
Source File: index.js    From react-native-beauty-webview with MIT License 4 votes vote down vote up
BeautyWebView = ({
  visible,
  onPressClose,
  backgroundColor,
  headerContent, // 'dark' || 'light', default 'dark'
  headerBackground, // default #fff
  url, // Required
  progressColor,
  progressHeight,
  loadingText,
  copyLinkTitle,
  openBrowserTitle,
  extraMenuItems,
  animationType,
  progressBarType, // 'normal' || 'background'
  onLoadEnd,
  onLoadStart,
  navigationVisible,
  closeIcon,
  menuIcon,
  onGoBack,
  onGoForward,
  incognito
}) => {
  const [progressRef, setProgressRef] = useState(null);
  const [backgroundProgressRef, setBackgroundProgressRef] = useState(null);
  const [title, setTitle] = useState(loadingText);
  const [backQueue, setBackQueue] = useState([]);
  const [forwardQueue, setForwardQueue] = useState([]);
  const [currentUrl, setCurrentUrl] = useState(url);

  const onProgress = (progress) => {
    progressRef?.startAnimation(progress);
    progressBarType === 'background' && backgroundProgressRef?.startAnimation(progress);
  };

  const onNavigationStateChange = (event) => {
    if (currentUrl === event.url) return;
    backQueue.push(currentUrl);
    setBackQueue(backQueue);
    onGoForward && onGoForward();
    setCurrentUrl(event.url);
  }

  const onPressBack = () => {
    if (backQueue.length == 0) return;
    const newUrl = backQueue[backQueue.length - 1];
    forwardQueue.push(currentUrl);
    setForwardQueue(forwardQueue);
    onGoBack && onGoBack();
    backQueue.pop();
    setBackQueue(backQueue);
    setCurrentUrl(newUrl);
  }

  const onPressForward = () => {
    if (forwardQueue.length == 0) return;
    const newUrl = forwardQueue[forwardQueue.length - 1];
    backQueue.push(currentUrl);
    setBackQueue(backQueue);
    forwardQueue.pop();
    setForwardQueue(forwardQueue);
    setCurrentUrl(newUrl);
    onGoForward && onGoForward();
  }

  const onClose = () => {
    onPressClose && onPressClose();
    setTimeout(() => {
      setBackQueue([]);
      setForwardQueue([]);
      setCurrentUrl(url);
    }, 200);
  } 

  return (
    <Modal visible={visible} transparent={false} animationType={animationType}>
      <SafeAreaView style={[styles.container, { backgroundColor: backgroundColor }]}>
        <Header
          backgroundColor={headerBackground}
          contentType={headerContent}
          title={title}
          url={currentUrl}
          onPressClose={onClose}
          copyLinkTitle={copyLinkTitle}
          openBrowserTitle={openBrowserTitle}
          extraMenuItems={extraMenuItems}
          backgroundProgressRefOnChange={setBackgroundProgressRef}
          navigationVisible={navigationVisible}
          canForward={forwardQueue.length > 0}
          canback={backQueue.length > 0}
          onPressBack={onPressBack}
          onPressForward={onPressForward}
          closeIcon={closeIcon}
          menuIcon={menuIcon}
        />
        {
          progressBarType === 'normal' &&
          <Progress
            height={progressHeight}
            color={progressColor}
            ref={(progress) => setProgressRef(progress)}
          />
        }
        <WebView
          source={{ uri: currentUrl }}
          onLoadProgress={({ nativeEvent }) => {
            let loadingProgress = nativeEvent.progress;
            onProgress(loadingProgress);
          }}
          injectedJavaScript="window.ReactNativeWebView.postMessage(document.title)"
          onMessage={event => setTitle(event.nativeEvent.data)}
          onLoadEnd={onLoadEnd}
          onLoadStart={onLoadStart}
          onNavigationStateChange={onNavigationStateChange}
          incognito={incognito}
        />
      </SafeAreaView>
    </Modal>
  );
}
Example #20
Source File: index.js    From tcap-mobile with GNU General Public License v3.0 4 votes vote down vote up
Details = () =>{

    const walletService = WalletService.getInstance();
    const pk = walletService.pk;    
    const accAddress = walletUtils.createAddressFromPrivateKey(pk);

    const [isActive, setIsActive] = useState(false);
    const [qrSvg , setQrSvg] = useState(undefined);

    useEffect(()=>{generateQR();},[]);

    const generateQR = async() => {
        let svg = await QRCode.toString(accAddress,{type:'terminal'});
        setQrSvg(svg);
    };

    const copyToClipboard = () =>{
        Clipboard.setString(accAddress);
        Toast.show('Address Copied to Clipboard',Toast.LONG);
    };

    const shareAddress = () =>{
        Share.share({
            message: accAddress,
        }, {
            // Android only:
            dialogTitle: 'Trustless Capital - Account Address',
            // iOS only:
            excludedActivityTypes: [
                'com.apple.UIKit.activity.PostToTwitter'
            ]
        });
    };

    const renderQrCodeBox = () =>{
        return(
            <View style={styles.bottomModal}>
                <TouchableOpacity onPress={()=>setIsActive(false)} style={{alignSelf:'flex-end',paddingHorizontal:moderateScale(8),padding:moderateScale(2)}}>
                    <Text style={{color:Colors.darkGrey}}>Done</Text>
                </TouchableOpacity>
                <Text style={{alignSelf:'center',fontSize:moderateScale(16),marginVertical:moderateScale(5),fontWeight:'bold'}}>Send To Your Wallet</Text>
                <View style={styles.barcodeBox}>
                    {(!qrSvg) && <Text>Preparing...</Text>}
                    {
                        (qrSvg) && 
                            <WebView  source={{ html: qrSvg }} style={{width:moderateScale(250),height:250,}} />
                    }
                </View>
                <TouchableOpacity onPress={()=>copyToClipboard()}>
                    <Text style={{...styles.accAddressText,color:Colors.darkGrey,alignSelf:'center',marginTop:moderateScale(10)}}>Account Addess</Text>
                    <Text style={{...styles.titleBar_title,maxWidth:moderateScale(200),color:Colors.darkGrey,alignSelf:'center',textAlign:'center'}}>{accAddress}</Text>
                </TouchableOpacity>
                <TouchableOpacity onPressOut={()=>shareAddress()} style={styles.shareButton}>
                    <Text style={{color:Colors.white}}>Share</Text>
                </TouchableOpacity>
            </View>
        );
    };
    
    return(
        <View style={{...styles.boxWrapper,justifyContent:'center',alignItems:'center'}}>
            <Text style={styles.accAddressText}>Account Addess</Text>
            <Text ellipsizeMode={'middle'} numberOfLines={1} style={{...styles.titleBar_title,maxWidth:moderateScale(100)}}>{accAddress}</Text>
            <View style={styles.buttonWrappers}>
                <TouchableOpacity onPress={()=>copyToClipboard()} style={styles.buttons}>
                    <Icon name={'copy'} size={moderateScale(16)} />
                    <Text style={styles.buttonText}>Copy</Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={()=>setIsActive(true)} style={styles.buttons}>
                    <Icon name={'qrcode'} size={moderateScale(16)} />
                    <Text style={styles.buttonText}>Receive</Text>
                </TouchableOpacity>
            </View>
            <Modal
                animationIn={'slideInUp'}
                animationOut={'slideOutDown'}
                backdropColor={'#000'}
                dismissable={true}
                isVisible={isActive}
                onBackButtonPress={()=>setIsActive(false)}
                onBackdropPress={()=>setIsActive(false)}
                style={{padding:0,margin:0}}
                useNativeDriver={true}
            >
                {renderQrCodeBox()}
            </Modal>
        </View>
    );
}
Example #21
Source File: PdfReader.js    From duofolio with GNU General Public License v3.0 4 votes vote down vote up
function PdfReader(props) {
	const [state, setState] = useState({ docUrl: null, server: null });
	const [isDrawer, setDrawer] = useState(false);
	// const [searchResults, setSearchResults] = useState(null);
	const [selectedText, setSelectedText] = useState('');
	const [isModal, setModal] = useState(false);

	const webview = useRef();
	const { params } = props.route;
	const { progress, totalPages } = props.books[params.index];

	useLayoutEffect(() => {
		props.navigation.setOptions({
			headerRight: () => (
				<View style={styles.iconWrapper}>
					<Icon
						name="g-translate"
						type="material"
						size={21}
						color={props.settings.fg}
						style={styles.headerIcon}
						onPress={onTranslation}
					/>
					<Icon
						name="menu"
						size={20}
						color={props.settings.fg}
						style={styles.headerIcon}
						onPress={() => setDrawer(!isDrawer)}
					/>
				</View>
			)
		});
	}, [props.navigation, isDrawer, selectedText]);

	useEffect(() => {
		showToast('Opening book');
		let newServer = new StaticServer(0, ExternalStorageDirectoryPath, serverConfig);
		newServer.start().then((url) =>
			setState({
				docUrl: url + params.url.replace(ExternalStorageDirectoryPath, ''),
				server: newServer
			})
		);
		return () => {
			props.sortBook(params.index);
			state.server && state.server.stop();
		};
	}, []);

	let injectedJS = `window.DOC_PATH = "${state.docUrl}";`;

	if (progress) {
		injectedJS = `${injectedJS}
		window.pageNum = ${progress};
		`;
	}

	function goPrev() {
		webview.current?.injectJavaScript(`
		if (window.pageNum > 1) {
			window.pageNum--;
			window.queueRenderPage(window.pageNum);
		}`);
	}

	function goNext() {
		webview.current?.injectJavaScript(`
		if (window.pageNum < pdfDoc.numPages) {
			window.pageNum++;
			window.queueRenderPage(window.pageNum);
		}`);
	}

	function goToLocation(pageNum) {
		if (pageNum >= 1 && pageNum <= totalPages) {
			props.addMetadata({ progress: pageNum }, params.index);
			webview.current?.injectJavaScript(`
			window.pageNum = ${pageNum};
			window.queueRenderPage(${pageNum});`);
		}
	}

	function onTranslation() {
		props.navigation.navigate('dictionary', { selected: selectedText });
		// setTimeout(refresh, 200);
	}

	function handleMessage(e) {
		let parsedData = JSON.parse(e.nativeEvent.data);
		let { type } = parsedData;
		delete parsedData.type;
		switch (type) {
			case 'selected': {
				setSelectedText(parsedData.selected);
				if (parsedData.selected.length < 40) setModal(true);
				return;
			}
			case 'loc': {
				return props.addMetadata(parsedData, params.index);
			}
			default:
				return;
		}
	}

	if (!state.docUrl) {
		return <Spinner fg={props.settings.fg} bg={props.settings.bg} />;
	}
	const menu = (
		<Drawer
			index={params.index}
			// goToLocation={goToLocation}
			// onSearch={onSearch}
			// searchResults={searchResults}
		/>
	);
	return (
		<SideMenu menu={menu} isOpen={isDrawer} menuPosition="right" onChange={setDrawer}>
			<WebView
				ref={webview}
				style={[styles.wholeScreen, { backgroundColor: props.settings.bg }]}
				source={{ uri: 'file:///android_asset/pdf.html' }}
				injectedJavaScriptBeforeContentLoaded={injectedJS}
				onMessage={handleMessage}
			/>
			<Footer goNext={goNext} goPrev={goPrev} goToLocation={goToLocation} index={params.index} />
			{isModal && (
				<DictionaryModal
					isVisible={isModal}
					selected={selectedText}
					hide={() => setModal(false)}
					onTranslation={onTranslation}
				/>
			)}
		</SideMenu>
	);
}
Example #22
Source File: EpubReader.js    From duofolio with GNU General Public License v3.0 4 votes vote down vote up
function EpubReader(props) {
	const [state, setState] = useState({ bookUrl: null, server: null });
	const [isDrawer, setDrawer] = useState(false);
	const [searchResults, setSearchResults] = useState(null);
	const [selectedText, setSelectedText] = useState('');
	const [isModal, setModal] = useState(false);

	const webview = useRef();
	const { params } = props.route;
	const currentLocation = props.locations[props.books[params.index].key];
	const bookLocations = props.books[params.index].locations;
	const { bg, fg, size, height } = props.settings;

	useLayoutEffect(() => {
		props.navigation.setOptions({
			headerRight: () => (
				<View style={styles.iconWrapper}>
					<Icon
						name="g-translate"
						type="material"
						size={21}
						color={props.settings.fg}
						style={styles.headerIcon}
						onPress={onTranslation}
					/>
					<Icon
						name="menu"
						size={20}
						color={props.settings.fg}
						style={styles.headerIcon}
						onPress={() => setDrawer(!isDrawer)}
					/>
				</View>
			)
		});
	}, [props.navigation, isDrawer, selectedText]);

	useEffect(() => {
		showToast('Opening book');
		let newServer = new StaticServer(0, ExternalStorageDirectoryPath, serverConfig);
		newServer.start().then((url) =>
			setState({
				bookUrl: url + params.url.replace(ExternalStorageDirectoryPath, ''),
				server: newServer
			})
		);
		return () => {
			props.sortBook(params.index);
			state.server && state.server.stop();
		};
	}, []);

	useEffect(() => {
		webview.current?.injectJavaScript(`
		window.rendition.themes.register({ theme: "${JSON.stringify(themeToStyles(props.settings))}" });
		window.rendition.themes.select('theme');`);
		refresh();
		StatusBar.setBackgroundColor(props.settings.bg, true);
		StatusBar.setBarStyle(`${props.settings.fg === '#000000' ? 'dark' : 'light'}-content`);
	}, [bg, fg, size, height]);

	let injectedJS = `window.BOOK_PATH = "${state.bookUrl}";
	window.LOCATIONS = ${bookLocations};
	window.THEME = ${JSON.stringify(themeToStyles(props.settings))};
	`;

	if (currentLocation) {
		injectedJS = `${injectedJS}
		window.BOOK_LOCATION = '${currentLocation}';
		`;
	}

	function goPrev() {
		webview.current?.injectJavaScript(`window.rendition.prev()`);
	}

	function goNext() {
		webview.current?.injectJavaScript(`window.rendition.next()`);
	}

	function goToLocation(href) {
		webview.current?.injectJavaScript(`window.rendition.display('${href}')`);
		isDrawer && setDrawer(false);
	}

	function refresh() {
		webview.current?.injectJavaScript(`window.BOOK_LOCATION = "${currentLocation}"`);
		webview.current?.reload();
	}

	function onTranslation() {
		props.navigation.navigate('dictionary', { selected: selectedText });
		setTimeout(refresh, 200);
	}

	function onSearch(q) {
		webview.current?.injectJavaScript(`
		Promise.all(
			window.book.spine.spineItems.map((item) => {
				return item.load(window.book.load.bind(window.book)).then(() => {
					let results = item.find('${q}'.trim());
					item.unload();
					return Promise.resolve(results);
				});
			})
		).then((results) =>
			window.ReactNativeWebView.postMessage(
				JSON.stringify({ type: 'search', results: [].concat.apply([], results) })
			)
		)`);
	}

	function handleMessage(e) {
		let parsedData = JSON.parse(e.nativeEvent.data);
		let { type } = parsedData;
		delete parsedData.type;
		switch (type) {
			case 'selected': {
				setSelectedText(parsedData.selected);
				if (parsedData.selected.length < 40) setModal(true);
				return;
			}
			case 'loc': {
				const { progress, totalPages } = parsedData;
				props.addMetadata({ progress, totalPages }, params.index);
				delete parsedData.progress;
				delete parsedData.totalPages;
				return props.addLocation(parsedData);
			}
			case 'key':
			case 'metadata':
			case 'contents':
			case 'locations':
				return props.addMetadata(parsedData, params.index);
			case 'search':
				return setSearchResults(parsedData.results);
			default:
				return;
		}
	}

	if (!state.bookUrl) {
		return <Spinner fg={props.settings.fg} bg={props.settings.bg} />;
	}
	const menu = (
		<Drawer
			index={params.index}
			goToLocation={goToLocation}
			onSearch={onSearch}
			searchResults={searchResults}
		/>
	);
	return (
		<SideMenu menu={menu} isOpen={isDrawer} menuPosition="right" onChange={setDrawer}>
			<WebView
				ref={webview}
				style={[styles.wholeScreen, { backgroundColor: props.settings.bg }]}
				source={{ uri: 'file:///android_asset/epub.html' }}
				injectedJavaScriptBeforeContentLoaded={injectedJS}
				onMessage={handleMessage}
			/>
			<Footer
				goNext={goNext}
				goPrev={goPrev}
				locations={bookLocations}
				goToLocation={goToLocation}
				index={params.index}
			/>
			{isModal && (
				<DictionaryModal
					isVisible={isModal}
					selected={selectedText}
					hide={() => setModal(false)}
					onTranslation={onTranslation}
				/>
			)}
		</SideMenu>
	);
}
Example #23
Source File: Search.js    From Turbo-Browser with MIT License 4 votes vote down vote up
Search = ({ navigation, route }) => {

  const styleTypes = ['default','dark-content', 'light-content'];
  const [styleStatusBar, setStyleStatusBar] = useState(styleTypes[1]);

  const [rippleOverflow, setRippleOverflow] = useState(false);

  const [canGoBack, setCanGoBack] = useState(false);
  const [canGoForward, setCanGoForward] = useState(false);
  const [currentUrl, setCurrentUrl] = useState("");

  const [WebL, setWebL] = useState(true);
  const [cUrl, setCUrl] = useState((route.params.name).replace("turbo/", ""));
  const [httpS, setHttpS] = useState(2);
  const [favIcon, setFavIcon] = useState("");
  const [webTS, setWebTS] = useState((route.params.name).replace("turbo/", "").split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
  const [titleCurrent, setTitleCurrent] = useState("");

  const [webViewShow, setWebViewShow] = useState(false);
  const [fullscreen, setFullscreen] = useState(false);
  const [f2, setF2] = useState(false);

  const BottomNavOpacity = useRef(new Animated.Value(1)).current;

  const [optionsAlertOpen, setOptionsAlertOpen] = useState(false);
  const [copiedText, setCopiedText] = useState('');

  const [searchAlertOpen, setSearchAlertOpen] = useState(false);

  const INJECTEDJAVASCRIPT = `
  const meta = document.createElement('meta'); meta.setAttribute('content', 'initial-scale=1.0, maximum-scale=1.0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta);
  
  var links = document.links, i, length;
  for (i = 0, length = links.length; i < length; i++) {
      links[i].target == '_blank' && links[i].removeAttribute('target');
  }
  
  window.ReactNativeWebView.postMessage(document.title);
  `;

  const inputRef = React.useRef();
  const webviewRef = useRef(null);

  const [searchOpen, setSearchOpen] = useState(false);
  const [searchValue, setSearchValue] = useState("");

  const [bookmarksKeyValue, setBookmarksKeyValue] = useState("");

  const appInfo = useSelector((state) => state.appInfo);

  useEffect(() => {
    Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
    Keyboard.addListener("keyboardDidHide", _keyboardDidHide);

    // cleanup function
    return () => {
      Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
      Keyboard.removeListener("keyboardDidHide", _keyboardDidHide);
    };
  }, []);

  const speechToTextHandler = async () => {
    let speechToTextData = null;
    try {
      speechToTextData = await SpeechToText.startSpeech('Try saying something', 'en_IN');
      searchStringS(speechToTextData);
    } catch (error) {
      // error
    }
  }

  const _keyboardDidShow = () => {
    if(route.name == "Search"){
      setF2(true);
    } else {
      // Do nothing
    }
  };

  const _keyboardDidHide = () => {
    if(route.name == "Search"){
      setF2(false);
    } else {
      // Do nothing
    }
  };

  const showToast = () => {
    ToastAndroid.show("URL copied", ToastAndroid.SHORT);
  };

  useEffect(() => {
    setTimeout(() => {
      setWebViewShow(true);
    }, 600);
  }, []);

  const se1 = () => {
    if (webviewRef.current){
      if(canGoBack) {
        webviewRef.current.goBack();
      } else {
        navigation.goBack();
      }
    }
  }

  const se2 = () => {
    if (webviewRef.current) webviewRef.current.goForward();
  }

  const se3 = () => {
    navigation.navigate('Home', { name: "Home" });
  }

  const setHttpIcon = () => {
    if(cUrl.substring(0, 5) == "https") {
      setHttpS(1);
    } else if (cUrl.substring(0, 5) == "http:") {
      setHttpS(2);
    } else {
      setHttpS(3);
    }
  }

  const getBookmarkValue = async () => {
    try {
      const value = await AsyncStorage.getItem("bookmarksKey")
      if(value !== null) {
        // value previously stored
        setBookmarksKeyValue(value);
      } else {
        setBookmarksKeyValue("");
      }
    } catch(e) {
      // error
    }
  }

  const saveBookmarkValue = async () => {
    try {
      const value = await AsyncStorage.getItem("bookmarksKey")
      if(value !== null) {
        // value previously stored
        await AsyncStorage.setItem("bookmarksKey", value + "~" + currentUrl);
        setBookmarksKeyValue(value + "~" + currentUrl);
      } else {
        await AsyncStorage.setItem("bookmarksKey", currentUrl + "~");
        setBookmarksKeyValue(currentUrl + "~");
      }
    } catch(e) {
      // error
    }
  }

  useEffect(() => {
    navigation.addListener('focus',
    () => {

      let urlToOpen = (route.params.name).replace("turbo/", "");
      setCurrentUrl(urlToOpen);

      setWebTS(urlToOpen.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
      setHttpS(2);
      setF2(false);

      getBookmarkValue();

    }
    );
  }, []);

  const refreshWeb = () => {
    if (webviewRef.current) webviewRef.current.reload();
  }

  const onMessage = async (message) => {
    setTitleCurrent(message.nativeEvent.data);
    if(message.nativeEvent.data !== ""){
      let objectToSet = {
        name: message.nativeEvent.data,
        url: message.nativeEvent.url
      }
      let valueToSet = JSON.stringify(objectToSet);
      await AsyncStorage.setItem("lastSearchedWeb", valueToSet);
    }
  }

  const handleFullScrTouch = () => {
    if(fullscreen){
      setFullscreen(false);
      Animated.timing(
        BottomNavOpacity,
        {
          toValue: 0,
          duration: 0,
          useNativeDriver: true,
        }
        ).start();
      setTimeout(() => {
        Animated.timing(
          BottomNavOpacity,
          {
            toValue: 1,
            duration: appInfo.animations == false ? 0 : 200,
            useNativeDriver: true,
          }
          ).start();
      }, 200);
    } else {
      setFullscreen(true);
      Animated.timing(
      BottomNavOpacity,
      {
        toValue: 0,
        duration: appInfo.animations == false ? 0 : 100,
        useNativeDriver: true,
      }
      ).start();
    }
  }

  const se4 = () => {
    saveBookmarkValue();
  }

  const se5 = () => {
    setOptionsAlertOpen(true);
  }

  const onShare = async () => {
    try {
      const result = await Share.share({
        message: currentUrl,
      });
      if (result.action === Share.sharedAction) {
        if (result.activityType) {
          // shared with activity type of result.activityType
        } else {
          // shared
        }
      } else if (result.action === Share.dismissedAction) {
        // dismissed
      }
    } catch (error) {
      // error
    }
  };

  const copyToClipboard = () => {
    Clipboard.setString(currentUrl);
  };

  const onSearchChangeText = (text) => {
    setSearchValue(text);
  }

  const saveHistory = async () => {
    if(currentUrl !== "about:blank" || currentUrl !== "" || currentUrl.includes("~"))
    try {
      const value = await AsyncStorage.getItem("historyKey");
      if(value !== null) {
        // value previously stored
        if(value.includes("~")){
          await AsyncStorage.setItem("historyKey", currentUrl + "~" + value);
        } else {
          await AsyncStorage.setItem("historyKey", currentUrl + "~" + value);
        }
      } else {
        await AsyncStorage.setItem("historyKey", currentUrl);
      }
    } catch (error) {
      // error
    }
  }

  const searchStringS = (string) => {

    if(string == ""){

    } else if (string.substring(0, 8) == "https://" || string.substring(0, 7) == "http://") {
      setCurrentUrl(string);
    } else {

      // openWebsite("https://www.google.com/search?q=" + string.replace(/ /g,"+"));

      if(appInfo.searchEngine == "Google"){
        setCurrentUrl("https://www.google.com/search?q=" + string.replace(/ /g,"+"));
      } else if (appInfo.searchEngine == "DuckDuckGo") {
        openWebsite("https://duckduckgo.com/?q=" + string.replace(/ /g,"+"));
      } else if (appInfo.searchEngine == "Bing") {
        setCurrentUrl("https://www.bing.com/search?q=" + string.replace(/ /g,"+"));
      } else if (appInfo.searchEngine == "Yahoo!") {
        setCurrentUrl("https://in.search.yahoo.com/search?p=" + string.replace(/ /g,"+"));
      } else {
        setCurrentUrl("https://www.google.com/search?q=" + string.replace(/ /g,"+"));
      }

    }

  }

  const voiceSearchBtnClk = () => {
    speechToTextHandler();
    setSearchAlertOpen(false);
    setSearchOpen(false);
  }

  const se4Remove = async () => {
    try {
      const value = await AsyncStorage.getItem("bookmarksKey");
      const newValue = value.split(currentUrl).join("");
      await AsyncStorage.setItem("bookmarksKey", newValue);
      setBookmarksKeyValue(newValue);
    } catch(e) {
      // error
    }
  }

  return (
    <SafeAreaView>

    <StatusBar backgroundColor="#ffffff" barStyle={styleStatusBar} />

    <Modal
      isOpen={searchAlertOpen}
      onClosed={() => {
        setSearchAlertOpen(false);
        setSearchOpen(false);
      }}
      style={[styles.modal, styles.modal12]} 
      entry={"top"}
      position={"top"} 
      backdropPressToClose={true} 
      swipeToClose={false}
      backdropOpacity={0.4} 
      backButtonClose={true}
      coverScreen={true} 
      animationDuration={200}
    >
      <View style={styles.view__2}>
      <View style={{borderRadius: 40, overflow: 'hidden'}}>
      {/* <TouchableOpacity
      style={{width: "100%"}}
      > */}
      <View style={styles.view_input_c_1}>

      <IonicIcon style={styles.search_icon} name="search"/>

      <TextInput
        ref={inputRef}
        style={{
          // maxWidth: 200,
          fontSize: 14,
          color: "#5B5D5DFF",
          marginLeft: 8,
          fontFamily: "Helvetica",
          flexGrow: 1,
        }}
        value={searchValue}
        onChangeText={(text) => onSearchChangeText(text)}
        autoFocus={true}
        editable={searchOpen}
        onSubmitEditing={() => {
          setSearchAlertOpen(false);
          setSearchOpen(false);
          searchStringS(searchValue);
        }}
        placeholderTextColor="#CECFCFFF"
        placeholder="Search Google"
      />

      {
        searchValue.length > 0 ?
        <IonicIcon onPress={() => setSearchValue("")} style={styles.mic_icon} name="close"/>
        :
        <IonicIcon onPress={voiceSearchBtnClk} style={styles.mic_icon} name="mic"/>
      }

      </View>
      {/* </TouchableOpacity> */}
      </View>
      </View>

    </Modal>

    <Modal
      isOpen={optionsAlertOpen} 
      onClosed={() => {setOptionsAlertOpen(false)}} 
      style={[styles.modal, styles.modal8]} 
      position={"bottom"} 
      backdropPressToClose={true} 
      swipeToClose={false}
      backdropOpacity={0.2} 
      backButtonClose={true}
      coverScreen={true} 
      animationDuration={200}
    >
      <View style={styles.optionAlertCont_MAIN}>

        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            copyToClipboard();
            showToast();
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Copy URL
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            setTimeout(() => {
              onShare();
            }, 320);
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Share
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            setCurrentUrl("view-source:" + currentUrl);
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              View page source
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            navigation.navigate('Bookmarks', { name: "Home" });
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Bookmarks
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            navigation.navigate('History', { name: "Home" });
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              History
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            navigation.navigate('Settings', { name: "Home" });
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Settings
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            setCurrentUrl("https://turbo-browser.netlify.app/privacy-policy.html");
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Privacy Policy
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1_B}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            navigation.navigate('Help', { name: "Home" });
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
            FAQs
            </Text>
          </TouchableOpacity>
        </View>

        <View style={styles.optionAlertCont_opt_icon_1}>
          <TouchableOpacity style={{
            width: "100%",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            paddingBottom: 10,
            marginBottom: 4,
          }} onPress={() => {setOptionsAlertOpen(false)}}>
            {/* <FontAwesome style={styles.optionAlertCont_opt_icon_2} name="chevron-down"/> */}
            <Image 
              source={require("../assets/arrowDown2.png")} 
              style={{
                height: 26,
                width: 26,
              }}
            />
          </TouchableOpacity>
        </View>
        
      </View>
    </Modal>

    <View style={styles.searchMainContainer}>
        
      {/* Search 1 */}
      <View style={styles.search_1}>
        {
          currentUrl.includes("view-source:") ?
          <View style={styles.sea1__1}>
          <Image

            style={styles.sea1__1A}

            source={(favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.nytimes.com/") ? require("../assets/ny.png") :

            favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.google.com/") ? require("../assets/googleIcon.png") :

            {uri: favIcon})}
            
          />
          </View>
          :
          <View style={styles.sea1__1}>
            {WebL ?
              <ActivityIndicator size="small" style={{
                height: 16,
                width: 16,
                resizeMode: "cover",
                marginLeft: 8,
                marginRight: 8,
              }} color={'#8F8D8DFE'} />
              :
              <Image

                style={styles.sea1__1A}

                source={(favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.nytimes.com/") ? require("../assets/ny.png") :

                favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.google.com/") ? require("../assets/googleIcon.png") :

                {uri: favIcon})}

              />
            }
          </View>
        }

        <View style={{
          height: 30,
          borderRadius: 30,
          flexGrow: 1,
          overflow: "hidden",
        }}>
        <TouchableNativeFeedback
          background={TouchableNativeFeedback.Ripple("#AEAEAEFF", rippleOverflow)}
          onPress={() => {
            setSearchAlertOpen(true);
            setSearchValue("");
            setTimeout(() => {
              setSearchOpen(true);
              inputRef.current?.focus();
            }, 400);
          }}
        >
          <View style={styles.sea1__2}>
            <View style={styles.sea1__2A}>
              {
                (httpS == 1) ?
                <MaterialIcons style={styles.sea1__2A_icon1} name="https"/>
                : (httpS == 2) ?
                <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
                : (httpS == 3) ?
                <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
                : <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
              }
            </View>
            <View style={styles.sea1__2B}>
              <Text style={styles.sea1__2B_txt}>
                {currentUrl.replace("turbo/", "").split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]}
              </Text>
            </View>
            <TouchableOpacity onPress={refreshWeb}>
            <View style={styles.sea1__2C}>
              <MaterialIcons style={styles.sea1__2C_icon} name="replay"/>
            </View>
            </TouchableOpacity>
          </View>
        </TouchableNativeFeedback>
        </View>

        <View style={styles.sea1__3}>
        <TouchableOpacity onPress={handleFullScrTouch}>
          {/* <MaterialIcons style={styles.sea1__3_icon} name="more-vert"/> */}
          {
            fullscreen ?
            <MaterialIcons style={styles.sea1__3_icon} name="fullscreen-exit"/>
            :
            <MaterialIcons style={styles.sea1__3_icon} name="fullscreen"/>
          }
        </TouchableOpacity>
        </View>
      </View>

      {/* Search 2 */}
      <View style={styles.search_2}>
        {
          webViewShow ?
          <WebView
            startInLoadingState={true}
            ref={webviewRef}
            source={{
              uri: currentUrl,
            }}
            onNavigationStateChange={navState => {
              setCanGoBack(navState.canGoBack);
              setCanGoForward(navState.canGoForward);
              setCUrl(navState.url);
              // setWebTS(cUrl.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
            }}
            allowFileAccess={true}
            geolocationEnabled={true}
            showsHorizontalScrollIndicator={false}
            showsVerticalScrollIndicator={false}
            injectedJavaScript={INJECTEDJAVASCRIPT}
            onLoadStart={() => {
              setWebL(true);
            }}
            onLoadEnd={() => {
              setFavIcon("https://api.statvoo.com/favicon/?url=" + cUrl);
              setWebL(false);
              setHttpIcon();
              setWebTS(cUrl.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
              saveHistory();
            }}
            userAgent="Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36"
            onMessage={onMessage}
            javaScriptEnabled={appInfo.disableJS == true ? false : true}
            domStorageEnabled={appInfo.disableCookies == true ? false : true}
          />
          : <></>
        }
      </View>

      {/* Search 3 */}
      {
        fullscreen || f2 ?
        <></>
        :
        <Animated.View
          style={{
            opacity: BottomNavOpacity
          }}
        >
        <View style={styles.search_3}>
        <TouchableOpacity onPress={se1} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="chevron-back-outline"/>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={se2} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="chevron-forward-outline"/>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={se3} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="home-outline"/>
          </View>
        </TouchableOpacity>
        {
          bookmarksKeyValue.includes(currentUrl) ?
          <TouchableOpacity onPress={se4Remove} style={styles.sea_3_item}>
            <View>
              <IonicIcon style={styles.sea3__3_icon_r} name="heart"/>
            </View>
          </TouchableOpacity>
          :
          <TouchableOpacity onPress={se4} style={styles.sea_3_item}>
            <View>
              <IonicIcon style={styles.sea3__3_icon_r} name="heart-outline"/>
            </View>
          </TouchableOpacity>
        }
        {/* <TouchableOpacity onPress={se4} style={styles.sea_3_item}>
          <View>
            {
              bookmarksKeyValue.includes(currentUrl) ?
              <IonicIcon style={styles.sea3__3_icon_r} name="heart"/>
              :
              <IonicIcon style={styles.sea3__3_icon} name="heart-outline"/>
            }
          </View>
        </TouchableOpacity> */}
        <TouchableOpacity onPress={se5} style={styles.sea_3_item}>
          {/* Future Tab Feature */}
          {/* <View style={{justifyContent: "center", alignItems: "center"}}>
            <View style={{
              height: 17,
              width: 17,
              borderWidth: 1.6,
              borderRadius: 4,
              borderColor: "#767778FE",
              alignItems: "center",
              justifyContent: "center",
            }}>
              <Text style={{
                color: "#767778FE",
                fontSize: 10,
                textAlign: "center",
                fontWeight: "bold",
              }}>
                1
              </Text>
            </View>
          </View> */}
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="grid-outline"/>
          </View>
        </TouchableOpacity>
        </View>
        </Animated.View>
      }
        
    </View>
        
    </SafeAreaView>
  );

}
Example #24
Source File: IncognitoSearch.js    From Turbo-Browser with MIT License 4 votes vote down vote up
IncognitoSearch = ({ navigation, route }) => {

  const styleTypes = ['default','dark-content', 'light-content'];
  const [styleStatusBar, setStyleStatusBar] = useState(styleTypes[2]);

  const [rippleOverflow, setRippleOverflow] = useState(false);

  const [canGoBack, setCanGoBack] = useState(false);
  const [canGoForward, setCanGoForward] = useState(false);
  const [currentUrl, setCurrentUrl] = useState("");

  const [WebL, setWebL] = useState(true);
  const [cUrl, setCUrl] = useState((route.params.name).replace("turbo/", ""));
  const [httpS, setHttpS] = useState(2);
  const [favIcon, setFavIcon] = useState("");
  const [webTS, setWebTS] = useState((route.params.name).replace("turbo/", "").split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);

  const [webViewShow, setWebViewShow] = useState(false);
  const [fullscreen, setFullscreen] = useState(false);
  const [f2, setF2] = useState(false);

  const BottomNavOpacity = useRef(new Animated.Value(1)).current;

  const [optionsAlertOpen, setOptionsAlertOpen] = useState(false);

  const [searchAlertOpen, setSearchAlertOpen] = useState(false);

  const INJECTEDJAVASCRIPT = `
  const meta = document.createElement('meta'); meta.setAttribute('content', 'initial-scale=1.0, maximum-scale=1.0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta);
  
  var links = document.links, i, length;
  for (i = 0, length = links.length; i < length; i++) {
      links[i].target == '_blank' && links[i].removeAttribute('target');
  }
  
  window.ReactNativeWebView.postMessage(document.title);
  `;

  const inputRef = React.useRef();
  const webviewRef = useRef(null);

  const [searchOpen, setSearchOpen] = useState(false);
  const [searchValue, setSearchValue] = useState("");

  const [bookmarksKeyValue, setBookmarksKeyValue] = useState("");

  const appInfo = useSelector((state) => state.appInfo);

  useEffect(() => {
    Keyboard.addListener("keyboardDidShow", _keyboardDidShow);
    Keyboard.addListener("keyboardDidHide", _keyboardDidHide);

    // cleanup function
    return () => {
      Keyboard.removeListener("keyboardDidShow", _keyboardDidShow);
      Keyboard.removeListener("keyboardDidHide", _keyboardDidHide);
    };
  }, []);

  const speechToTextHandler = async () => {
    showToast4();
  }

  const _keyboardDidShow = () => {
    if(route.name == "IncognitoSearch"){
      setF2(true);
    } else {
      // Do nothing
    }
  };

  const _keyboardDidHide = () => {
    if(route.name == "IncognitoSearch"){
      setF2(false);
    } else {
      // Do nothing
    }
  };

  const showToast = () => {
    ToastAndroid.show("URL copied", ToastAndroid.SHORT);
  };

  const showToast2 = () => {
    ToastAndroid.show("You can't set bookmarks on Incognito mode", ToastAndroid.SHORT);
  };

  const showToast4 = () => {
    ToastAndroid.show("You can't use Voice Search on Incognito mode", ToastAndroid.SHORT);
  };

  useEffect(() => {
    setTimeout(() => {
      setWebViewShow(true);
    }, 100);
  }, [])

  const se1 = () => {
    if (webviewRef.current){
      if(canGoBack) {
        webviewRef.current.goBack();
      } else {
        navigation.goBack();
      }
    }
  }

  const se2 = () => {
    if (webviewRef.current) webviewRef.current.goForward();
  }

  const se3 = () => {
    navigation.navigate('Home', { name: "Home" });
  }

  const setHttpIcon = () => {
    if(cUrl.substring(0, 5) == "https") {
      setHttpS(1);
    } else if (cUrl.substring(0, 5) == "http:") {
      setHttpS(2);
    } else {
      setHttpS(3);
    }
  }

  useEffect(() => {
    navigation.addListener('focus',
    () => {
      let urlToOpen = (route.params.name).replace("turbo/", "");
      setCurrentUrl(urlToOpen);
      setWebTS(urlToOpen.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
      setHttpS(2);
      setF2(false);
    }
    );
  }, []);

  const refreshWeb = () => {
    if (webviewRef.current) webviewRef.current.reload();
  }

  const handleFullScrTouch = () => {
    if(fullscreen){
      setFullscreen(false);
      Animated.timing(
        BottomNavOpacity,
        {
          toValue: 0,
          duration: 0,
          useNativeDriver: true,
        }
        ).start();
      setTimeout(() => {
        Animated.timing(
          BottomNavOpacity,
          {
            toValue: 1,
            duration: 200,
            useNativeDriver: true,
          }
          ).start();
      }, 200);
    } else {
      setFullscreen(true);
      Animated.timing(
      BottomNavOpacity,
      {
        toValue: 0,
        duration: 100,
        useNativeDriver: true,
      }
      ).start();
    }
  }

  const se4 = () => {
    showToast2();
  }

  const se5 = () => {
    setOptionsAlertOpen(true);
  }

  const onShare = async () => {
    try {
      const result = await Share.share({
        message: currentUrl,
      });
      if (result.action === Share.sharedAction) {
        if (result.activityType) {
          // shared with activity type of result.activityType
        } else {
          // shared
        }
      } else if (result.action === Share.dismissedAction) {
        // dismissed
      }
    } catch (error) {
      // error
    }
  };

  const copyToClipboard = () => {
    Clipboard.setString(currentUrl);
  };

  const onSearchChangeText = (text) => {
    setSearchValue(text);
  }

  const searchStringS = (string) => {

    if(string == ""){

    } else if (string.substring(0, 8) == "https://" || string.substring(0, 7) == "http://") {
      setCurrentUrl(string);
    } else {

      setCurrentUrl("https://duckduckgo.com/?q=" + string.replace(/ /g,"+"));

    }

  }

  const voiceSearchBtnClk = () => {
    speechToTextHandler();
    setSearchAlertOpen(false);
    setSearchOpen(false);
  }

  const se4Remove = async () => {
    showToast2();
  }

  useEffect(() => {

    navigation.addListener('focus',
    () => {
      
      changeNavigationBarColor("#1C2124", false, true);

    }
    );

    navigation.addListener('blur',
      () => {
        
        changeNavigationBarColor("#FFFFFF", true, true);

      }
    );

  }, []);

  return (
    <SafeAreaView>

    <StatusBar backgroundColor="#1C2124FF" barStyle={styleStatusBar} />

    <Modal
      isOpen={searchAlertOpen}
      onClosed={() => {
        setSearchAlertOpen(false);
        setSearchOpen(false);
      }}
      style={[styles.modal, styles.modal12]} 
      entry={"top"}
      position={"top"} 
      backdropPressToClose={true} 
      swipeToClose={false}
      backdropOpacity={0.6} 
      backButtonClose={true}
      coverScreen={false} 
      animationDuration={200}
    >
      <View style={styles.view__2}>
      <View style={{borderRadius: 40, overflow: 'hidden'}}>
      {/* <TouchableOpacity
      style={{width: "100%"}}
      > */}
      <View style={styles.view_input_c_1}>

      <IonicIcon style={styles.search_icon} name="search"/>

      <TextInput
        ref={inputRef}
        style={{
          // maxWidth: 200,
          fontSize: 14,
          color: "#808D8FFE",
          marginLeft: 8,
          fontFamily: "Helvetica",
          flexGrow: 1,
        }}
        value={searchValue}
        onChangeText={(text) => onSearchChangeText(text)}
        autoFocus={true}
        editable={searchOpen}
        onSubmitEditing={() => {
          setSearchAlertOpen(false);
          setSearchOpen(false);
          searchStringS(searchValue);
        }}
        placeholderTextColor="#4A5558FE"
        placeholder="Search DuckDuckGo"
      />

      {
        searchValue.length > 0 ?
        <IonicIcon onPress={() => setSearchValue("")} style={styles.mic_icon} name="close"/>
        :
        <></>
      }

      </View>
      {/* </TouchableOpacity> */}
      </View>
      </View>

    </Modal>

    <Modal
      isOpen={optionsAlertOpen} 
      onClosed={() => {setOptionsAlertOpen(false)}} 
      style={[styles.modal, styles.modal8]} 
      position={"bottom"} 
      backdropPressToClose={true} 
      swipeToClose={false}
      backdropOpacity={0.6} 
      backButtonClose={true}
      coverScreen={false} 
      animationDuration={200}
    >
      <View style={styles.optionAlertCont_MAIN}>

        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            copyToClipboard();
            showToast();
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Copy URL
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            setTimeout(() => {
              onShare();
            }, 320);
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              Share
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            setCurrentUrl("view-source:" + currentUrl);
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
              View page source
            </Text>
          </TouchableOpacity>
        </View>
        <View style={styles.optionAlertCont_opt_1_B}>
          <TouchableOpacity onPress={() => {
            setOptionsAlertOpen(false);
            navigation.navigate('Home', { name: "Incognito" });
          }}>
            <Text style={styles.optionAlertCont_optText_1}>
            Close Incognito
            </Text>
          </TouchableOpacity>
        </View>

        <View style={styles.optionAlertCont_opt_icon_1}>
          <TouchableOpacity style={{
            width: "100%",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            paddingBottom: 10,
            marginBottom: 4,
          }} onPress={() => {setOptionsAlertOpen(false)}}>
            {/* <FontAwesome style={styles.optionAlertCont_opt_icon_2} name="chevron-down"/> */}
            <Image 
              source={require("../assets/arrowDown2.png")} 
              style={{
                height: 26,
                width: 26,
              }}
            />
          </TouchableOpacity>
        </View>
        
      </View>
    </Modal>

    <View style={styles.searchMainContainer}>
        
      {/* Search 1 */}
      <View style={styles.search_1}>
        {
          currentUrl.includes("view-source:") ?
          <View style={styles.sea1__1}>
          <Image

            style={styles.sea1__1A}

            source={( favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.google.com/") ? require("../assets/googleIcon.png") :

            {uri: favIcon})}
            
          />
          </View>
          :
          <View style={styles.sea1__1}>
            {WebL ?
              <ActivityIndicator size="small" style={{
                height: 16,
                width: 16,
                resizeMode: "cover",
                marginLeft: 8,
                marginRight: 8,
              }} color={'#4A5558FE'} />
              :
              <Image

                style={styles.sea1__1A}

                source={(favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.nytimes.com/") ? require("../assets/ny.png") :

                favIcon.includes("https://api.statvoo.com/favicon/?url=https://www.google.com/") ? require("../assets/googleIcon.png") :

                {uri: favIcon})}

              />
            }
          </View>
        }

        <View style={{
          height: 30,
          borderRadius: 30,
          flexGrow: 1,
          overflow: "hidden",
        }}>
        <TouchableNativeFeedback
          background={TouchableNativeFeedback.Ripple("#AEAEAEFF", rippleOverflow)}
          onPress={() => {
            setSearchAlertOpen(true);
            setSearchValue("");
            setTimeout(() => {
              setSearchOpen(true);
              inputRef.current?.focus();
            }, 400);
          }}
        >
          <View style={styles.sea1__2}>
            <View style={styles.sea1__2A}>
              {
                (httpS == 1) ?
                <MaterialIcons style={styles.sea1__2A_icon1} name="https"/>
                : (httpS == 2) ?
                <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
                : (httpS == 3) ?
                <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
                : <MaterialIcons style={styles.sea1__2A_icon2} name="https"/>
              }
            </View>
            <View style={styles.sea1__2B}>
              <Text style={styles.sea1__2B_txt}>
                {currentUrl.replace("turbo/", "").split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]}
              </Text>
            </View>
            <TouchableOpacity onPress={refreshWeb}>
            <View style={styles.sea1__2C}>
              <MaterialIcons style={styles.sea1__2C_icon} name="replay"/>
            </View>
            </TouchableOpacity>
          </View>
        </TouchableNativeFeedback>
        </View>

        <View style={styles.sea1__3}>
        <TouchableOpacity onPress={handleFullScrTouch}>
          {/* <MaterialIcons style={styles.sea1__3_icon} name="more-vert"/> */}
          {
            fullscreen ?
            <MaterialIcons style={styles.sea1__3_icon} name="fullscreen-exit"/>
            :
            <MaterialIcons style={styles.sea1__3_icon} name="fullscreen"/>
          }
        </TouchableOpacity>
        </View>
      </View>

      {/* Search 2 */}
      <View style={styles.search_2}>
        {
          webViewShow ?
          <WebView
            startInLoadingState={true}
            ref={webviewRef}
            source={{
              uri: currentUrl,
            }}
            onNavigationStateChange={navState => {
              setCanGoBack(navState.canGoBack);
              setCanGoForward(navState.canGoForward);
              setCUrl(navState.url);
              // setWebTS(cUrl.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
            }}
            allowFileAccess={true}
            geolocationEnabled={true}
            showsHorizontalScrollIndicator={false}
            showsVerticalScrollIndicator={false}
            injectedJavaScript={INJECTEDJAVASCRIPT}
            onLoadStart={() => {
              setWebL(true);
            }}
            onLoadEnd={() => {
              setFavIcon("https://api.statvoo.com/favicon/?url=" + cUrl);
              setWebL(false);
              setHttpIcon();
              setWebTS(cUrl.split("/")[2] > 26 ? cUrl.split("/")[2].substring(0, 24) + "..." : cUrl.split("/")[2]);
            }}
            userAgent="Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36"
            domStorageEnabled={false}
          />
          : <></>
        }
      </View>

      {/* Search 3 */}
      {
        fullscreen || f2 ?
        <></>
        :
        <Animated.View
          style={{
            opacity: BottomNavOpacity
          }}
        >
        <View style={styles.search_3}>
        <TouchableOpacity onPress={se1} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="chevron-back-outline"/>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={se2} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="chevron-forward-outline"/>
          </View>
        </TouchableOpacity>
        <TouchableOpacity onPress={se3} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="home-outline"/>
          </View>
        </TouchableOpacity>
        {
          bookmarksKeyValue.includes(currentUrl) ?
          <TouchableOpacity onPress={se4Remove} style={styles.sea_3_item}>
            <View>
              <IonicIcon style={styles.sea3__3_icon_r} name="heart"/>
            </View>
          </TouchableOpacity>
          :
          <TouchableOpacity onPress={se4} style={styles.sea_3_item}>
            <View>
              <IonicIcon style={styles.sea3__3_icon_r} name="heart-outline"/>
            </View>
          </TouchableOpacity>
        }
        <TouchableOpacity onPress={se5} style={styles.sea_3_item}>
          <View>
            <IonicIcon style={styles.sea3__3_icon} name="grid-outline"/>
          </View>
        </TouchableOpacity>
        </View>
        </Animated.View>
      }
        
    </View>
        
    </SafeAreaView>
  );

}
Example #25
Source File: Help.js    From Turbo-Browser with MIT License 4 votes vote down vote up
Help = ({ navigation, route }) => {
  
  // ["#282C34FF", "#FFFFFFFF"]
  const styleTypes = ['default','dark-content', 'light-content'];
  const [statusColor, setStatusColor] = useState("#FFFFFFFF");
  const [styleStatusBar, setStyleStatusBar] = useState(styleTypes[3]);

  const [webViewShow, setWebViewShow] = useState(false);

  const [currentUrl, setCurrentUrl] = useState("https://turbo-browser.netlify.app/help.html");

  useEffect(() => {
    setCurrentUrl("https://turbo-browser.netlify.app/help.html");
  }, []);

  useEffect(() => {
    navigation.addListener("blur",
    () => {
      setStatusColor("#FFFFFFFF");
      setStyleStatusBar(styleTypes[3]);
    }
  );
  }, []);

  useEffect(() => {
    setTimeout(() => {
      setWebViewShow(true);
    }, 200);
  }, []);

  return (
    <SafeAreaView>
    <StatusBar backgroundColor={statusColor} barStyle={styleStatusBar} />

    <View style={styles.searchMainContainer}>
      {
        statusColor == "#282C34FF" ?
        <View style={styles.history_title_1_DARK}>
          <TouchableOpacity onPress={() => {navigation.goBack()}}>
          <View style={styles.history1_AA}>
            <IonicIcon name="arrow-back" style={styles.history_title_1A_icon_DARK}/>
          </View>
          </TouchableOpacity>
          <View style={styles.history1_BB}>
            <Text style={styles.history_title_1B_txt_DARK}>FAQs</Text>
          </View>
        </View>
      :
        <View style={styles.history_title_1}>
          <TouchableOpacity onPress={() => {navigation.goBack()}}>
          <View style={styles.history1_AA}>
            <IonicIcon name="arrow-back" style={styles.history_title_1A_icon}/>
          </View>
          </TouchableOpacity>
          <View style={styles.history1_BB}>
            <Text style={styles.history_title_1B_txt}>FAQs</Text>
          </View>
          <View style={{
            marginLeft: 10,
            transform: [
                { scale: 0.8 },
            ]
          }}>
            <ActivityIndicator color={'#282C34'}/>
          </View>
        </View>
      }

      <View style={styles.helpWebContainer}>
      { webViewShow ?
        <WebView
          startInLoadingState={true}
          source={{
            uri: currentUrl,
          }}
          onLoadEnd={() => {
            setStatusColor("#282C34FF");
            setStyleStatusBar(styleTypes[2]);
          }}
          geolocationEnabled={true}
          showsHorizontalScrollIndicator={false}
          showsVerticalScrollIndicator={false}
          userAgent="Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36"
        />
        : <></>
      }
      </View>
    
    </View>

    </SafeAreaView>
  );

}
Example #26
Source File: Index.jsx    From expo-plaid-link with MIT License 4 votes vote down vote up
export default function PlaidLink({ linkToken, onEvent, onExit, onSuccess }) {
  let webviewRef = useRef();

  const handleNavigationStateChange = (event) => {
    if (event.url.startsWith("plaidlink://")) {
      const eventParams = queryString.parse(event.url.replace(/.*\?/, ""));

      const linkSessionId = eventParams.link_session_id;
      const mfaType = eventParams.mfa_type;
      const requestId = eventParams.request_id;
      const viewName = eventParams.view_name;
      const errorCode = eventParams.error_code;
      const errorMessage = eventParams.error_message;
      const errorType = eventParams.error_type;
      const exitStatus = eventParams.exist_status;
      const institutionId = eventParams.institution_id;
      const institutionName = eventParams.institution_name;
      const institutionSearchQuery = eventParams.institution_search_query;
      const timestamp = eventParams.timestamp;

      if (event.url.startsWith("plaidlink://event") && onEvent) {
        onEvent({
          eventName: eventParams.event_name,
          metadata: {
            linkSessionId,
            mfaType,
            requestId,
            viewName,
            errorCode,
            errorMessage,
            errorType,
            exitStatus,
            institutionId,
            institutionName,
            institutionSearchQuery,
            timestamp,
          },
        });
      } else if (event.url.startsWith("plaidlink://exit") && onExit) {
        onExit({
          error: {
            errorCode: LinkErrorCode[errorCode],
            errorMessage: eventParams.error_message,
            errorType: LinkErrorType[errorType],
          },
          metadata: {
            status: LinkExitMetadataStatus[exitStatus],
            institution: {
              id: institutionId,
              name: institutionName,
            },
            linkSessionId,
            requestId,
          },
        });
      } else if (event.url.startsWith("plaidlink://connected") && onSuccess) {
        const publicToken = eventParams.public_token;
        const accounts = JSON.parse(eventParams.accounts);
        onSuccess({
          publicToken,
          metadata: {
            institution: {
              id: institutionId,
              name: institutionName,
            },
            accounts,
            linkSessionId,
          },
        });
      }
      return false;
    }
    return true;
  };

  return (
    <WebView
      source={{
        uri: `https://cdn.plaid.com/link/v2/stable/link.html?isWebview=true&token=${linkToken}`,
      }}
      ref={(ref) => (webviewRef = ref)}
      onError={() => webviewRef.reload()}
      originWhitelist={["https://*", "plaidlink://*"]}
      onShouldStartLoadWithRequest={handleNavigationStateChange}
    />
  );
}
Example #27
Source File: privacy.js    From haven with MIT License 4 votes vote down vote up
render() {
    const { loggingIn, urlInModal, showSpinner } = this.state;
    return (
      <View style={screenWrapper.wrapper}>
        <Image style={styles.bottomImg} source={bottomImg} resizeMode="contain" />
        <View style={onboardingStyles.header}>
          <StatusBarSpacer />
          <View style={onboardingStyles.headerContent}>
            <TouchableWithoutFeedback onPress={this.handleGoBack}>
              <View style={styles.backBtn}>
                <NavBackButton />
              </View>
            </TouchableWithoutFeedback>
            <Image style={styles.logo} source={shieldImg} resizeMode="contain" />
          </View>
        </View>
        <ScrollView style={{ flex: 1 }} contentContainerStyle={styles.scrollContent}>
          <View>
            <Text style={[styles.privacyText]}>
              PRIVACY
            </Text>
            <Hyperlink
              style={styles.hyperlinkContainer}
              linkStyle={styles.privacyButtonText}
              linkText={this.handleLinkText}
              onPress={this.handleShowModal}
            >
              <Text style={styles.privacyDescription1}>
                Haven is built to give you far more privacy in your commerce, messaging, and payments than other apps.
                It uses several advanced technologies to keep your information from prying eyes, such as peer-to-peer networking and end-to-end encryption.
              </Text>
              <Text style={styles.privacyDescription2}>
                There are ways to use Haven which improve or diminish your privacy.
                To learn more about how the underlying technology works, and what steps you can take to improve your privacy,
                {' '}
                tap the privacy policy link below.
              </Text>
              <Text style={styles.privacyDescription2}>
                Before you proceed, you must accept the Haven https://gethaven.app/terms and https://gethaven.app/privacy.
              </Text>
            </Hyperlink>
          </View>
          <View style={footerStyles.roundButtonContainer}>
            <TouchableWithoutFeedback onPress={this.handleGoBack}>
              <View>
                <Text style={styles.cancelButton}>Cancel</Text>
              </View>
            </TouchableWithoutFeedback>
            <Button
              wrapperStyle={onboardingStyles.button}
              title="I Accept"
              onPress={this.handleGetStarted}
              disabled={loggingIn}
            />
          </View>
        </ScrollView>
        <OBLightModal
          animationType="slide"
          transparent
          visible={!!urlInModal}
          onRequestClose={this.handleHideModal}
        >
          <Header modal left={<NavCloseButton />} onLeft={this.handleHideModal} />
          <View style={styles.webviewWrapper}>
            <WebView
              onLoadStart={this.handleHideSpinner}
              onError={this.handleHideSpinner}
              originWhitelist={['*']}
              source={{ uri: urlInModal }}
              scalesPageToFit={Platform.OS === 'android'}
              automaticallyAdjustContentInsets
              useWebKit={false}
            />
          </View>
          {showSpinner && (
            <View style={styles.activityIndicator}>
              <ActivityIndicator size="large" color="#8a8a8f" />
            </View>
          )}
        </OBLightModal>
      </View>
    );
  }