diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 5b0a0db31b..2f558982d2 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -17,6 +17,7 @@ import com.tangem.datasource.asset.AssetReader import com.tangem.datasource.config.ConfigManager import com.tangem.datasource.config.FeaturesLocalLoader import com.tangem.datasource.config.models.Config +import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.domain.DomainLayer import com.tangem.domain.common.LogConfig import com.tangem.tap.common.IntentHandler @@ -49,7 +50,6 @@ import com.tangem.tap.domain.walletStores.repository.WalletManagersRepository import com.tangem.tap.domain.walletStores.repository.WalletStoresRepository import com.tangem.tap.domain.walletStores.repository.di.provideDefaultImplementation import com.tangem.tap.domain.walletconnect.WalletConnectRepository -import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.persistence.PreferencesStorage import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphAction @@ -124,6 +124,9 @@ class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var featureTogglesManager: FeatureTogglesManager + @Inject + lateinit var networkConnectionManager: NetworkConnectionManager + override fun onCreate() { super.onCreate() @@ -144,7 +147,6 @@ class TapApplication : Application(), ImageLoaderFactory { registerActivityLifecycleCallbacks(foregroundActivityObserver.callbacks) DomainLayer.init() - NetworkConnectivity.createInstance(store, this) preferencesStorage = PreferencesStorage(this) walletConnectRepository = WalletConnectRepository(this) @@ -161,12 +163,18 @@ class TapApplication : Application(), ImageLoaderFactory { userTokensRepository = UserTokensRepository.init( context = this, tangemTechService = store.state.domainNetworks.tangemTechService, + networkConnectionManager = networkConnectionManager, ) appStateHolder.mainStore = store appStateHolder.userTokensRepository = userTokensRepository appStateHolder.walletStoresManager = walletStoresManager - store.dispatch(DaggerGraphAction.SetApplicationDependencies(assetReader)) + store.dispatch( + action = DaggerGraphAction.SetApplicationDependencies( + assetReader = assetReader, + networkConnectionManager = networkConnectionManager, + ), + ) scope.launch { featureTogglesManager.init() diff --git a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt index 0939e05be9..0930704d50 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/WalletManager.kt @@ -16,8 +16,8 @@ import com.tangem.tap.features.demo.isDemoCard import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.redux.AddressData import com.tangem.tap.features.wallet.redux.reducers.createAddressesData -import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager +import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.store import kotlinx.coroutines.delay import timber.log.Timber @@ -47,7 +47,8 @@ suspend fun WalletManager.safeUpdate(): Result = try { } catch (exception: Exception) { Timber.e(exception) - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + val networkConnectionManager = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + if (!networkConnectionManager.isOnline) { Result.Failure(TapError.NoInternetConnection) } else { val blockchain = wallet.blockchain @@ -87,8 +88,6 @@ fun WalletManager?.getAddressData(): AddressData? { return if (addressDataList.isEmpty()) null else addressDataList[0] } -fun WalletManager.getTxHistory(currency: Currency): List = wallet.getTxHistory(currency) - fun WalletManager.getBlockchainTxHistory(): List = wallet.getBlockchainTxHistory() fun WalletManager.getTokenTxHistory(token: Token): List = wallet.getTokenTxHistory(token) diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt index 03b431d3e2..ee21bf9347 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt @@ -6,6 +6,7 @@ import com.tangem.common.core.TangemSdkError import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.TangemTechService import com.tangem.datasource.api.tangemTech.models.UserTokensResponse +import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.domain.common.CardDTO import com.tangem.tap.common.AndroidFileReader import com.tangem.tap.domain.model.builders.UserWalletIdBuilder @@ -15,7 +16,6 @@ import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.toBlockchainNetworks import com.tangem.tap.features.wallet.models.toCurrencies -import com.tangem.tap.network.NetworkConnectivity import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.withContext @@ -25,6 +25,7 @@ class UserTokensRepository( private val storageService: UserTokensStorageService, private val tangemTechApi: TangemTechApi, private val dispatchers: CoroutineDispatcherProvider, + private val networkConnectionManager: NetworkConnectionManager, ) { // TODO("After adding DI") replace with CoroutineDispatcherProvider @@ -34,7 +35,7 @@ class UserTokensRepository( return@withContext loadTokensOffline(card, userId).ifEmpty(::loadDemoCurrencies) } - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + if (!networkConnectionManager.isOnline) { return@withContext loadTokensOffline(card, userId) } @@ -131,7 +132,11 @@ class UserTokensRepository( private const val NOT_FOUND_HTTP_CODE = "404" // TODO("After adding DI") get dependencies by DI - fun init(context: Context, tangemTechService: TangemTechService): UserTokensRepository { + fun init( + context: Context, + tangemTechService: TangemTechService, + networkConnectionManager: NetworkConnectionManager, + ): UserTokensRepository { val fileReader = AndroidFileReader(context) val dispatchers = AppCoroutineDispatcherProvider() @@ -149,6 +154,7 @@ class UserTokensRepository( storageService = storageService, tangemTechApi = tangemTechService.api, dispatchers = dispatchers, + networkConnectionManager = networkConnectionManager, ) } } diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt index f42dd9ced5..d2936d9dcc 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletStores/repository/implementation/DefaultWalletAmountsRepository.kt @@ -44,7 +44,8 @@ import com.tangem.tap.features.wallet.models.Currency import com.tangem.tap.features.wallet.models.PendingTransactionType import com.tangem.tap.features.wallet.models.filterByCoin import com.tangem.tap.features.wallet.models.getPendingTransactions -import com.tangem.tap.network.NetworkConnectivity +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.store import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -62,8 +63,6 @@ internal class DefaultWalletAmountsRepository( private val tangemTechApi: TangemTechApi, private val dispatchers: CoroutineDispatcherProvider, ) : WalletAmountsRepository { - private val walletStoresStorage = WalletStoresStorage - private val walletManagersStorage = WalletManagerStorage override suspend fun updateAmountsForUserWallets( userWallets: List, @@ -76,8 +75,7 @@ internal class DefaultWalletAmountsRepository( awaitAll( async { fetchAmountsForUserWallets(userWallets) }, async { fetchFiatRates(userWallets, walletStores = null, fiatCurrency) }, - ) - .fold() + ).fold() } } } @@ -104,8 +102,7 @@ internal class DefaultWalletAmountsRepository( awaitAll( async { fetchAmountForWalletStores(userWalletId, scanResponse, walletStores) }, async { fetchFiatRates(listOf(userWallet), walletStores, fiatCurrency) }, - ) - .fold() + ).fold() } } } @@ -123,41 +120,41 @@ internal class DefaultWalletAmountsRepository( walletStores: List?, fiatCurrency: FiatCurrency, ): CompletionResult { - // FIXME: Use NetworkConnectionManager when it is added to DI - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + val networkConnectionManager = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + if (!networkConnectionManager.isOnline) { return CompletionResult.Failure(WalletStoresError.NoInternetConnection) } val walletStoresInternal = walletStores ?: getWalletStores(userWallets) - val currencies = walletStoresInternal - .asSequence() - .flatMap { it.walletsData } - .map { it.currency } + val currencies = walletStoresInternal.asSequence().flatMap { it.walletsData }.map { it.currency } val coinsIds = currencies.mapNotNull { it.coinId }.distinct().toList() return withContext(dispatchers.io) { - runCatching { tangemTechApi.getRates(fiatCurrency.code.lowercase(), coinsIds.joinToString(",")) } - .onSuccess { - updateWalletStoresWithFiatRates(walletStores = walletStoresInternal, fiatRates = it.rates) - return@withContext CompletionResult.Success(Unit) - } - .onFailure { - val error = WalletStoresError.FetchFiatRatesError( - currencies = currencies.map(Currency::currencySymbol).toList(), - cause = it, - ) + runCatching { + tangemTechApi.getRates( + fiatCurrency.code.lowercase(), + coinsIds.joinToString(","), + ) + }.onSuccess { + updateWalletStoresWithFiatRates(walletStores = walletStoresInternal, fiatRates = it.rates) + return@withContext CompletionResult.Success(Unit) + }.onFailure { + val error = WalletStoresError.FetchFiatRatesError( + currencies = currencies.map(Currency::currencySymbol).toList(), + cause = it, + ) - Timber.e( - error, - """ + Timber.e( + error, + """ Unable to fetch fiat rates |- Coins ids: $coinsIds - """.trimIndent(), - ) + """.trimIndent(), + ) - return@withContext CompletionResult.Failure(error) - } + return@withContext CompletionResult.Failure(error) + } error("Unreachable code because runCatching must return result") } @@ -166,9 +163,7 @@ internal class DefaultWalletAmountsRepository( private suspend fun fetchAmountsForUserWallets( userWallets: List, ): CompletionResult = withContext(Dispatchers.Default) { - userWallets.map { async { fetchAmountsForUserWallet(it) } } - .awaitAll() - .fold() + userWallets.map { async { fetchAmountsForUserWallet(it) } }.awaitAll().fold() } private suspend fun fetchAmountsForUserWallet( @@ -186,8 +181,8 @@ internal class DefaultWalletAmountsRepository( scanResponse: ScanResponse, walletStores: List, ): CompletionResult = coroutineScope { - // FIXME: Use NetworkConnectionManager when it is added to DI - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + val networkConnectionManager = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + if (!networkConnectionManager.isOnline) { walletStores.forEach { updateWalletStoreWithUnreachable(it) } @@ -200,9 +195,7 @@ internal class DefaultWalletAmountsRepository( val walletManager = walletStore.walletManager fetchAmountsForWalletStore(userWalletId, scanResponse, walletStore, walletManager) } - } - .awaitAll() - .fold() + }.awaitAll().fold() } private suspend fun fetchAmountsForWalletStore( @@ -223,24 +216,25 @@ internal class DefaultWalletAmountsRepository( updateWalletStoreWithUnreachable(walletStore) } else -> { - updateWalletManager(scanResponse, walletManager) - .map { updateWalletManagerInStorage(userWalletId, walletManager) } - .flatMap { - updateWalletStoreWithAmounts( - walletStore = walletStore, - updatedWallet = walletManager.wallet, - // FIXME: move DemoHelper to Demo core module maybe - isDemo = DemoHelper.isDemoCardId(scanResponse.card.cardId), - ) - } - .flatMap { fetchWalletStoreRentIfNeeded(walletStore, walletManager) } - .flatMapOnFailure { error -> - updateWalletStoreWithError( - walletStore = walletStore, - wallet = walletManager.wallet, - error = error, - ) - } + updateWalletManager(scanResponse, walletManager).map { + updateWalletManagerInStorage( + userWalletId, + walletManager, + ) + }.flatMap { + updateWalletStoreWithAmounts( + walletStore = walletStore, + updatedWallet = walletManager.wallet, + // FIXME: move DemoHelper to Demo core module maybe + isDemo = DemoHelper.isDemoCardId(scanResponse.card.cardId), + ) + }.flatMap { fetchWalletStoreRentIfNeeded(walletStore, walletManager) }.flatMapOnFailure { error -> + updateWalletStoreWithError( + walletStore = walletStore, + wallet = walletManager.wallet, + error = error, + ) + } } } } @@ -267,8 +261,7 @@ internal class DefaultWalletAmountsRepository( walletStore: WalletStoreModel, walletManager: WalletManager, ): CompletionResult { - val rentProvider = walletManager as? RentProvider - ?: return CompletionResult.Success(Unit) + val rentProvider = walletManager as? RentProvider ?: return CompletionResult.Success(Unit) when (val result = rentProvider.minimalBalanceForRentExemption()) { is Success -> { @@ -318,7 +311,7 @@ internal class DefaultWalletAmountsRepository( ) if (error is BlockchainSdkError) { - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStore( walletStoreToUpdate = walletStore, update = { @@ -350,7 +343,7 @@ internal class DefaultWalletAmountsRepository( """.trimIndent(), ) - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStore( walletStoreToUpdate = walletStore, update = { @@ -378,7 +371,7 @@ internal class DefaultWalletAmountsRepository( """.trimIndent(), ) - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStore( walletStoreToUpdate = walletStore, update = { @@ -402,7 +395,7 @@ internal class DefaultWalletAmountsRepository( """.trimIndent(), ) - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStore( walletStoreToUpdate = walletStore, update = { @@ -425,7 +418,7 @@ internal class DefaultWalletAmountsRepository( """.trimIndent(), ) - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStores( walletStoresToUpdate = walletStores, update = { @@ -450,7 +443,7 @@ internal class DefaultWalletAmountsRepository( ) if (rent != walletStore.walletRent) { - walletStoresStorage.update { prevState -> + WalletStoresStorage.update { prevState -> prevState.replaceWalletStore( walletStoreToUpdate = walletStore, update = { @@ -465,14 +458,12 @@ internal class DefaultWalletAmountsRepository( userWalletId: UserWalletId, walletManager: WalletManager, ) = withContext(Dispatchers.Default) { - walletManagersStorage.update { prevManagers -> - val newManagersForUserWallet = prevManagers[userWalletId].orEmpty() - .toMutableList() - .apply { - replaceByOrAdd(walletManager) { - it.wallet.blockchain == walletManager.wallet.blockchain - } + WalletManagerStorage.update { prevManagers -> + val newManagersForUserWallet = prevManagers[userWalletId].orEmpty().toMutableList().apply { + replaceByOrAdd(walletManager) { + it.wallet.blockchain == walletManager.wallet.blockchain } + } prevManagers.apply { set(userWalletId, newManagersForUserWallet) @@ -481,13 +472,8 @@ internal class DefaultWalletAmountsRepository( } private suspend fun getWalletStores(userWallets: List): List { - return userWallets - .map { it.walletId } - .flatMap { userWalletId -> - walletStoresStorage.getAll() - .firstOrNull() - ?.get(userWalletId) - .orEmpty() - } + return userWallets.map { it.walletId }.flatMap { userWalletId -> + WalletStoresStorage.getAll().firstOrNull()?.get(userWalletId).orEmpty() + } } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt index 9d741424b7..305df3393e 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/redux/TokensMiddleware.kt @@ -31,6 +31,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.tokens.LoadAvailableCoinsService import com.tangem.tap.features.wallet.models.Currency +import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager @@ -84,7 +85,7 @@ class TokensMiddleware { val loadCoinsService = LoadAvailableCoinsService( tangemTechApi = store.state.domainNetworks.tangemTechService.api, dispatchers = AppCoroutineDispatcherProvider(), - assetReader = requireNotNull(store.state.daggerGraphState.assetReader) { "Asset reader is null" }, + assetReader = store.state.daggerGraphState.get(DaggerGraphState::assetReader), ) scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index 1866921b7e..41b72a10d4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -6,6 +6,7 @@ import com.tangem.blockchain.common.AmountType import com.tangem.common.CompletionResult import com.tangem.common.extensions.guard import com.tangem.core.analytics.Analytics +import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.tap.common.analytics.converters.BasicEventsPreChecker import com.tangem.tap.common.analytics.converters.BasicEventsSourceData import com.tangem.tap.common.analytics.events.AnalyticsParam @@ -37,15 +38,13 @@ import com.tangem.tap.features.wallet.redux.WalletData import com.tangem.tap.features.wallet.redux.WalletState import com.tangem.tap.features.wallet.redux.WalletStore import com.tangem.tap.features.wallet.redux.reducers.findSelectedCurrency -import com.tangem.tap.network.NetworkConnectivity -import com.tangem.tap.network.NetworkStateChanged import com.tangem.tap.preferencesStorage +import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager import com.tangem.tap.totalFiatBalanceCalculator import com.tangem.tap.userWalletsListManager -import com.tangem.tap.userWalletsListManagerSafe import com.tangem.tap.walletStoresManager import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers @@ -72,6 +71,9 @@ class WalletMiddleware { ) } + private val networkConnectionManager: NetworkConnectionManager + get() = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + val walletMiddleware: Middleware = { _, state -> { next -> { action -> @@ -135,16 +137,6 @@ class WalletMiddleware { ) } } - is NetworkStateChanged -> { - store.dispatch(WalletAction.Warnings.CheckHashesCount.CheckHashesCountOnline) - if (!action.isOnline) return - - val selectedUserWallet = userWalletsListManagerSafe?.selectedUserWalletSync.guard { - Timber.e("Unable to proceed with changed network state, no user wallet selected") - return - } - scope.launch { globalState.tapWalletManager.loadData(selectedUserWallet, refresh = true) } - } is WalletAction.CopyAddress -> { Analytics.send(Token.Receive.ButtonCopyAddress()) action.context.copyToClipboard(action.address) @@ -159,7 +151,7 @@ class WalletMiddleware { store.dispatchOpenUrl(action.exploreUrl) } is WalletAction.Send -> { - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) { + if (!networkConnectionManager.isOnline) { store.dispatchErrorNotification(TapError.NoInternetConnection) return } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt index d9a40e965d..1de96bac4b 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WarningsMiddleware.kt @@ -2,29 +2,26 @@ package com.tangem.tap.features.wallet.redux.middlewares import com.tangem.blockchain.common.BlockchainSdkError import com.tangem.blockchain.common.SignatureCountValidator -import com.tangem.blockchain.common.Wallet import com.tangem.blockchain.extensions.SimpleResult import com.tangem.common.card.FirmwareVersion import com.tangem.domain.common.CardDTO import com.tangem.domain.common.ScanResponse import com.tangem.domain.common.TapWorkarounds.isTestCard import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.common.extensions.isGreaterThan import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.domain.configurable.warningMessage.WarningMessage import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager import com.tangem.tap.domain.extensions.hasSignedHashes import com.tangem.tap.features.demo.isDemoCard import com.tangem.tap.features.wallet.redux.WalletAction -import com.tangem.tap.network.NetworkConnectivity import com.tangem.tap.preferencesStorage +import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.wallet.R import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.math.BigDecimal class WarningsMiddleware { fun handle(action: WalletAction.Warnings, globalState: GlobalState?) { @@ -75,13 +72,6 @@ class WarningsMiddleware { } } - fun tryToShowAppRatingWarning(wallet: Wallet) { - val nonZeroWalletsCount = wallet.amounts.filter { - it.value.value?.isGreaterThan(BigDecimal.ZERO) ?: false - }.size - tryToShowAppRatingWarning(hasNonZeroWallets = nonZeroWalletsCount > 0) - } - private fun showCardWarningsIfNeeded(globalState: GlobalState?) { globalState?.scanResponse?.let { scanResponse -> val card = scanResponse.card @@ -147,7 +137,9 @@ class WarningsMiddleware { private fun checkHashesCountOnline() { if (store.state.walletState.hashesCountVerified != false) return - if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) return + + val networkConnectionManager = store.state.daggerGraphState.get(DaggerGraphState::networkConnectionManager) + if (!networkConnectionManager.isOnline) return val scanResponse = store.state.globalState.scanResponse val card = scanResponse?.card diff --git a/app/src/main/java/com/tangem/tap/network/NetworkConnectivity.kt b/app/src/main/java/com/tangem/tap/network/NetworkConnectivity.kt deleted file mode 100644 index bf61064eaa..0000000000 --- a/app/src/main/java/com/tangem/tap/network/NetworkConnectivity.kt +++ /dev/null @@ -1,71 +0,0 @@ -package com.tangem.tap.network - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter -import android.net.ConnectivityManager -import android.net.NetworkCapabilities -import android.os.Build -import org.rekotlin.Action -import org.rekotlin.Store -import java.lang.ref.WeakReference - -/** -[REDACTED_AUTHOR] - */ -@Deprecated("Use com.tangem.datasource.connection.NetworkConnectionManager") -class NetworkConnectivity( - private val store: Store<*>, - context: Context, -) { - - private val wContext: WeakReference = WeakReference(context) - - private val receiver = object : BroadcastReceiver() { - override fun onReceive(c: Context?, intent: Intent?) { - store.dispatch(NetworkStateChanged(isOnlineOrConnecting())) - } - } - - init { - val intentFilter = IntentFilter() - intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION) - wContext.get()?.registerReceiver(receiver, intentFilter) - store.dispatch(NetworkStateChanged(isOnlineOrConnecting())) - } - - fun isOnlineOrConnecting(): Boolean { - val connectivityManager = getConnectivityManager() ?: return false - - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) - capabilities != null && - (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || - capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN) || - 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 - } -} - -data class NetworkStateChanged(val isOnline: Boolean) : Action \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt index f8e0d379ef..cd392ae831 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphAction.kt @@ -1,12 +1,16 @@ package com.tangem.tap.proxy.redux import com.tangem.datasource.asset.AssetReader +import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.features.tester.api.TesterRouter import org.rekotlin.Action sealed interface DaggerGraphAction : Action { - data class SetApplicationDependencies(val assetReader: AssetReader) : DaggerGraphAction + data class SetApplicationDependencies( + val assetReader: AssetReader, + val networkConnectionManager: NetworkConnectionManager, + ) : DaggerGraphAction data class SetActivityDependencies(val testerRouter: TesterRouter) : DaggerGraphAction } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt index 54988a4aa2..34564599ac 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphReducer.kt @@ -13,10 +13,11 @@ object DaggerGraphReducer { private fun internalReduce(action: DaggerGraphAction, state: AppState): DaggerGraphState { return when (action) { is DaggerGraphAction.SetApplicationDependencies -> state.daggerGraphState.copy( - assetReader = action.assetReader + assetReader = action.assetReader, + networkConnectionManager = action.networkConnectionManager, ) is DaggerGraphAction.SetActivityDependencies -> state.daggerGraphState.copy( - testerRouter = action.testerRouter + testerRouter = action.testerRouter, ) } } diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index ceea2d495c..800182a67c 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -1,10 +1,19 @@ package com.tangem.tap.proxy.redux import com.tangem.datasource.asset.AssetReader +import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.features.tester.api.TesterRouter import org.rekotlin.StateType data class DaggerGraphState( val assetReader: AssetReader? = null, val testerRouter: TesterRouter? = null, -) : StateType \ No newline at end of file + val networkConnectionManager: NetworkConnectionManager? = null, +) : StateType { + + inline fun get(getDependency: DaggerGraphState.() -> T?): T { + return requireNotNull(getDependency()) { + "${T::class.simpleName} isn't initialized " + } + } +} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/connection/AndroidNetworkConnectionManager.kt b/core/datasource/src/main/java/com/tangem/datasource/connection/AndroidNetworkConnectionManager.kt index d5bff89d3b..695dbce8bd 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/connection/AndroidNetworkConnectionManager.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/connection/AndroidNetworkConnectionManager.kt @@ -15,7 +15,6 @@ import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject @@ -36,9 +35,9 @@ internal class AndroidNetworkConnectionManager @Inject constructor( private val dispatchers: CoroutineDispatcherProvider, ) : NetworkConnectionManager { - override val connectionStatus: StateFlow get() = _connectionStatus + override val isOnline: Boolean get() = _isOnline.value - private val _connectionStatus = MutableStateFlow(ConnectionStatus.OFFLINE) + private val _isOnline = MutableStateFlow(value = false) private val callbacks = NetworkConnectionManagerCallbacks() private val receiver = NetworkConnectionBroadcastReceiver() @@ -78,28 +77,26 @@ internal class AndroidNetworkConnectionManager @Inject constructor( CoroutineScope(SupervisorJob()).launch(dispatchers.io) { try { - val status = getCurrentStatus() + val status = isConnected() - _connectionStatus.emit(value = status) - Timber.i("Status changed to $status") + _isOnline.emit(value = status) + Timber.i("Connection status is ${if (status) "ONLINE" else "OFFLINE"}") } finally { pendingResult.finish() } } } - private fun getCurrentStatus(): ConnectionStatus { - connectivityManager ?: return ConnectionStatus.OFFLINE + private fun isConnected(): Boolean { + connectivityManager ?: return false - val isConnected = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork) capabilities != null && capabilities.hasNetworkTransport() } else { val networkInfo = connectivityManager.activeNetworkInfo networkInfo != null && networkInfo.isConnectedOrConnecting } - - return if (isConnected) ConnectionStatus.ONLINE else ConnectionStatus.OFFLINE } private fun NetworkCapabilities.hasNetworkTransport(): Boolean { diff --git a/core/datasource/src/main/java/com/tangem/datasource/connection/ConnectionStatus.kt b/core/datasource/src/main/java/com/tangem/datasource/connection/ConnectionStatus.kt deleted file mode 100644 index b59aa6f4df..0000000000 --- a/core/datasource/src/main/java/com/tangem/datasource/connection/ConnectionStatus.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.datasource.connection - -/** - * Network connection status - * -[REDACTED_AUTHOR] - */ -enum class ConnectionStatus { - ONLINE, OFFLINE -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/connection/NetworkConnectionManager.kt b/core/datasource/src/main/java/com/tangem/datasource/connection/NetworkConnectionManager.kt index 9d6c73849d..fa6faca57d 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/connection/NetworkConnectionManager.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/connection/NetworkConnectionManager.kt @@ -1,10 +1,8 @@ package com.tangem.datasource.connection -import kotlinx.coroutines.flow.StateFlow - /** Network connection manager */ interface NetworkConnectionManager { /** Connection status */ - val connectionStatus: StateFlow + val isOnline: Boolean } \ No newline at end of file