5
5
AppState ,
6
6
Linking ,
7
7
NativeEventSubscription ,
8
+ NativeModules ,
8
9
Platform ,
9
10
} from 'react-native' ;
10
11
@@ -13,6 +14,32 @@ import { nativeModule } from '../nativeModule';
13
14
let appStateListener : NativeEventSubscription | undefined ;
14
15
let redirectListener : NativeEventSubscription | undefined ;
15
16
17
+ export async function isChromebook ( ) : Promise < boolean > {
18
+ // expo go
19
+ try {
20
+ const Device = require ( 'expo-device' ) ;
21
+ if ( Device ?. hasPlatformFeatureAsync ) {
22
+ if ( await Device . hasPlatformFeatureAsync ( 'org.chromium.arc' ) ) return true ;
23
+ if (
24
+ await Device . hasPlatformFeatureAsync (
25
+ 'org.chromium.arc.device_management' ,
26
+ )
27
+ )
28
+ return true ;
29
+ }
30
+ } catch {
31
+ // not using Expo
32
+ }
33
+
34
+ // fallback to native module
35
+ try {
36
+ const nm = ( NativeModules as any ) ?. ChromeOS ;
37
+ if ( nm ?. isChromeOS ) return ! ! ( await nm . isChromeOS ( ) ) ;
38
+ } catch { }
39
+
40
+ return false ;
41
+ }
42
+
16
43
export const openAuthSessionAsync = async (
17
44
url : string ,
18
45
redirectUrls : string [ ] ,
@@ -25,6 +52,15 @@ export const openAuthSessionAsync = async (
25
52
}
26
53
27
54
if ( Platform . OS === 'android' ) {
55
+ try {
56
+ const isChromebookRes = await isChromebook ( ) ;
57
+ if ( isChromebookRes ) {
58
+ return openAuthSessionChromeOs ( httpsUrl , redirectUrls ) ;
59
+ }
60
+ } catch {
61
+ // ignore and fallback to android
62
+ }
63
+
28
64
return openAuthSessionAndroid ( httpsUrl , redirectUrls ) ;
29
65
}
30
66
} ;
@@ -66,6 +102,27 @@ const openAuthSessionAndroid = async (url: string, redirectUrls: string[]) => {
66
102
}
67
103
} ;
68
104
105
+ const openAuthSessionChromeOs = async ( url : string , redirectUrls : string [ ] ) => {
106
+ try {
107
+ const [ redirectUrl ] = await Promise . all ( [
108
+ Promise . race ( [
109
+ // wait for app to redirect, resulting in a redirectUrl
110
+ getRedirectPromise ( redirectUrls ) ,
111
+ // wait for app to return some other way, resulting in null
112
+ getAppStatePromise ( ) ,
113
+ ] ) ,
114
+ Linking . openURL ( url ) ,
115
+ ] ) ;
116
+
117
+ if ( redirectUrl ) Linking . openURL ( redirectUrl ) ;
118
+
119
+ return redirectUrl ;
120
+ } finally {
121
+ removeAppStateListener ( ) ;
122
+ removeRedirectListener ( ) ;
123
+ }
124
+ } ;
125
+
69
126
const getAppStatePromise = ( ) : Promise < null > =>
70
127
new Promise ( resolve => {
71
128
// remove any stray listeners before creating new ones
0 commit comments