diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 4b49e6ff0a..e55d54f88e 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -21,6 +21,6 @@ class TapApplication : Application() { if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } - NetworkConnectivity(store, this) + NetworkConnectivity.createInstance(store, this) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt index 63b2b4ef43..216a6c2053 100644 --- a/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TapWalletManager.kt @@ -11,6 +11,7 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.domain.tasks.ScanNoteResponse import com.tangem.tap.features.wallet.redux.PayIdState import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.coinmarketcap.CoinMarketCapService import com.tangem.tap.store import kotlinx.coroutines.Dispatchers @@ -71,6 +72,10 @@ class TapWalletManager { withContext(Dispatchers.Main) { store.dispatch(GlobalAction.SaveScanNoteResponse(data)) if (data.walletManager != null) { + if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + store.dispatch(WalletAction.LoadData.NoInternetConnection) + return@withContext + } data.verifyResponse?.artworkInfo?.id?.let { store.dispatch(WalletAction.LoadArtwork(data.card, it)) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 7923065e3a..4d37900796 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -12,42 +12,51 @@ import java.math.BigDecimal sealed class WalletAction : Action { - object LoadData : WalletAction() + object LoadData : WalletAction() { + object NoInternetConnection : WalletAction() + } object LoadWallet : WalletAction() { - data class Success(val wallet: Wallet): WalletAction() - data class NoAccount(val amountToCreateAccount: Int): WalletAction() - data class Failure(val errorMessage: String? = null): WalletAction() + data class Success(val wallet: Wallet) : WalletAction() + data class NoAccount(val amountToCreateAccount: Int) : WalletAction() + data class Failure(val errorMessage: String? = null) : WalletAction() } + object LoadFiatRate : WalletAction() { data class Success(val fiatRates: Pair) : WalletAction() - object Failure: WalletAction() + object Failure : WalletAction() } + object LoadPayId : WalletAction() { - data class Success(val payId: String): WalletAction() - object NotCreated: WalletAction() - object Failure: WalletAction() + data class Success(val payId: String) : WalletAction() + object NotCreated : WalletAction() + object Failure : WalletAction() } + data class LoadArtwork(val card: Card, val artworkId: String) : WalletAction() { data class Success(val artworkId: String, val artwork: ByteArray) : WalletAction() - object Failure: WalletAction() + object Failure : WalletAction() } + object Scan : WalletAction() object Send : WalletAction() object CreatePayId : WalletAction() { - data class CompleteCreatingPayId(val payId: String): WalletAction() - data class Success(val payId: String): WalletAction() - object EmptyField: WalletAction(), ErrorAction { + data class CompleteCreatingPayId(val payId: String) : WalletAction() + data class Success(val payId: String) : WalletAction() + object EmptyField : WalletAction(), ErrorAction { override val error = TapError.PayIdEmptyField } + class Failure(override val error: TapError) : WalletAction(), ErrorAction - object Cancel: WalletAction() + object Cancel : WalletAction() } + data class CopyAddress(val context: Context) : WalletAction() { object Success : WalletAction(), NotificationAction { override val messageResource = R.string.notification_address_copied } } + object ShowQrCode : WalletAction() object HideQrCode : WalletAction() data class ExploreAddress(val context: Context) : WalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt index 643df319d3..3cc142d37f 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletMiddleware.kt @@ -10,6 +10,7 @@ import com.tangem.tap.common.extensions.copyToClipboard import com.tangem.tap.common.redux.AppState import com.tangem.tap.domain.PayIdManager import com.tangem.tap.domain.TapError +import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager @@ -90,7 +91,7 @@ val walletMiddleware: Middleware = { dispatch, state -> } } } - is WalletAction.LoadData -> { + is WalletAction.LoadData, is NetworkStateChanged -> { scope.launch { store.state.globalState.scanNoteResponse?.let { store.state.globalState.tapWalletManager.onCardScanned(it) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt index 8690115296..5c832714be 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletReducer.kt @@ -31,6 +31,23 @@ private fun internalReduce(action: Action, state: AppState): WalletState { currencyData = BalanceWidgetData(BalanceStatus.EmptyCard), mainButton = WalletMainButton.CreateWalletButton(true) ) + is WalletAction.LoadData.NoInternetConnection -> { + val wallet = state.globalState.scanNoteResponse?.walletManager?.wallet + val addressData = if (wallet == null) { + null + } else { + AddressData(wallet.address, wallet.shareUrl, wallet.exploreUrl) + } + newState = WalletState( + state = ProgressState.Error, + error = ErrorType.NoInternetConnection, + addressData = addressData, + currencyData = BalanceWidgetData( + status = BalanceStatus.Unreachable, + currency = wallet?.blockchain?.fullName), + mainButton = WalletMainButton.SendButton(false) + ) + } is WalletAction.LoadWallet -> { val wallet = state.globalState.scanNoteResponse?.walletManager?.wallet val addressData = if (wallet == null) { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt index 4144388fef..120ab1a281 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletState.kt @@ -9,6 +9,7 @@ import org.rekotlin.StateType data class WalletState( val state: ProgressState = ProgressState.Done, + val error: ErrorType? = null, val cardImage: Artwork? = null, val wallet: Wallet? = null, val pendingTransactions: List = emptyList(), @@ -23,6 +24,8 @@ data class WalletState( enum class ProgressState { Loading, Done, Error } +enum class ErrorType { NoInternetConnection } + enum class PayIdState { Disabled, Loading, NotCreated, Created, ErrorLoading } data class PayIdData( diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt index 6f8d7dac2a..1e1ad65d42 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/BalanceWidget.kt @@ -10,13 +10,6 @@ import kotlinx.android.synthetic.main.layout_balance.* import kotlinx.android.synthetic.main.layout_balance_error.* import kotlinx.android.synthetic.main.layout_token.view.* -enum class PayIdState { - Loading, - NotCreated, - Loaded, - Error -} - enum class BalanceStatus { VerifiedOnline, Unreachable, @@ -54,12 +47,14 @@ class BalanceWidget( BalanceStatus.Loading -> { fragment.l_balance.show() fragment.l_balance_error.hide() + fragment.tv_fiat_amount.hide() + fragment.l_token.hide() + fragment.tv_currency.text = data.currency fragment.tv_currency_symbol.text = "-" fragment.tv_amount.text = "" - fragment.tv_fiat_amount.hide() + showStatus(R.id.tv_status_loading) - fragment.l_token.hide() } BalanceStatus.VerifiedOnline -> { fragment.l_balance.show() @@ -78,14 +73,18 @@ class BalanceWidget( fragment.l_token.tv_token_fiat_amount.text = data.token.fiatAmount } else { fragment.l_token.hide() - } - } BalanceStatus.Unreachable -> { fragment.l_balance.show() fragment.l_balance_error.hide() fragment.l_token.hide() + fragment.tv_fiat_amount.hide() + + fragment.tv_currency.text = data.currency + fragment.tv_currency_symbol.text = "-" + fragment.tv_amount.text = "" + showStatus(R.id.tv_status_error) } BalanceStatus.EmptyCard -> { @@ -112,15 +111,4 @@ class BalanceWidget( fragment.tv_status_loading.show(viewRes == R.id.tv_status_loading) fragment.tv_status_verified.show(viewRes == R.id.tv_status_verified) } -} - - -enum class BalanceErrorWidgetState { - NoAccount, - NoWallet, - BlockchainError -} - -class BalanceErrorWidget( - -) \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 887f9c2ee3..598760abbd 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -7,13 +7,13 @@ import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import androidx.transition.TransitionInflater +import com.google.android.material.snackbar.Snackbar import com.tangem.tap.common.extensions.getDrawable import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.wallet.redux.* -import com.tangem.tap.features.wallet.redux.PayIdState import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.android.synthetic.main.card_balance.* @@ -26,6 +26,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber, context: Context ) { - private val connectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + private val wContext: WeakReference = WeakReference(context) private val receiver = object : BroadcastReceiver() { override fun onReceive(c: Context?, intent: Intent?) { @@ -26,14 +30,42 @@ class NetworkConnectivity( init { val intentFilter = IntentFilter() intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION) - context.registerReceiver(receiver, intentFilter) + wContext.get()?.registerReceiver(receiver, intentFilter) store.dispatch(NetworkStateChanged(isOnlineOrConnecting())) } fun isOnlineOrConnecting(): Boolean { - val netInfo = connectivityManager.activeNetworkInfo - return netInfo != null && netInfo.isConnectedOrConnecting + val connectivityManager = getConnectivityManager() ?: return false + + return if (Build.VERSION.SDK_INT >= 23) { + val capabilities = + connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) + (capabilities != null) && + (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || + capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) + + } else { + val networkInfo = connectivityManager.activeNetworkInfo + networkInfo != null && networkInfo.isConnectedOrConnecting + } + } + + private fun getConnectivityManager(): ConnectivityManager? { + return wContext.get()?.applicationContext + ?.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager + } + + companion object { + private lateinit var instance: NetworkConnectivity + + fun createInstance(store: Store<*>, context: Context): NetworkConnectivity { + instance = NetworkConnectivity(store, context) + return instance + } + + fun getInstance(): NetworkConnectivity = instance } } diff --git a/app/src/main/res/layout/fragment_wallet.xml b/app/src/main/res/layout/fragment_wallet.xml index eadd74b5e1..ccaf8611ff 100644 --- a/app/src/main/res/layout/fragment_wallet.xml +++ b/app/src/main/res/layout/fragment_wallet.xml @@ -1,6 +1,7 @@ Tangem Tap Address was successfully copied + No internet connection + Retry Done Welcome to Tangem.\nDo you have one of our cards?