1- import { Linking } from 'react-native' ; // eslint-disable-line import/no-unresolved, max-len
1+ import { Linking , AppState } from 'react-native' ; // eslint-disable-line import/no-unresolved, max-len
22
3- let previousOnLinkChange ;
3+ let appStateTimeout ;
4+ let previousLinkingCallback ;
5+ let previousAppStateCallback ;
46
5- export const dance = ( authUrl ) => {
6- if ( previousOnLinkChange ) {
7- Linking . removeEventListener ( 'url' , previousOnLinkChange ) ;
7+ const cleanup = ( ) => {
8+ clearTimeout ( appStateTimeout ) ;
9+
10+ if ( previousLinkingCallback ) {
11+ Linking . removeEventListener ( 'url' , previousLinkingCallback ) ;
12+ previousLinkingCallback = null ;
813 }
914
15+ if ( previousAppStateCallback ) {
16+ AppState . removeEventListener ( 'change' , previousAppStateCallback ) ;
17+ previousAppStateCallback = null ;
18+ }
19+ } ;
20+
21+ export const dance = ( authUrl ) => {
22+ cleanup ( ) ;
23+
1024 return Linking . openURL ( authUrl )
1125 . then ( ( ) => new Promise ( ( resolve , reject ) => {
1226 const handleUrl = ( url ) => {
@@ -17,15 +31,26 @@ export const dance = (authUrl) => {
1731 }
1832 } ;
1933
20- const onLinkChange = ( { url } ) => {
21- Linking . removeEventListener ( 'url' , onLinkChange ) ;
22- previousOnLinkChange = undefined ;
34+ const linkingCallback = ( { url } ) => {
35+ cleanup ( ) ;
2336 handleUrl ( url ) ;
2437 } ;
2538
26- Linking . addEventListener ( 'url' , onLinkChange ) ;
39+ Linking . addEventListener ( 'url' , linkingCallback ) ;
40+ previousLinkingCallback = linkingCallback ;
41+
42+ const appStateCallback = ( state ) => {
43+ // Give time for Linking event to fire.
44+ appStateTimeout = setTimeout ( ( ) => {
45+ if ( state === 'active' ) {
46+ cleanup ( ) ;
47+ reject ( 'cancelled' ) ;
48+ }
49+ } , 100 ) ;
50+ } ;
2751
28- previousOnLinkChange = onLinkChange ;
52+ AppState . addEventListener ( 'change' , appStateCallback ) ;
53+ previousAppStateCallback = appStateCallback ;
2954 } ) ) ;
3055} ;
3156
0 commit comments