UNPKG

6.38 kBJavaScriptView Raw
1import { UnavailabilityError } from '@unimodules/core';
2import { AppState, Linking, Platform } from 'react-native';
3import ExponentWebBrowser from './ExpoWebBrowser';
4import { WebBrowserResultType, } from './WebBrowser.types';
5export { WebBrowserResultType, };
6const emptyCustomTabsPackages = {
7 defaultBrowserPackage: undefined,
8 preferredBrowserPackage: undefined,
9 browserPackages: [],
10 servicePackages: [],
11};
12export async function getCustomTabsSupportingBrowsersAsync() {
13 if (!ExponentWebBrowser.getCustomTabsSupportingBrowsersAsync) {
14 throw new UnavailabilityError('WebBrowser', 'getCustomTabsSupportingBrowsersAsync');
15 }
16 if (Platform.OS !== 'android') {
17 return emptyCustomTabsPackages;
18 }
19 else {
20 return await ExponentWebBrowser.getCustomTabsSupportingBrowsersAsync();
21 }
22}
23export async function warmUpAsync(browserPackage) {
24 if (!ExponentWebBrowser.warmUpAsync) {
25 throw new UnavailabilityError('WebBrowser', 'warmUpAsync');
26 }
27 if (Platform.OS !== 'android') {
28 return {};
29 }
30 else {
31 return await ExponentWebBrowser.warmUpAsync(browserPackage);
32 }
33}
34export async function mayInitWithUrlAsync(url, browserPackage) {
35 if (!ExponentWebBrowser.mayInitWithUrlAsync) {
36 throw new UnavailabilityError('WebBrowser', 'mayInitWithUrlAsync');
37 }
38 if (Platform.OS !== 'android') {
39 return {};
40 }
41 else {
42 return await ExponentWebBrowser.mayInitWithUrlAsync(url, browserPackage);
43 }
44}
45export async function coolDownAsync(browserPackage) {
46 if (!ExponentWebBrowser.coolDownAsync) {
47 throw new UnavailabilityError('WebBrowser', 'coolDownAsync');
48 }
49 if (Platform.OS !== 'android') {
50 return {};
51 }
52 else {
53 return await ExponentWebBrowser.coolDownAsync(browserPackage);
54 }
55}
56export async function openBrowserAsync(url, browserParams = {}) {
57 if (!ExponentWebBrowser.openBrowserAsync) {
58 throw new UnavailabilityError('WebBrowser', 'openBrowserAsync');
59 }
60 return await ExponentWebBrowser.openBrowserAsync(url, browserParams);
61}
62export function dismissBrowser() {
63 if (!ExponentWebBrowser.dismissBrowser) {
64 throw new UnavailabilityError('WebBrowser', 'dismissBrowser');
65 }
66 ExponentWebBrowser.dismissBrowser();
67}
68export async function openAuthSessionAsync(url, redirectUrl, browserParams = {}) {
69 if (_authSessionIsNativelySupported()) {
70 if (!ExponentWebBrowser.openAuthSessionAsync) {
71 throw new UnavailabilityError('WebBrowser', 'openAuthSessionAsync');
72 }
73 return ExponentWebBrowser.openAuthSessionAsync(url, redirectUrl);
74 }
75 else {
76 return _openAuthSessionPolyfillAsync(url, redirectUrl, browserParams);
77 }
78}
79export function dismissAuthSession() {
80 if (_authSessionIsNativelySupported()) {
81 if (!ExponentWebBrowser.dismissAuthSession) {
82 throw new UnavailabilityError('WebBrowser', 'dismissAuthSession');
83 }
84 ExponentWebBrowser.dismissAuthSession();
85 }
86 else {
87 if (!ExponentWebBrowser.dismissBrowser) {
88 throw new UnavailabilityError('WebBrowser', 'dismissAuthSession');
89 }
90 ExponentWebBrowser.dismissBrowser();
91 }
92}
93/* iOS <= 10 and Android polyfill for SFAuthenticationSession flow */
94function _authSessionIsNativelySupported() {
95 if (Platform.OS === 'android') {
96 return false;
97 }
98 const versionNumber = parseInt(String(Platform.Version), 10);
99 return versionNumber >= 11;
100}
101let _redirectHandler = null;
102/*
103 * openBrowserAsync on Android doesn't wait until closed, so we need to polyfill
104 * it with AppState
105 */
106// Store the `resolve` function from a Promise to fire when the AppState
107// returns to active
108let _onWebBrowserCloseAndroid = null;
109function _onAppStateChangeAndroid(state) {
110 if (state === 'active' && _onWebBrowserCloseAndroid) {
111 _onWebBrowserCloseAndroid();
112 }
113}
114async function _openBrowserAndWaitAndroidAsync(startUrl, browserParams = {}) {
115 let appStateChangedToActive = new Promise(resolve => {
116 _onWebBrowserCloseAndroid = resolve;
117 AppState.addEventListener('change', _onAppStateChangeAndroid);
118 });
119 let result = { type: 'cancel' };
120 let { type } = await openBrowserAsync(startUrl, browserParams);
121 if (type === 'opened') {
122 await appStateChangedToActive;
123 result = { type: 'dismiss' };
124 }
125 AppState.removeEventListener('change', _onAppStateChangeAndroid);
126 _onWebBrowserCloseAndroid = null;
127 return result;
128}
129async function _openAuthSessionPolyfillAsync(startUrl, returnUrl, browserParams = {}) {
130 if (_redirectHandler) {
131 throw new Error(`The WebBrowser's auth session is in an invalid state with a redirect handler set when it should not be`);
132 }
133 if (_onWebBrowserCloseAndroid) {
134 throw new Error(`WebBrowser is already open, only one can be open at a time`);
135 }
136 try {
137 if (Platform.OS === 'android') {
138 return await Promise.race([
139 _openBrowserAndWaitAndroidAsync(startUrl, browserParams),
140 _waitForRedirectAsync(returnUrl),
141 ]);
142 }
143 else {
144 return await Promise.race([
145 openBrowserAsync(startUrl, browserParams),
146 _waitForRedirectAsync(returnUrl),
147 ]);
148 }
149 }
150 finally {
151 // We can't dismiss the browser on Android, only call this when it's available.
152 // Users on Android need to manually press the 'x' button in Chrome Custom Tabs, sadly.
153 if (ExponentWebBrowser.dismissBrowser) {
154 ExponentWebBrowser.dismissBrowser();
155 }
156 _stopWaitingForRedirect();
157 }
158}
159function _stopWaitingForRedirect() {
160 if (!_redirectHandler) {
161 throw new Error(`The WebBrowser auth session is in an invalid state with no redirect handler when one should be set`);
162 }
163 Linking.removeEventListener('url', _redirectHandler);
164 _redirectHandler = null;
165}
166function _waitForRedirectAsync(returnUrl) {
167 return new Promise(resolve => {
168 _redirectHandler = (event) => {
169 if (event.url.startsWith(returnUrl)) {
170 resolve({ url: event.url, type: 'success' });
171 }
172 };
173 Linking.addEventListener('url', _redirectHandler);
174 });
175}
176//# sourceMappingURL=WebBrowser.js.map
\No newline at end of file