diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 7dbb8936e17..511f1c61201 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -721,4 +721,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 225a865018bba07be314e8afa4e91319ab40adac -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.0 diff --git a/src/common/WebLink.js b/src/common/WebLink.js index 3ae256f5b4a..599a0980424 100644 --- a/src/common/WebLink.js +++ b/src/common/WebLink.js @@ -5,7 +5,7 @@ import React, { PureComponent } from 'react'; import type { Dispatch } from '../types'; import { connect } from '../react-redux'; import Label from './Label'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; import { getCurrentRealm } from '../selectors'; import { BRAND_COLOR, createStyleSheet } from '../styles'; @@ -26,7 +26,7 @@ type Props = $ReadOnly<{| class WebLink extends PureComponent { handlePress = () => { const { realm, href } = this.props; - openLink(new URL(href, realm).toString()); + openLinkEmbedded(new URL(href, realm).toString()); }; styles = createStyleSheet({ diff --git a/src/lightbox/LightboxActionSheet.js b/src/lightbox/LightboxActionSheet.js index e66b34601e1..4d007536597 100644 --- a/src/lightbox/LightboxActionSheet.js +++ b/src/lightbox/LightboxActionSheet.js @@ -5,7 +5,7 @@ import share from './share'; import shareImage from './shareImage'; import { showToast } from '../utils/info'; import * as api from '../api'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; type DownloadImageType = {| src: string, @@ -37,7 +37,7 @@ const tryToDownloadImage = async ({ src, auth }: DownloadImageType) => { const tempUrl = await api.tryGetFileTemporaryUrl(src, auth); if (tempUrl === null) { showToast('Please download the image from your browser'); - openLink(new URL(src, auth.realm).toString()); + openLinkEmbedded(new URL(src, auth.realm).toString()); return; } diff --git a/src/lightbox/shareImage.js b/src/lightbox/shareImage.js index fa2c5ff6344..176fa3d3ebd 100644 --- a/src/lightbox/shareImage.js +++ b/src/lightbox/shareImage.js @@ -6,14 +6,14 @@ import type { Auth } from '../types'; import ShareImageAndroid from '../nativeModules/ShareImageAndroid'; import { showToast } from '../utils/info'; import * as api from '../api'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; export default async (url: string, auth: Auth) => { const tempUrl = await api.tryGetFileTemporaryUrl(url, auth); if (tempUrl === null) { showToast('Please share the image from your browser'); - openLink(new URL(url, auth.realm).toString()); + openLinkEmbedded(new URL(url, auth.realm).toString()); return; } diff --git a/src/settings/LegalScreen.js b/src/settings/LegalScreen.js index 2c468c98825..fedf324c5a5 100644 --- a/src/settings/LegalScreen.js +++ b/src/settings/LegalScreen.js @@ -6,7 +6,7 @@ import type { NavigationStackProp, NavigationStateRoute } from 'react-navigation import type { Dispatch } from '../types'; import { connect } from '../react-redux'; import { Screen, OptionButton } from '../common'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; import { getCurrentRealm } from '../selectors'; type Props = $ReadOnly<{| @@ -23,12 +23,12 @@ type Props = $ReadOnly<{| class LegalScreen extends PureComponent { openTermsOfService = () => { const { realm } = this.props; - openLink(new URL('/terms/?nav=no', realm).toString()); + openLinkEmbedded(new URL('/terms/?nav=no', realm).toString()); }; openPrivacyPolicy = () => { const { realm } = this.props; - openLink(new URL('/privacy/?nav=no', realm).toString()); + openLinkEmbedded(new URL('/privacy/?nav=no', realm).toString()); }; render() { diff --git a/src/start/AuthScreen.js b/src/start/AuthScreen.js index c178a85aedd..17b0108093e 100644 --- a/src/start/AuthScreen.js +++ b/src/start/AuthScreen.js @@ -32,7 +32,7 @@ import { encodeParamsForUrl } from '../utils/url'; import * as webAuth from './webAuth'; import { loginSuccess, navigateToDev, navigateToPassword } from '../actions'; import IosCompliantAppleAuthButton from './IosCompliantAppleAuthButton'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; /** * Describes a method for authenticating to the server. @@ -269,7 +269,7 @@ class AuthScreen extends PureComponent { id_token: credential.identityToken, }); - openLink(new URL(`/complete/apple/?${params}`, this.props.realm).toString()); + openLinkEmbedded(new URL(`/complete/apple/?${params}`, this.props.realm).toString()); // Currently, the rest is handled with the `zulip://` redirect, // same as in the web flow. diff --git a/src/start/webAuth.js b/src/start/webAuth.js index d818708675b..a25b7f2ea8a 100644 --- a/src/start/webAuth.js +++ b/src/start/webAuth.js @@ -3,7 +3,7 @@ import { NativeModules, Platform } from 'react-native'; import SafariView from 'react-native-safari-view'; import type { Auth } from '../types'; -import openLink from '../utils/openLink'; +import openLinkEmbedded from '../utils/openLinkEmbedded'; import { tryParseUrl } from '../utils/url'; import { base64ToHex, hexToAscii, xorHexStrings } from '../utils/encoding'; @@ -48,7 +48,7 @@ export const generateRandomToken = async (): Promise => { export const generateOtp = async (): Promise => generateRandomToken(); export const openBrowser = (url: string, otp: string) => { - openLink(`${url}?mobile_flow_otp=${otp}`); + openLinkEmbedded(`${url}?mobile_flow_otp=${otp}`); }; export const closeBrowser = () => { @@ -86,11 +86,11 @@ export const authFromCallbackUrl = (callbackUrl: string, otp: string, realm: URL const otpEncryptedApiKey = url.searchParams.get('otp_encrypted_api_key'); if ( - url.host === 'login' - && otp - && email !== null - && otpEncryptedApiKey !== null - && otpEncryptedApiKey.length === otp.length + url.host === 'login' && + otp && + email !== null && + otpEncryptedApiKey !== null && + otpEncryptedApiKey.length === otp.length ) { const apiKey = extractApiKey(otpEncryptedApiKey, otp); return { realm, email, apiKey }; diff --git a/src/utils/openLink.js b/src/utils/openLink.js index ee9144dbd03..6b0e5ee7297 100644 --- a/src/utils/openLink.js +++ b/src/utils/openLink.js @@ -1,11 +1,10 @@ /* @flow strict-local */ -import { NativeModules, Platform } from 'react-native'; -import SafariView from 'react-native-safari-view'; +import { NativeModules, Platform, Linking } from 'react-native'; export default (url: string): void => { if (Platform.OS === 'ios') { - SafariView.show({ url: encodeURI(url) }); + Linking.openURL(url); //open url in the browser } else { - NativeModules.CustomTabsAndroid.openURL(url); + NativeModules.CustomTabsAndroid.openURL(url); //open url in the embedded webview } }; diff --git a/src/utils/openLinkEmbedded.js b/src/utils/openLinkEmbedded.js new file mode 100644 index 00000000000..9b0f2d9575c --- /dev/null +++ b/src/utils/openLinkEmbedded.js @@ -0,0 +1,11 @@ +/* @flow strict-local */ +import { NativeModules, Platform } from 'react-native'; +import SafariView from 'react-native-safari-view'; + +export default (url: string): void => { + if (Platform.OS === 'ios') { + SafariView.show({ url: encodeURI(url) }); //open link in embedded webview + } else { + NativeModules.CustomTabsAndroid.openURL(url); //open link in embedded webview + } +};