react-native-webview#WebView TypeScript 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: GoogleTimeLine.tsx From hamagen-react-native with MIT License | 6 votes |
FetchHistoryModal = ({ isVisible, isLoggedIn, webViewRef, onMessage, closeModal }: FetchHistoryModalProps) => {
return (
<Modal
visible={isVisible}
animationType="slide"
onRequestClose={isLoggedIn ? () => { } : closeModal}
>
<View style={styles.container}>
<WebviewHeader hideClose={isLoggedIn} closeModal={closeModal} />
<WebView
style={{ flex: 1, width: SCREEN_WIDTH }}
ref={webViewRef}
source={{ uri: 'https://accounts.google.com/signin/v2/identifier?service=accountsettings&flowName=GlifWebSignIn&flowEntry=ServiceLogin', }}
startInLoadingState
onMessage={onMessage}
injectedJavaScript={`(function() {
if(window.location.href.startsWith('https://myaccount.google.com/?utm_source=sign_in_no_continue')) {
window.ReactNativeWebView.postMessage("LOGGED_IN");
}
})();`
}
originWhitelist={['*']}
/>
</View>
</Modal>
);
}
Example #2
Source File: washerWeb.tsx From THUInfo with MIT License | 6 votes |
WasherWebScreen = () => {
const themeName = useColorScheme();
const theme = themes(themeName);
return (
<View style={{backgroundColor: theme.colors.themeBackground, flex: 1}}>
<WebView
source={{uri: "https://washer.sdevs.top/"}}
forceDarkOn={themeName === "dark"}
style={{
backgroundColor: theme.colors.themeBackground,
color: theme.colors.text,
}}
setSupportMultipleWindows={false}
/>
</View>
);
}
Example #3
Source File: index.tsx From hive-keychain-mobile with MIT License | 6 votes |
render() {
return (
<View style={styles.container}>
<WebView
source={{html}}
ref={(r) => {
this.webref = r;
}}
onMessage={this.onWebViewMessage}
/>
</View>
);
}
Example #4
Source File: WebView.tsx From DoobooIAP with MIT License | 6 votes |
function Page(props: Props): ReactElement {
const {
route: {
params: { uri },
},
} = props;
return (
<Container>
<WebView source={{ uri }} />
</Container>
);
}
Example #5
Source File: debug.tsx From bext with MIT License | 6 votes |
DebugScreen: FC = () => {
const webView = useRef<WebView>(null);
const { params } = useRoute<any>();
const { script } = useDebug();
return (
<WebView
ref={webView}
originWhitelist={['*']}
source={{
uri: params.url,
}}
injectedJavaScriptBeforeContentLoaded={`${script.current};true;`}
/>
);
}
Example #6
Source File: quill-editor.tsx From react-native-cn-quill with MIT License | 6 votes |
renderWebview = (
content: string,
style: StyleProp<ViewStyle>,
props: WebViewProps = {}
) => (
<WebView
scrollEnabled={false}
hideKeyboardAccessoryView={true}
keyboardDisplayRequiresUserAction={false}
originWhitelist={['*']}
style={style}
onError={(syntheticEvent) => {
const { nativeEvent } = syntheticEvent;
console.warn('WebView error: ', nativeEvent);
}}
allowFileAccess={true}
domStorageEnabled={false}
automaticallyAdjustContentInsets={true}
bounces={false}
dataDetectorTypes="none"
{...props}
javaScriptEnabled={true}
source={{ html: content }}
ref={this._webview}
onMessage={this.onMessage}
/>
);
Example #7
Source File: CredentialGenerator.tsx From jellyfin-audio-player with MIT License | 6 votes |
render() {
const { serverUrl } = this.props;
return (
<WebView
source={{ uri: serverUrl as string }}
style={{ borderRadius: 20 }}
onNavigationStateChange={this.handleStateChange}
onMessage={this.handleMessage}
ref={this.ref}
startInLoadingState={true}
/>
);
}
Example #8
Source File: RecommendationList.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function Entry(props: EntryPropsType) {
const [visible, setVisible] = useState(false);
const [loadingWebview, setLoading] = useState(true);
return (
<View>
<ListItem
onPress={() => setVisible(true)}
Component={TouchableOpacity}
title={<Text style={{ fontWeight: '800' }}>{props.title}</Text>}
subtitle={
<Text style={{ fontSize: 12, paddingTop: 3 }}>
修改时间:
{formatDate(props.modifyTime)} from {props.operator}
</Text>
}
leftAvatar={{ source: { uri: props.imgUrl } }}
rightIcon={{ name: 'unfold-more' }}
/>
<Modal
animationType="fade"
presentationStyle="pageSheet"
visible={visible}
onDismiss={() => {
setVisible(false);
}}
onRequestClose={() => {
setVisible(false);
}}>
<View style={{ padding: 16, justifyContent: 'space-between' }}>
{loadingWebview ? (
<ActivityIndicator size="large" color="red" />
) : null}
<View style={{ height: height - 150 }}>
<WebView
onLoad={() => setLoading(true)}
onLoadEnd={() => setLoading(false)}
source={{ uri: props.linkUrl }}
/>
</View>
<View>
<Button
buttonStyle={styles.button}
title="关闭预览"
onPress={() => {
setVisible(false);
}}
/>
</View>
</View>
</Modal>
</View>
);
}
Example #9
Source File: Webview.tsx From wuhan2020-frontend-react-native-app with MIT License | 5 votes |
function WebViewModal({
uri,
title,
visible,
onClose,
}: {
uri: string;
title: string;
visible: boolean;
onClose: () => void;
}) {
const [loadingWebview, setLoading] = useState(true);
return (
<Modal
animationType="fade"
presentationStyle="pageSheet"
visible={visible}
onDismiss={onClose}
onRequestClose={onClose}>
<View style={{ padding: 16, justifyContent: 'space-between' }}>
<View style={{ height: height - 150 }}>
<H1 title={title} />
{loadingWebview ? (
<View style={{ paddingVertical: 20 }}>
<Loader />
</View>
) : null}
<WebView
onLoad={() => setLoading(true)}
onLoadEnd={() => setLoading(false)}
source={{ uri }}
/>
</View>
<View>
<Button
buttonStyle={styles.button}
title="关闭预览"
onPress={onClose}
/>
</View>
</View>
</Modal>
);
}
Example #10
Source File: login-web-view.tsx From beancount-mobile with MIT License | 5 votes |
LoginWebView = connect(
() => ({}),
(dispatch) => ({
updateReduxState(payload: {
base: { userId: string; authToken: string };
}): void {
dispatch(actionUpdateReduxState(payload));
},
})
)(function LoginWebViewInner(props: Props): JSX.Element {
const { updateReduxState, isSignUp } = props;
const [progress, setProgress] = useState(0);
const injectedJavascript = `(function() {
window.postMessage = function(data) {
window.ReactNativeWebView.postMessage(data);
};
})()`;
return (
<View style={{ flex: 1, flexDirection: "column" }}>
<ProgressBar progress={progress} />
<WebView
injectedJavaScript={injectedJavascript}
source={{
uri: isSignUp ? getEndpoint("sign-up") : getEndpoint("login"),
headers,
}}
style={{
alignSelf: "stretch",
marginTop: 0,
height: height - statusBarHeight,
}}
onLoadProgress={({ nativeEvent }) => setProgress(nativeEvent.progress)}
onMessage={async (event) => {
try {
const msg = decodeURIComponent(
decodeURIComponent(event.nativeEvent.data)
);
const msgObj = JSON.parse(msg);
if (msgObj.authToken) {
const { sub } = jwtDecode(msgObj.authToken);
analytics.identify(sub);
await analytics.track(isSignUp ? "signed_up" : "logged_in", {});
updateReduxState({
base: {
userId: sub,
authToken: msgObj.authToken,
},
});
props.onClose();
}
} catch (e) {
// tslint:disable-next-line:no-console
console.error(`failed to decode jwt: ${e}`);
}
}}
/>
</View>
);
})
Example #11
Source File: ledger-screen.tsx From beancount-mobile with MIT License | 5 votes |
LedgerScreen = connect((state: AppState) => {
return { authToken: state.base.authToken };
})(function BbsScreenInner(props: Props): JSX.Element {
let webViewRef: WebView | null;
const theme = useTheme().colorTheme;
const styles = getStyles(theme);
const [progress, setProgress] = useState(0);
useEffect(() => {
async function init() {
await analytics.track("page_view_ledger", {});
}
init();
}, []);
const onRefresh = async () => {
await analytics.track("tap_refresh", {});
if (webViewRef) {
webViewRef.reload();
}
};
const { authToken } = props;
const [uri, setUri] = useState(getEndpoint("ledger/editor/"));
return (
<View style={styles.container}>
<View style={{ height: statusBarHeight, backgroundColor: theme.white }} />
<ProgressBar progress={progress} />
<WebView
ref={(webView) => {
webViewRef = webView;
}}
onLoadProgress={({ nativeEvent }) => setProgress(nativeEvent.progress)}
source={{
uri,
headers: { Authorization: `Bearer ${authToken}`, ...headers },
}}
onLoadStart={(navState) => {
setUri(navState.nativeEvent.url);
}}
/>
<Button style={styles.refreshButton} onPress={onRefresh}>
<Ionicons name="md-refresh" size={24} color={theme.white} />
</Button>
</View>
);
})
Example #12
Source File: WebViewScene.tsx From sellflow with MIT License | 5 votes |
export default function WebScene() {
let {
params: { type, webUrl },
} = useRoute<StackRouteProp<'WebView'>>();
let { navigate, setOptions } = useNavigation<StackNavProp<'WebView'>>();
let { resetShoppingCart } = useResetCart();
let title: string;
switch (type) {
case 'policy':
title = t('Privacy Policy');
break;
case 'terms':
title = t('Terms & Conditions');
break;
default:
title = t('Payment');
}
useEffect(() => {
setOptions({
title,
});
});
return webUrl ? (
<SafeAreaView style={styles.flex}>
<WebView
style={styles.container}
source={{ uri: webUrl }}
originWhitelist={['*']}
onShouldStartLoadWithRequest={({ url }) => {
if (url.endsWith('thank_you')) {
resetShoppingCart();
navigate('OrderPlacedConfirmation', { orderNumber: '' });
return false;
}
return true;
}}
startInLoadingState={true}
renderLoading={() => <ActivityIndicator style={styles.center} />}
/>
</SafeAreaView>
) : (
<SafeAreaView style={styles.text}>
<Text>{t('Please check your connection.')}</Text>
</SafeAreaView>
);
}
Example #13
Source File: AppMain.tsx From tailchat with GNU General Public License v3.0 | 5 votes |
AppMain: React.FC = React.memo(() => {
return (
<WebView
style={styles.webview}
source={{ uri: 'https://nightly.paw.msgbyte.com/' }}
/>
);
})
Example #14
Source File: react-native-webview-controller.tsx From magic-js with MIT License | 5 votes |
/**
* Renders a React Native `<WebView>` with built-in message handling to and
* from the Magic `<iframe>` context.
*/
// Validating this logic requires lots of React-specific boilerplate. We will
// revisit this method for unit testing in the future. For now, manual testing
// is sufficient (this logic is stable right now and not expected to change in
// the forseeable future).
/* istanbul ignore next */
public Relayer: React.FC = () => {
const [show, setShow] = useState(false);
/**
* Saves a reference to the underlying `<WebView>` node so we can interact
* with incoming messages.
*/
const webViewRef = useCallback((webView: any): void => {
this.webView = webView;
}, []);
/**
* Saves a reference to the underlying `<View>` node so we can interact with
* display styles.
*/
const containerRef = useCallback((view: any): void => {
this.container = {
...view,
showOverlay,
hideOverlay,
};
}, []);
/**
* Show the Magic `<WebView>` overlay.
*/
const showOverlay = useCallback(() => {
setShow(true);
}, []);
/**
* Hide the Magic `<WebView>` overlay.
*/
const hideOverlay = useCallback(() => {
setShow(false);
}, []);
const containerStyles = useMemo(() => {
return [this.styles['webview-container'], show ? this.styles.show : this.styles.hide];
}, [show]);
const handleWebViewMessage = useCallback((event: any) => {
this.handleReactNativeWebViewMessage(event);
}, []);
return (
<View ref={containerRef} style={containerStyles}>
<WebView
ref={webViewRef}
source={{ uri: `${this.endpoint}/send/?params=${encodeURIComponent(this.parameters)}` }}
onMessage={handleWebViewMessage}
style={this.styles['magic-webview']}
/>
</View>
);
};
Example #15
Source File: react-native-webview-controller.tsx From magic-js with MIT License | 5 votes |
private webView!: WebView | null;
Example #16
Source File: CredentialGenerator.tsx From jellyfin-audio-player with MIT License | 5 votes |
ref = createRef<WebView>();
Example #17
Source File: quill-editor.tsx From react-native-cn-quill with MIT License | 5 votes |
private _webview: React.RefObject<WebView>;
Example #18
Source File: index.tsx From hive-keychain-mobile with MIT License | 5 votes |
webref: WebView;
Example #19
Source File: Webview.tsx From SQUID with MIT License | 5 votes |
WebviewScreen = () => {
const webviewRef = useRef<WebView>()
const uri = useNavigationParam('uri')
const onClose = useNavigationParam('onClose')
return (
<SafeAreaView
style={{
flex: 1,
backgroundColor: COLORS.BLACK_1,
}}
>
<View
style={{
width: '100%',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 16,
backgroundColor: COLORS.BLACK_1,
}}
>
<View style={{ flex: 1 }} />
<CloseButton onClose={onClose} />
</View>
<WebView
source={{ uri }}
ref={ref => {
webviewRef.current = ref
if (webviewRef.current) {
// setTimeout(() => {
// webviewRef.current.injectJavaScript(
// `window.ReactNativeWebView.postMessage("complete")`,
// )
// }, 2000)
}
}}
style={{
flex: 1,
}}
onMessage={event => {
if (event.nativeEvent.data === 'complete') {
onClose()
}
// console.log('event.nativeEvent.data', event.nativeEvent.data)
// alert(event.nativeEvent.data)
}}
/>
</SafeAreaView>
)
}
Example #20
Source File: newsDetail.tsx From THUInfo with MIT License | 5 votes |
NewsDetailScreen = ({route}: {route: NewsDetailRouteProp}) => {
const [html, setHtml] = useState<string>("");
const [pdf, setPdf] = useState<string>("");
const [refreshing, setRefreshing] = useState(true);
const themeName = useColorScheme();
const theme = themes(themeName);
const style = styles(themeName);
const fetchHtml = () => {
setRefreshing(true);
helper
.getNewsDetail(route.params.detail.url)
.then(([title, res, abstract]) => {
if (title === "PdF" && abstract === "PdF") {
setPdf(res);
} else {
setHtml(`<h2>${title}</h2>${res}`);
}
setRefreshing(false);
})
.catch(() => {
Snackbar.show({
text: getStr("networkRetry"),
duration: Snackbar.LENGTH_LONG,
});
setRefreshing(false);
});
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(fetchHtml, []);
const adaptedHtml = `<head><meta name="viewport" content="width=100, initial-scale=1"></head>
<body>${html}</body>`;
return (
<>
<View style={style.container}>
{pdf === "" ? (
<WebView
source={{
html: adaptedHtml,
baseUrl: "https://webvpn.tsinghua.edu.cn",
}}
containerStyle={style.webContainer}
userAgent={USER_AGENT}
setSupportMultipleWindows={false}
forceDarkOn={themeName === "dark"}
/>
) : (
<Pdf
style={style.pdf}
source={{uri: `data:application/pdf;base64,${pdf}`}}
/>
)}
</View>
{refreshing && (
<View style={style.container}>
<ActivityIndicator size="large" color={theme.colors.primary} />
</View>
)}
</>
);
}
Example #21
Source File: dev.tsx From bext with MIT License | 4 votes |
DevScreen: FC = () => {
const [loading, setLoading] = useState(true);
const { params } = useRoute<any>();
const { id, modify } = params || {};
const { data: draft, mutate } = useRequest(
async () => {
try {
return await getDraft(id);
} catch (error) {}
},
{
ready: !!id,
},
);
useUpdateEffect(() => {
if (draft?.id) {
updateUrl(draft.id, draft.url || '');
}
}, [draft?.url, draft?.id]);
const navigation = useNavigation();
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (loading ? <Text>加载中...</Text> : null),
...(draft?.name ? { title: draft.name } : null),
});
}, [navigation, loading, draft?.name]);
const [modalVisible, setModalVisible] = useState(false);
const { script } = useDebug();
const webView = useRef<WebView>(null);
const onMessage = (msg: string = '{}') => {
try {
const data = JSON.parse(msg);
switch (data.type) {
case 'save':
updateJson(id, JSON.stringify(data.payload));
break;
case 'ready':
webView.current?.injectJavaScript(`
if (window.injectDraft) {
window.injectDraft(decodeURIComponent("${encodeURIComponent(
draft?.json || '{}',
)}"));
}
true;
`);
break;
case 'debug':
setModalVisible(true);
script.current = data.payload;
break;
default:
break;
}
} catch (error) {}
};
const navigateToDebug = () => {
navigation.navigate(
'debug' as never,
{
url: draft?.url,
} as never,
);
setModalVisible(false);
};
return (
<>
<Overlay
transparent
isVisible={modalVisible}
onBackdropPress={() => setModalVisible(false)}
overlayStyle={styles.overlay}
>
<Input
label="输入窗口链接"
value={draft?.url}
onChangeText={(url) => mutate((old) => ({ ...old, url } as any))}
/>
<Button title="确定" disabled={!draft?.url} onPress={navigateToDebug} />
</Overlay>
<WebView
ref={webView}
originWhitelist={['*']}
source={{
uri: `${BEXT_ORIGIN}${
modify
? '/meta?from=dev&devPath=%2Fdev%2Fscript-m'
: '/dev/script-m'
}`,
}}
onLoad={() => setLoading(false)}
onMessage={(e) => onMessage(e.nativeEvent.data)}
/>
</>
);
}
Example #22
Source File: WebView.tsx From react-native-jigsaw with MIT License | 4 votes |
NativeWebView: React.FC<WebViewProps> = ({
source,
style,
optimizeVideoChat,
}) => {
const [height, setHeight] = useState(0);
const [cameraPermissions, setCameraPermissions] =
useState<null | PermissionResponse>(null);
const [microphonePermissions, setMicrophonePermissions] =
useState<null | PermissionResponse>(null);
const videoChatProps = optimizeVideoChat
? {
allowsInlineMediaPlayback: true,
domStorageEnabled: true,
javaScriptEnabled: true,
mediaCapturePermissionGrantType: "grant", // so iOS uses system settings
mediaPlaybackRequiresUserAction: false,
startInLoadingState: true,
}
: ({} as Record<string, boolean | string>);
const onMessage = (event: WebViewMessageEvent) =>
setHeight(Number(event.nativeEvent.data));
const getAndSetPermissions = async (
currentState: null | PermissionResponse,
setCurrentState: Dispatch<SetStateAction<null | PermissionResponse>>,
getPermission: () => Promise<PermissionResponse>,
requestPermission: () => Promise<PermissionResponse>
) => {
const currentPermission = currentState ?? (await getPermission());
if (currentPermission.granted || !currentPermission.canAskAgain) {
setCurrentState(currentPermission);
} else {
setCurrentState(await requestPermission());
}
};
const getAndSetCameraAndMicrophonePermissions = async () => {
await getAndSetPermissions(
cameraPermissions,
setCameraPermissions,
Camera.getCameraPermissionsAsync,
Camera.requestCameraPermissionsAsync
);
await getAndSetPermissions(
microphonePermissions,
setMicrophonePermissions,
Camera.getMicrophonePermissionsAsync,
Camera.requestMicrophonePermissionsAsync
);
};
const getFinalWidth = () => {
const { width } = Dimensions.get("window");
if (typeof style?.width === "number") {
return style.width;
} else if (typeof style?.width === "string" && style.width.includes("%")) {
return width * (Number(style.width.replace("%", "")) / 100);
} else {
return width;
}
};
const selectComponent = () => {
if (
!optimizeVideoChat ||
(cameraPermissions?.granted && microphonePermissions?.granted)
) {
return (
<WebView
source={source}
style={{ ...style, width: getFinalWidth() }}
injectedJavaScript={injectFirst}
onMessage={onMessage}
{...videoChatProps}
/>
);
}
if (
(!cameraPermissions?.granted && cameraPermissions?.canAskAgain) ||
(!microphonePermissions?.granted && microphonePermissions?.canAskAgain)
) {
return (
<Button
title={"Press to enable Audio and/or Video permissions"}
onPress={getAndSetCameraAndMicrophonePermissions}
/>
);
}
if (
(cameraPermissions?.status === "denied" &&
cameraPermissions?.canAskAgain === false) ||
(microphonePermissions?.status === "denied" &&
microphonePermissions?.canAskAgain === false)
) {
return (
<Text>
{"Set the missing Audio and/or Video permissions in System Settings"}
</Text>
);
}
return <ActivityIndicator />;
};
useEffect(() => {
if (optimizeVideoChat) getAndSetCameraAndMicrophonePermissions();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [optimizeVideoChat]);
return (
<ScrollView
contentContainerStyle={[
styles.container,
{
height: style?.height || height,
},
]}
>
{selectComponent()}
</ScrollView>
);
}
Example #23
Source File: GoogleTimeLine.tsx From hamagen-react-native with MIT License | 4 votes |
GoogleTimeLine = ({ strings, toggleWebview, onCompletion }: GoogleTimeLineProps) => {
const {
general: { additionalInfo },
locationHistory: { beforeCheckTitle, beforeCheckDesc, beforeCheckDesc2, beforeCheckButton, skip, successFoundTitle, successFoundDesc, successFoundButton, successNotFoundTitle, successNotFoundDesc, successNotFoundButton, failedTitle, failedDesc, failedButton }
} = strings;
const didRetry = useRef<boolean>(false);
const webViewRef = useRef<WebView>(null);
const [{ openWebview, isLoggedIn, state }, setState] = useState<State>({ openWebview: false, isLoggedIn: false, state: 'before' });
const pageStateConfig = () => {
switch (state) {
case 'before': {
return {
icon: require('../../assets/locationHistory/before.png'),
title: beforeCheckTitle,
desc1: beforeCheckDesc,
desc2: beforeCheckDesc2,
button: beforeCheckButton,
action: () => setState(prevState => ({ ...prevState, openWebview: true }))
};
}
case 'successFound': {
return {
icon: require('../../assets/locationHistory/successFound.png'),
title: successFoundTitle,
desc1: successFoundDesc,
desc2: '',
button: successFoundButton,
action: () => onCompletion()
};
}
case 'successNotFound': {
return {
icon: require('../../assets/locationHistory/successNotFound.png'),
title: successNotFoundTitle,
desc1: successNotFoundDesc,
desc2: '',
button: successNotFoundButton,
action: () => onCompletion()
};
}
case 'failed': {
return {
icon: require('../../assets/locationHistory/failed.png'),
title: failedTitle,
desc1: failedDesc,
desc2: '',
button: failedButton,
action: () => setState(prevState => ({ ...prevState, openWebview: true }))
};
}
default: { return { icon: 0, title: '', desc1: '', desc2: '', button: '', action: () => { } }; }
}
};
const retryKMLDownload = (didRetry: any, kmlUrls: string[]) => new Promise<string[]>((resolve) => {
setTimeout(async () => {
didRetry.current = true;
resolve(await Promise.all(kmlUrls.map(url => fetch(url).then(r => r.text()))));
}, IS_IOS ? 5000 : 10);
});
const onMessage = async ({ nativeEvent: { data } }: WebViewMessageEvent) => {
if (!data) {
return;
}
if (data === 'LOGGED_IN' && !isLoggedIn) {
try {
webViewRef.current?.injectJavaScript(`document.getElementsByTagName(\'html\')[0].innerHTML = \'${getLoadingHTML()}\'; true;`);
setState(prevState => ({ ...prevState, isLoggedIn: true }));
const kmlUrls = getLastNrDaysKmlUrls();
let texts = await Promise.all(kmlUrls.map(url => fetch(url).then(r => r.text())));
if (texts[0].indexOf('DOCTYPE') > -1 && texts[0].indexOf('Error') > -1) {
if (!didRetry.current) {
texts = await retryKMLDownload(didRetry, kmlUrls);
if (texts[0].indexOf('DOCTYPE') > -1 && texts[0].indexOf('Error') > -1) {
return onFetchError('Fetch KML error');
}
} else {
return onFetchError('Fetch KML error');
}
}
const pointsData = texts.flatMap((kml: string) => kmlToGeoJson(kml));
if (pointsData.length === 0) {
return onFlowEnd('successNotFound');
}
await insertToSampleDB(pointsData);
return onFlowEnd('successFound');
} catch (error) {
await onFetchError(error);
}
}
};
const onFetchError = async (error: any) => {
await onFlowEnd('failed');
onError({ error });
};
const onFlowEnd = async (state: 'before' | 'successFound' | 'successNotFound' | 'failed') => {
if (state !== 'failed') {
// once 14 days flow completed for the first time
await AsyncStorage.setItem(SHOULD_HIDE_LOCATION_HISTORY, 'true');
store().dispatch(checkIfHideLocationHistory());
}
webViewRef.current?.injectJavaScript('setTimeout(() => { document.location = "https://accounts.google.com/logout"; true; }, 10)');
setTimeout(async () => {
didRetry.current = false;
setState(prevState => ({ ...prevState, openWebview: false, isLoggedIn: false, state }));
await CookieManager.clearAll(true);
}, 300);
};
return (
<View style={styles.container}>
<View style={styles.textsContainer}>
{
(!IS_SMALL_SCREEN || state !== 'before') && (
<Icon source={pageStateConfig().icon} width={154} height={64} customStyles={{ marginBottom: 50 }} />
)
}
<Text style={styles.title} bold>{pageStateConfig().title}</Text>
<Text style={{ marginBottom: 20 }}>{pageStateConfig().desc1}</Text>
<Text bold>{pageStateConfig().desc2}</Text>
</View>
{
state === 'before' && (
<View style={{ width: SCREEN_WIDTH * 0.7, alignItems: 'center' }}>
<TouchableOpacity onPress={() => toggleWebview(true, USAGE_PRIVACY)}>
<Text style={{ fontSize: 14 }}>{additionalInfo}</Text>
<View style={styles.bottomBorder} />
</TouchableOpacity>
</View>
)
}
<View style={{ alignItems: 'center' }}>
<ActionButton text={pageStateConfig().button} onPress={pageStateConfig().action} containerStyle={{ marginBottom: 15 }} />
<View style={{ height: 20 }}>
{
(state === 'before' || state === 'failed') && (
<TouchableOpacity onPress={onCompletion}>
<Text style={{ fontSize: 20 }}>{skip}</Text>
</TouchableOpacity>
)
}
</View>
</View>
<FetchHistoryModal
webViewRef={webViewRef}
isVisible={openWebview}
onMessage={onMessage}
isLoggedIn={isLoggedIn}
closeModal={() => setState(prevState => ({ ...prevState, openWebview: false }))}
/>
</View>
);
}
Example #24
Source File: IterableInboxMessageDisplay.tsx From react-native-sdk with MIT License | 4 votes |
IterableInboxMessageDisplay = ({
rowViewModel,
inAppContentPromise,
returnToInbox,
deleteRow,
contentWidth,
isPortrait
}: MessageDisplayProps) => {
const messageTitle = rowViewModel.inAppMessage.inboxMetadata?.title
const [inAppContent, setInAppContent] = useState<IterableHtmlInAppContent>(new IterableHtmlInAppContent(new IterableEdgeInsets(0, 0, 0, 0), ""))
const styles = StyleSheet.create({
messageDisplayContainer: {
height: '100%',
width: contentWidth,
backgroundColor: 'whitesmoke',
flexDirection: 'column',
justifyContent: 'flex-start'
},
header: {
flexDirection: 'row',
justifyContent: 'center',
width: '100%'
},
returnButtonContainer: {
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
width: '25%',
marginLeft: 0,
marginTop: 0
},
returnButton: {
flexDirection: 'row',
alignItems: 'center'
},
returnButtonIcon: {
color: 'deepskyblue',
fontSize: 40,
paddingLeft: 0
},
returnButtonText: {
color: 'deepskyblue',
fontSize: 20
},
messageTitleContainer: {
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center',
width: '75%',
marginTop: 0
},
messageTitle: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
width: 0.5 * contentWidth,
},
messageTitleText: {
fontWeight: 'bold',
fontSize: 20,
backgroundColor: 'whitesmoke'
},
contentContainer: {
flex: 1,
}
})
let {
header,
returnButtonContainer,
returnButton,
returnButtonIcon,
returnButtonText,
messageTitleContainer,
messageTitleText,
messageDisplayContainer
} = styles
// orientation dependent styling
returnButtonContainer = (!isPortrait) ? { ...returnButtonContainer, marginLeft: 80 } : returnButtonContainer
let JS = `
const links = document.querySelectorAll('a')
links.forEach(link => {
link.class = link.href
link.href = "javascript:void(0)"
link.addEventListener("click", () => {
window.ReactNativeWebView.postMessage(link.class)
})
})
`
useEffect(() => {
let mounted = true
inAppContentPromise.then(
(value) => {
if(mounted) {
setInAppContent(value)
}
})
return () => {mounted = false}
})
function handleInAppLinkAction(event: any) {
let URL = event.nativeEvent.data
let action = new IterableAction("openUrl", URL, "")
let source = IterableActionSource.inApp
let context = new IterableActionContext(action, source)
Iterable.trackInAppClick(rowViewModel.inAppMessage, IterableInAppLocation.inbox, URL)
Iterable.trackInAppClose(rowViewModel.inAppMessage, IterableInAppLocation.inbox, IterableInAppCloseSource.link, URL)
if (URL === 'iterable://delete') {
returnToInbox(() => deleteRow(rowViewModel.inAppMessage.messageId))
} else if(URL === 'iterable://dismiss') {
returnToInbox()
} else if (URL.slice(0, 4) === 'http') {
returnToInbox(() => Linking.openURL(URL))
} else {
returnToInbox(() => {
if(Iterable.savedConfig.urlHandler) {
Iterable.savedConfig.urlHandler(URL, context)
}
})
}
}
return (
<View style={messageDisplayContainer}>
<View style={header}>
<View style={returnButtonContainer}>
<TouchableWithoutFeedback
onPress={() => {
returnToInbox()
Iterable.trackInAppClose(rowViewModel.inAppMessage, IterableInAppLocation.inbox, IterableInAppCloseSource.back)
}}
>
<View style={returnButton}>
<Icon name="ios-chevron-back" style={returnButtonIcon} />
<Text style={returnButtonText}>Inbox</Text>
</View>
</TouchableWithoutFeedback>
</View>
<View style={messageTitleContainer}>
<View style={styles.messageTitle}>
<Text numberOfLines={1} ellipsizeMode='tail' style={messageTitleText}>{messageTitle}</Text>
</View>
</View>
</View>
<ScrollView contentContainerStyle={styles.contentContainer}>
<WebView
originWhiteList={['*']}
source={{ html: inAppContent.html }}
style={{ width: contentWidth }}
onMessage={(event) => handleInAppLinkAction(event)}
injectedJavaScript={JS}
/>
</ScrollView>
</View>
)
}