diff --git a/src/AppOnboarded.tsx b/src/AppOnboarded.tsx index 6c5ec91a6..fb21bab9f 100644 --- a/src/AppOnboarded.tsx +++ b/src/AppOnboarded.tsx @@ -60,6 +60,8 @@ const AppOnboarded = (): ReactElement => { const appStateSubscription = AppState.addEventListener( 'change', (nextAppState) => { + dispatch(updateUi({ appState: nextAppState })); + // on App to foreground if ( appState.current.match(/inactive|background/) && diff --git a/src/screens/Wallets/Receive/ReceiveQR.tsx b/src/screens/Wallets/Receive/ReceiveQR.tsx index 383eaf9b6..60e2d4f90 100644 --- a/src/screens/Wallets/Receive/ReceiveQR.tsx +++ b/src/screens/Wallets/Receive/ReceiveQR.tsx @@ -41,6 +41,7 @@ import { createLightningInvoice } from '../../../store/utils/lightning'; import { updatePendingInvoice } from '../../../store/slices/metadata'; import { generateNewReceiveAddress } from '../../../store/actions/wallet'; import { + appStateSelector, isLDKReadySelector, viewControllerIsOpenSelector, } from '../../../store/reselect/ui'; @@ -93,6 +94,7 @@ const ReceiveQR = ({ const addressType = useAppSelector(addressTypeSelector); const isGeoBlocked = useAppSelector(isGeoBlockedSelector); const isLDKReady = useAppSelector(isLDKReadySelector); + const appState = useAppSelector(appStateSelector); const { id, amount, message, tags, jitOrder } = useAppSelector(receiveSelector); const lightningBalance = useLightningBalance(false); @@ -244,6 +246,16 @@ const ReceiveQR = ({ dispatch, ]); + useEffect(() => { + if (receiveNavigationIsOpen && enableInstant && appState !== 'active') { + showToast({ + type: 'error', + title: t('receive_foreground_title'), + description: t('receive_foreground_msg'), + }); + } + }, [t, appState, enableInstant, receiveNavigationIsOpen]); + const uri = useMemo((): string => { if (!receiveNavigationIsOpen) { return ''; diff --git a/src/store/reselect/ui.ts b/src/store/reselect/ui.ts index 31e2e36d9..d52ed0c2a 100644 --- a/src/store/reselect/ui.ts +++ b/src/store/reselect/ui.ts @@ -110,3 +110,5 @@ export const fromAddressViewerSelector = createSelector( [uiState], (ui) => ui.fromAddressViewer, ); + +export const appStateSelector = createSelector([uiState], (ui) => ui.appState); diff --git a/src/store/shapes/ui.ts b/src/store/shapes/ui.ts index 98fb4ad1a..8f1a94f9a 100644 --- a/src/store/shapes/ui.ts +++ b/src/store/shapes/ui.ts @@ -43,4 +43,5 @@ export const initialUiState: TUiState = { viewControllers: defaultViewControllers, fromAddressViewer: false, // When true, ensures tx inputs are not cleared when sweeping from address viewer. paymentMethod: 'onchain', + appState: 'active', }; diff --git a/src/store/types/ui.ts b/src/store/types/ui.ts index b9937f8e3..a99d609aa 100644 --- a/src/store/types/ui.ts +++ b/src/store/types/ui.ts @@ -1,3 +1,4 @@ +import { AppStateStatus } from 'react-native'; import { LNURLWithdrawParams, LNURLPayParams } from 'js-lnurl'; import { EActivityType, TOnchainActivityItem } from './activity'; import { ReceiveStackParamList } from '../../navigation/bottom-sheet/ReceiveNavigation'; @@ -91,4 +92,5 @@ export type TUiState = { language: string; fromAddressViewer: boolean; paymentMethod: 'onchain' | 'lightning'; + appState: AppStateStatus; }; diff --git a/src/utils/i18n/locales/en/wallet.json b/src/utils/i18n/locales/en/wallet.json index 86f589536..7fcef6444 100644 --- a/src/utils/i18n/locales/en/wallet.json +++ b/src/utils/i18n/locales/en/wallet.json @@ -686,5 +686,13 @@ }, "receive_insufficient_text": { "string": "Insufficient receiving capacity to receive this amount over Lightning." + }, + "receive_foreground_title": { + "string": "Keep Bitkit In Foreground", + "developer_comment": "This message appears when the user is shown an LN invoice but tries to switch to another app" + }, + "receive_foreground_msg": { + "string": "Payments to your spending balance might fail if you switch between apps.", + "developer_comment": "This message appears when the user is shown an LN invoice but tries to switch to another app" } }