Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/store/app/app.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,43 @@ export const startInAppNotification =
dispatch(AppActions.showInAppNotification(context, _message, request));
};

/**
* Dismiss the native InAppBrowser, but only if we actually opened one via
* openUrlWithInAppBrowser (tracked in APP.inAppBrowserOpen). Some flows (e.g.
* Buy/Sell) render their own in-app WebView modal
* instead of the native IAB. Calling InAppBrowser.close() unconditionally
* (e.g. whenever a bitpay:// deep link is received) can dismiss whatever modal happens to be
* presented at that moment - including that unrelated WebView modal - since
* the underlying native module simply dismisses the topmost presented
* screen rather than a specific tracked IAB session.
*/
export const dismissInAppBrowserIfOpen =
(): Effect<void> => async (dispatch, getState) => {
const {APP} = getState();
if (!APP.inAppBrowserOpen) {
logManager.debug(
'[dismissInAppBrowserIfOpen] IAB not open, skipping close',
);
return;
}
logManager.debug(
'[dismissInAppBrowserIfOpen] IAB is open, attempting close...',
);
try {
const isAvailable = await InAppBrowser.isAvailable();
if (isAvailable) {
await InAppBrowser.close();
}
} catch (err) {
const errStr = err instanceof Error ? err.message : JSON.stringify(err);
logManager.error(
'[dismissInAppBrowserIfOpen] Error closing IAB: ' + errStr,
);
} finally {
dispatch(AppActions.setInAppBrowserOpen(false));
}
};

/**
* Open a URL with the InAppBrowser if available, else lets the device handle the URL.
* @param url
Expand Down
20 changes: 5 additions & 15 deletions src/utils/hooks/useDeeplinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
import {useMemo, useRef} from 'react';
import {DeviceEventEmitter, Linking, NativeModules} from 'react-native';
import AppsFlyer from 'react-native-appsflyer';
import InAppBrowser from 'react-native-inappbrowser-reborn';
import {
APP_CRYPTO_PREFIX,
APP_DEEPLINK_PREFIX,
Expand All @@ -21,8 +20,10 @@ import {navigationRef, RootStackParamList, RootStacks} from '../../Root';
import {TabsScreens, TabsStackParamList} from '../../navigation/tabs/TabsStack';
import {incomingData} from '../../store/scan/scan.effects';
import {showBlur} from '../../store/app/app.actions';
import {AppActions} from '../../store/app';
import {incomingLink} from '../../store/app/app.effects';
import {
dismissInAppBrowserIfOpen,
incomingLink,
} from '../../store/app/app.effects';
import useAppDispatch from './useAppDispatch';
import {useLogger} from './useLogger';
import {DebugScreens} from '../../navigation/Debug';
Expand Down Expand Up @@ -126,18 +127,7 @@ export const useUrlEventHandler = () => {
}
}

try {
// clicking a deeplink from the IAB in iOS doesn't auto-close the IAB, so do it manually
InAppBrowser.isAvailable().then(isAvailable => {
if (isAvailable) {
InAppBrowser.close();
dispatch(AppActions.setInAppBrowserOpen(false));
}
});
} catch (err) {
const errStr = err instanceof Error ? err.message : JSON.stringify(err);
logger.error('[deeplink] not available from IAB: ' + errStr);
}
dispatch(dismissInAppBrowserIfOpen());

return handled;
}
Expand Down