import { AppState, Linking, Platform } from 'react-native';
import { UnavailabilityError } from '@unimodules/core';
import ExponentWebBrowser from './ExpoWebBrowser';
const emptyCustomTabsPackages = {
defaultBrowserPackage: undefined,
preferredBrowserPackage: undefined,
browserPackages: [],
servicePackages: [],
};
export async function getCustomTabsSupportingBrowsersAsync() {
if (!ExponentWebBrowser.getCustomTabsSupportingBrowsersAsync) {
throw new UnavailabilityError('WebBrowser', 'getCustomTabsSupportingBrowsersAsync');
}
if (Platform.OS !== 'android') {
return emptyCustomTabsPackages;
}
else {
return await ExponentWebBrowser.getCustomTabsSupportingBrowsersAsync();
}
}
export async function warmUpAsync(browserPackage) {
if (!ExponentWebBrowser.warmUpAsync) {
throw new UnavailabilityError('WebBrowser', 'warmUpAsync');
}
if (Platform.OS !== 'android') {
return {};
}
else {
return await ExponentWebBrowser.warmUpAsync(browserPackage);
}
}
export async function mayInitWithUrlAsync(url, browserPackage) {
if (!ExponentWebBrowser.mayInitWithUrlAsync) {
throw new UnavailabilityError('WebBrowser', 'mayInitWithUrlAsync');
}
if (Platform.OS !== 'android') {
return {};
}
else {
return await ExponentWebBrowser.mayInitWithUrlAsync(url, browserPackage);
}
}
export async function coolDownAsync(browserPackage) {
if (!ExponentWebBrowser.coolDownAsync) {
throw new UnavailabilityError('WebBrowser', 'coolDownAsync');
}
if (Platform.OS !== 'android') {
return {};
}
else {
return await ExponentWebBrowser.coolDownAsync(browserPackage);
}
}
export async function openBrowserAsync(url, browserParams = {}) {
if (!ExponentWebBrowser.openBrowserAsync) {
throw new UnavailabilityError('WebBrowser', 'openBrowserAsync');
}
return await ExponentWebBrowser.openBrowserAsync(url, browserParams);
}
export function dismissBrowser() {
if (!ExponentWebBrowser.dismissBrowser) {
throw new UnavailabilityError('WebBrowser', 'dismissBrowser');
}
ExponentWebBrowser.dismissBrowser();
}
export async function openAuthSessionAsync(url, redirectUrl) {
if (_authSessionIsNativelySupported()) {
if (!ExponentWebBrowser.openAuthSessionAsync) {
throw new UnavailabilityError('WebBrowser', 'openAuthSessionAsync');
}
return ExponentWebBrowser.openAuthSessionAsync(url, redirectUrl);
}
else {
return _openAuthSessionPolyfillAsync(url, redirectUrl);
}
}
export function dismissAuthSession() {
if (_authSessionIsNativelySupported()) {
if (!ExponentWebBrowser.dismissAuthSession) {
throw new UnavailabilityError('WebBrowser', 'dismissAuthSession');
}
ExponentWebBrowser.dismissAuthSession();
}
else {
if (!ExponentWebBrowser.dismissBrowser) {
throw new UnavailabilityError('WebBrowser', 'dismissAuthSession');
}
ExponentWebBrowser.dismissBrowser();
}
}
/* iOS <= 10 and Android polyfill for SFAuthenticationSession flow */
function _authSessionIsNativelySupported() {
if (Platform.OS === 'android') {
return false;
}
const versionNumber = parseInt(String(Platform.Version), 10);
return versionNumber >= 11;
}
let _redirectHandler = null;
/*
* openBrowserAsync on Android doesn't wait until closed, so we need to polyfill
* it with AppState
*/
// Store the `resolve` function from a Promise to fire when the AppState
// returns to active
let _onWebBrowserCloseAndroid = null;
function _onAppStateChangeAndroid(state) {
if (state === 'active' && _onWebBrowserCloseAndroid) {
_onWebBrowserCloseAndroid();
}
}
async function _openBrowserAndWaitAndroidAsync(startUrl) {
let appStateChangedToActive = new Promise(resolve => {
_onWebBrowserCloseAndroid = resolve;
AppState.addEventListener('change', _onAppStateChangeAndroid);
});
let result = { type: 'cancel' };
let { type } = await openBrowserAsync(startUrl);
if (type === 'opened') {
await appStateChangedToActive;
result = { type: 'dismiss' };
}
AppState.removeEventListener('change', _onAppStateChangeAndroid);
_onWebBrowserCloseAndroid = null;
return result;
}
async function _openAuthSessionPolyfillAsync(startUrl, returnUrl) {
if (_redirectHandler) {
throw new Error(`The WebBrowser's auth session is in an invalid state with a redirect handler set when it should not be`);
}
if (_onWebBrowserCloseAndroid) {
throw new Error(`WebBrowser is already open, only one can be open at a time`);
}
try {
if (Platform.OS === 'android') {
return await Promise.race([
_openBrowserAndWaitAndroidAsync(startUrl),
_waitForRedirectAsync(returnUrl),
]);
}
else {
return await Promise.race([openBrowserAsync(startUrl), _waitForRedirectAsync(returnUrl)]);
}
}
finally {
// We can't dismiss the browser on Android, only call this when it's available.
// Users on Android need to manually press the 'x' button in Chrome Custom Tabs, sadly.
if (ExponentWebBrowser.dismissBrowser) {
ExponentWebBrowser.dismissBrowser();
}
_stopWaitingForRedirect();
}
}
function _stopWaitingForRedirect() {
if (!_redirectHandler) {
throw new Error(`The WebBrowser auth session is in an invalid state with no redirect handler when one should be set`);
}
Linking.removeEventListener('url', _redirectHandler);
_redirectHandler = null;
}
function _waitForRedirectAsync(returnUrl) {
return new Promise(resolve => {
_redirectHandler = (event) => {
if (event.url.startsWith(returnUrl)) {
resolve({ url: event.url, type: 'success' });
}
};
Linking.addEventListener('url', _redirectHandler);
});
}
//# sourceMappingURL=WebBrowser.js.map