From e4a5686284c6626a505daf05686c348a47925673 Mon Sep 17 00:00:00 2001 From: dominhquang Date: Wed, 16 Aug 2023 18:38:12 +0700 Subject: [PATCH] [Issue-199]: Add the lost internet connection screen --- src/components/NoInternetAlertBox.tsx | 19 +++++++++++++ src/hooks/balance/useGetBalance.ts | 9 +++++- src/screens/Home/index.tsx | 28 ++++++++++++++++--- src/screens/ImportNetwork.tsx | 7 ++++- src/screens/ImportToken/ImportToken.tsx | 11 +++++--- .../Transaction/CancelUnstake/index.tsx | 8 ++++-- src/screens/Transaction/ClaimReward/index.tsx | 7 ++++- src/screens/Transaction/NFT/index.tsx | 3 +- src/screens/Transaction/SendFundV2/index.tsx | 7 ++++- src/screens/Transaction/Stake/index.tsx | 9 ++++-- src/screens/Transaction/Unbond/index.tsx | 7 ++++- src/screens/Transaction/Withdraw/index.tsx | 7 ++++- src/utils/i18n/en_US.ts | 2 ++ src/utils/i18n/vi_VN.ts | 2 ++ src/utils/i18n/zh_CN.ts | 2 ++ 15 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 src/components/NoInternetAlertBox.tsx diff --git a/src/components/NoInternetAlertBox.tsx b/src/components/NoInternetAlertBox.tsx new file mode 100644 index 000000000..0c1fe7125 --- /dev/null +++ b/src/components/NoInternetAlertBox.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { View } from 'react-native'; +import AlertBox from 'components/design-system-ui/alert-box'; + +interface Props { + marginTop?: number; +} + +export const NoInternetAlertBox = ({ marginTop = 16 }: Props) => { + return ( + + + + ); +}; diff --git a/src/hooks/balance/useGetBalance.ts b/src/hooks/balance/useGetBalance.ts index 308bf5537..81642744e 100644 --- a/src/hooks/balance/useGetBalance.ts +++ b/src/hooks/balance/useGetBalance.ts @@ -1,11 +1,12 @@ import { _ChainInfo } from '@subwallet/chain-list/types'; import { AmountData } from '@subwallet/extension-base/background/KoniTypes'; import { _getChainNativeTokenSlug } from '@subwallet/extension-base/services/chain-service/utils'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import { RootState } from 'stores/index'; import { getFreeBalance, updateAssetSetting } from 'messaging/index'; import i18n from 'utils/i18n/i18n'; +import { WebRunnerContext } from 'providers/contexts'; const DEFAULT_BALANCE = { value: '0', symbol: '', decimals: 18 }; @@ -24,6 +25,7 @@ const useGetBalance = (chain = '', address = '', tokenSlug = '') => { const isChainActive = chainStateMap[chain]?.active; const nativeTokenActive = nativeTokenSlug && assetSettingMap[nativeTokenSlug]?.visible; const isTokenActive = assetSettingMap[tokenSlug]?.visible; + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const refreshBalance = useCallback(() => { setIsRefresh({}); @@ -33,6 +35,10 @@ const useGetBalance = (chain = '', address = '', tokenSlug = '') => { let cancel = false; setIsLoading(true); + + if (!isNetConnected) { + return; + } setTokenBalance(DEFAULT_BALANCE); if (address && chain) { @@ -126,6 +132,7 @@ const useGetBalance = (chain = '', address = '', tokenSlug = '') => { isChainActive, isTokenActive, nativeTokenActive, + isNetConnected, ]); return { refreshBalance, tokenBalance, nativeTokenBalance, nativeTokenSlug, isLoading, error }; diff --git a/src/screens/Home/index.tsx b/src/screens/Home/index.tsx index 4c8a9471e..79d103046 100644 --- a/src/screens/Home/index.tsx +++ b/src/screens/Home/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { BottomTabBarButtonProps, createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import StakingScreen from './Staking/StakingScreen'; @@ -6,8 +6,8 @@ import { Linking, Platform, StyleSheet, TouchableOpacity, View } from 'react-nat import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { Aperture, Database, Globe, Rocket, Wallet } from 'phosphor-react-native'; import { CryptoScreen } from 'screens/Home/Crypto'; -import { FontMedium } from 'styles/sharedStyles'; -import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { FontMedium, FontSemiBold } from 'styles/sharedStyles'; +import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'; import { BOTTOM_BAR_HEIGHT, deviceWidth } from 'constants/index'; import { ColorMap } from 'styles/color'; import useCheckEmptyAccounts from 'hooks/useCheckEmptyAccounts'; @@ -20,7 +20,7 @@ import withPageWrapper from 'components/pageWrapper'; import RequestCreateMasterPasswordModal from 'screens/MasterPassword/RequestCreateMasterPasswordModal'; import { useDispatch, useSelector } from 'react-redux'; import { RootState } from 'stores/index'; -import { ActivityIndicator } from 'components/design-system-ui'; +import { ActivityIndicator, Typography } from 'components/design-system-ui'; import { useSubWalletTheme } from 'hooks/useSubWalletTheme'; import useAppLock from 'hooks/useAppLock'; import { createDrawerNavigator, DrawerContentComponentProps } from '@react-navigation/drawer'; @@ -35,6 +35,7 @@ import { updateIsDeepLinkConnect } from 'stores/base/Settings'; import queryString from 'querystring'; import { connectWalletConnect } from 'utils/walletConnect'; import { useToast } from 'react-native-toast-notifications'; +import { WebRunnerContext } from 'providers/contexts'; interface tabbarIconColor { color: string; @@ -185,6 +186,17 @@ export const Home = ({ navigation }: Props) => { const isFirstOpen = useRef(true); const toast = useToast(); const dispatch = useDispatch(); + const theme = useSubWalletTheme().swThemes; + const { isNetConnected } = useContext(WebRunnerContext); + const [showNoInternetAlert, setShowNoInternetAlert] = useState(!isNetConnected); + + useEffect(() => { + if (isNetConnected) { + setTimeout(() => setShowNoInternetAlert(false), 3000); + } else { + setShowNoInternetAlert(true); + } + }, [isNetConnected]); useEffect(() => { if (isReady && isLoading) { @@ -246,6 +258,14 @@ export const Home = ({ navigation }: Props) => { <> {!isLocked && } + {showNoInternetAlert && ( + + + {isNetConnected ? 'Internet connected' : 'No internet connection'} + + + + )} ); }; diff --git a/src/screens/ImportNetwork.tsx b/src/screens/ImportNetwork.tsx index 37ebf614c..eb7ba9437 100644 --- a/src/screens/ImportNetwork.tsx +++ b/src/screens/ImportNetwork.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import useFormControl from 'hooks/screen/useFormControl'; import { ContainerWithSubHeader } from 'components/ContainerWithSubHeader'; import { Keyboard, View } from 'react-native'; @@ -26,6 +26,8 @@ import { _NetworkUpsertParams } from '@subwallet/extension-base/services/chain-s import { useToast } from 'react-native-toast-notifications'; import { HIDE_MODAL_DURATION } from 'constants/index'; import i18n from 'utils/i18n/i18n'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; interface ValidationInfo { status: ValidateStatus; @@ -43,6 +45,7 @@ export const ImportNetwork = () => { const [genesisHash, setGenesisHash] = useState(''); const [existentialDeposit, setExistentialDeposit] = useState('0'); const toast = useToast(); + const { isNetConnected } = useContext(WebRunnerContext); const handleErrorMessage = useCallback((errorCode: _CHAIN_VALIDATION_ERROR) => { switch (errorCode) { @@ -367,6 +370,8 @@ export const ImportNetwork = () => { onSubmitField={onSubmitField('crowdloanUrl')} onChangeText={onChangeValue('crowdloanUrl')} /> + + {!isNetConnected && } diff --git a/src/screens/ImportToken/ImportToken.tsx b/src/screens/ImportToken/ImportToken.tsx index de43a3ddc..2954ef2bf 100644 --- a/src/screens/ImportToken/ImportToken.tsx +++ b/src/screens/ImportToken/ImportToken.tsx @@ -38,6 +38,7 @@ import { Plus } from 'phosphor-react-native'; import { TokenTypeSelectField } from 'components/Field/TokenTypeSelect'; import { ModalRef } from 'types/modalRef'; import { ChainSelector } from 'components/Modal/common/ChainSelector'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; interface TokenTypeOption { label: string; @@ -364,10 +365,6 @@ export const ImportToken = ({ route: { params: routeParams } }: ImportTokenProps - {!isNetConnected && ( - - )} - {!isReady && ( )} @@ -390,6 +387,12 @@ export const ImportToken = ({ route: { params: routeParams } }: ImportTokenProps )} + {!isNetConnected && ( + + )} + { diff --git a/src/screens/Transaction/CancelUnstake/index.tsx b/src/screens/Transaction/CancelUnstake/index.tsx index 0182f7cc2..7a319be29 100644 --- a/src/screens/Transaction/CancelUnstake/index.tsx +++ b/src/screens/Transaction/CancelUnstake/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { StakingScreenNavigationProps } from 'routes/staking/stakingScreen'; import { NominatorMetadata, StakingType } from '@subwallet/extension-base/background/KoniTypes'; import { useNavigation } from '@react-navigation/native'; @@ -26,6 +26,8 @@ import { CancelUnstakeProps } from 'routes/transaction/transactionAction'; import i18n from 'utils/i18n/i18n'; import { ModalRef } from 'types/modalRef'; import { AccountSelector } from 'components/Modal/common/AccountSelector'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; const filterAccount = ( chainInfoMap: Record, @@ -52,7 +54,7 @@ export const CancelUnstake = ({ const navigation = useNavigation(); const theme = useSubWalletTheme().swThemes; const { isAllAccount, accounts } = useSelector((state: RootState) => state.accountState); - + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const { chainInfoMap } = useSelector((state: RootState) => state.chainStore); const cancelUnstakeFormConfig = { @@ -137,6 +139,8 @@ export const CancelUnstake = ({ onSelectItem={onChangeValue('unstakeIndex')} disabled={loading} /> + + {!isNetConnected && } diff --git a/src/screens/Transaction/ClaimReward/index.tsx b/src/screens/Transaction/ClaimReward/index.tsx index ae8c44f4d..e24566ceb 100644 --- a/src/screens/Transaction/ClaimReward/index.tsx +++ b/src/screens/Transaction/ClaimReward/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useTransaction } from 'hooks/screen/Transaction/useTransaction'; import { useNavigation } from '@react-navigation/native'; import { StakingScreenNavigationProps } from 'routes/staking/stakingScreen'; @@ -36,6 +36,8 @@ import { ClaimRewardProps } from 'routes/transaction/transactionAction'; import i18n from 'utils/i18n/i18n'; import { ModalRef } from 'types/modalRef'; import { AccountSelector } from 'components/Modal/common/AccountSelector'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; const filterAccount = ( chainInfoMap: Record, @@ -126,6 +128,7 @@ const ClaimReward = ({ const [isDisabled, setIsDisabled] = useState(true); const { onError, onSuccess } = useHandleSubmitTransaction(onDone); const accountInfo = useGetAccountByAddress(from); + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const onSubmit = useCallback(() => { setLoading(true); @@ -210,6 +213,8 @@ const ClaimReward = ({ }} checkBoxSize={20} /> + + {!isNetConnected && } diff --git a/src/screens/Transaction/NFT/index.tsx b/src/screens/Transaction/NFT/index.tsx index 869523a64..787142852 100644 --- a/src/screens/Transaction/NFT/index.tsx +++ b/src/screens/Transaction/NFT/index.tsx @@ -35,6 +35,7 @@ import { RootNavigationProps } from 'routes/index'; import { InputAddress } from 'components/Input/InputAddressV2'; import useGetChainPrefixBySlug from 'hooks/chain/useGetChainPrefixBySlug'; import { SendNFTProps } from 'routes/transaction/transactionAction'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; const DEFAULT_ITEM: NftItem = { collectionId: 'unknown', @@ -248,7 +249,7 @@ const SendNFT: React.FC = ({ )} - {!isNetConnected && } + {!isNetConnected && } diff --git a/src/screens/Transaction/SendFundV2/index.tsx b/src/screens/Transaction/SendFundV2/index.tsx index b1109a990..c617a2c5a 100644 --- a/src/screens/Transaction/SendFundV2/index.tsx +++ b/src/screens/Transaction/SendFundV2/index.tsx @@ -14,7 +14,7 @@ import { import { SWTransactionResponse } from '@subwallet/extension-base/services/transaction-service/types'; import { addLazy, isSameAddress, removeLazy } from '@subwallet/extension-base/utils'; import BigN from 'bignumber.js'; -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { BN, BN_ZERO } from '@polkadot/util'; import { isAddress, isEthereumAddress } from '@polkadot/util-crypto'; @@ -69,6 +69,8 @@ import createStylesheet from './styles'; import { useGetBalance } from 'hooks/balance'; import { FreeBalanceDisplay } from 'screens/Transaction/parts/FreeBalanceDisplay'; import { ModalRef } from 'types/modalRef'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; interface TransferFormValues extends TransactionFormValues { to: string; @@ -316,6 +318,7 @@ export const SendFund = ({ const accountSelectorRef = useRef(); const tokenSelectorRef = useRef(); const chainSelectorRef = useRef(); + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const { title, @@ -1000,6 +1003,8 @@ export const SendFund = ({ )} )} + + {!isNetConnected && } diff --git a/src/screens/Transaction/Stake/index.tsx b/src/screens/Transaction/Stake/index.tsx index d60c6f85d..fdb68200a 100644 --- a/src/screens/Transaction/Stake/index.tsx +++ b/src/screens/Transaction/Stake/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { ScrollView, View } from 'react-native'; import { StakingTab } from 'components/common/StakingTab'; import { TokenSelectField } from 'components/Field/TokenSelect'; @@ -48,6 +48,8 @@ import useFetchChainState from 'hooks/screen/useFetchChainState'; import i18n from 'utils/i18n/i18n'; import { ModalRef } from 'types/modalRef'; import { AccountSelector } from 'components/Modal/common/AccountSelector'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; export const Stake = ({ route: { @@ -67,6 +69,7 @@ export const Stake = ({ const [isBalanceReady, setIsBalanceReady] = useState(true); const accountSelectorRef = useRef(); const tokenSelectorRef = useRef(); + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const defaultStakingType: StakingType = useMemo(() => { if (isEthAdr) { @@ -432,7 +435,7 @@ export const Stake = ({ subLogoKey={chain} value={symbol} showIcon - outerStyle={stakingChain !== ALL_KEY || !from || loading} + // outerStyle={stakingChain !== ALL_KEY || !from || loading} /> )} /> @@ -484,6 +487,8 @@ export const Stake = ({ {getMetaInfo()} )} + + {!isNetConnected && } diff --git a/src/screens/Transaction/Unbond/index.tsx b/src/screens/Transaction/Unbond/index.tsx index 99441992b..b3154bbd9 100644 --- a/src/screens/Transaction/Unbond/index.tsx +++ b/src/screens/Transaction/Unbond/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useTransaction } from 'hooks/screen/Transaction/useTransaction'; import { useSelector } from 'react-redux'; import { RootState } from 'stores/index'; @@ -39,6 +39,8 @@ import { UnbondProps } from 'routes/transaction/transactionAction'; import i18n from 'utils/i18n/i18n'; import { ModalRef } from 'types/modalRef'; import { AccountSelector } from 'components/Modal/common/AccountSelector'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; const _accountFilterFunc = ( allNominator: NominatorMetadata[], @@ -92,6 +94,7 @@ export const Unbond = ({ return undefined; } }, [currentValidator, nominatorMetadata]); + const isNetConnected = useContext(WebRunnerContext).isNetConnected; const mustChooseValidator = useMemo(() => { return isActionFromValidator(stakingType, stakingChain || ''); @@ -299,6 +302,8 @@ export const Unbond = ({ }}> {i18n.message.unBondMessage(unBondedTime)} + + {!isNetConnected && } diff --git a/src/screens/Transaction/Withdraw/index.tsx b/src/screens/Transaction/Withdraw/index.tsx index f3bb48ba5..5d0b3494c 100644 --- a/src/screens/Transaction/Withdraw/index.tsx +++ b/src/screens/Transaction/Withdraw/index.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useNavigation } from '@react-navigation/native'; import { StakingScreenNavigationProps } from 'routes/staking/stakingScreen'; import { useTransaction } from 'hooks/screen/Transaction/useTransaction'; @@ -38,6 +38,8 @@ import { ModalRef } from 'types/modalRef'; import { AccountSelector } from 'components/Modal/common/AccountSelector'; import { getAstarWithdrawable } from '@subwallet/extension-base/koni/api/staking/bonding/astar'; import { _STAKING_CHAIN_GROUP } from '@subwallet/extension-base/services/chain-service/constants'; +import { WebRunnerContext } from 'providers/contexts'; +import { NoInternetAlertBox } from 'components/NoInternetAlertBox'; const filterAccount = ( chainInfoMap: Record, @@ -77,6 +79,7 @@ export const Withdraw = ({ const accountInfo = useGetAccountByAddress(from); const { onError, onSuccess } = useHandleSubmitTransaction(onDone); const accountSelectorRef = useRef(); + const isNetConnected = useContext(WebRunnerContext).isNetConnected; useEffect(() => { // Trick to trigger validate when case single account @@ -171,6 +174,8 @@ export const Withdraw = ({ /> )} + + {!isNetConnected && } diff --git a/src/utils/i18n/en_US.ts b/src/utils/i18n/en_US.ts index 556da2a34..39fc8a9cf 100644 --- a/src/utils/i18n/en_US.ts +++ b/src/utils/i18n/en_US.ts @@ -974,6 +974,7 @@ export const en = { updateNetwork: 'Update network', expiredConnectionTitle: 'Connection expired', unsupportedNetworkTitle: 'Unsupported network', + noInternetConnection: 'No internet connection', }, warningMessage: { passwordTooShort: 'Password is too short', @@ -1011,6 +1012,7 @@ export const en = { 'The network you selected has not enable. Please enable by click this button or choose other network', expiredConnectionMessage: 'Connection expired. Please create a new connection from dApp', unsupportedNetworkMessage: 'There is at least 1 chosen network unavailable', + noInternetConnectionMessage: 'Please, check your connection or try again later', }, errorMessage: { invalidPinCode: 'Invalid PIN Code', diff --git a/src/utils/i18n/vi_VN.ts b/src/utils/i18n/vi_VN.ts index 2b1435911..a3e358841 100644 --- a/src/utils/i18n/vi_VN.ts +++ b/src/utils/i18n/vi_VN.ts @@ -973,6 +973,7 @@ export const vi = { updateNetwork: 'Cập nhật mạng', expiredConnectionTitle: 'Connection expired', unsupportedNetworkTitle: 'Unsupported network', + noInternetConnection: 'No internet connection', }, warningMessage: { passwordTooShort: 'Mật khẩu quá ngắn', @@ -1010,6 +1011,7 @@ export const vi = { 'Mạng bạn đã chọn chưa được kích hoạt. Vui lòng nhấp vào nút này để bật mạng hoặc chọn mạng khác', expiredConnectionMessage: 'Connection expired. Please create a new connection from dApp', unsupportedNetworkMessage: 'There is at least 1 chosen network unavailable', + noInternetConnectionMessage: 'Please, check your connection or try again later', }, errorMessage: { invalidPinCode: 'Mã PIN không hợp lệ', diff --git a/src/utils/i18n/zh_CN.ts b/src/utils/i18n/zh_CN.ts index 8aa111080..1ea7bb771 100644 --- a/src/utils/i18n/zh_CN.ts +++ b/src/utils/i18n/zh_CN.ts @@ -964,6 +964,7 @@ export const zh = { updateNetwork: '更新网络', expiredConnectionTitle: 'Connection expired', unsupportedNetworkTitle: 'Unsupported network', + noInternetConnection: 'No internet connection', }, warningMessage: { passwordTooShort: '密码过短', @@ -996,6 +997,7 @@ export const zh = { enableNetworkMessage: '你选择的网络尚未启用。 请点击此按钮启用或选择其他网络', expiredConnectionMessage: 'Connection expired. Please create a new connection from dApp', unsupportedNetworkMessage: 'There is at least 1 chosen network unavailable', + noInternetConnectionMessage: 'Please, check your connection or try again later', }, errorMessage: { invalidPinCode: 'PIN码无效',