From 855ee45378f710a38c7514e23ace473d53785a96 Mon Sep 17 00:00:00 2001 From: Tangem Date: Tue, 16 May 2023 21:04:10 +0800 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/tap/TapApplication.kt | 7 +- .../tap/common/extensions/Navigation.kt | 8 +- .../com/tangem/tap/common/redux/AppState.kt | 2 +- .../tangem/tap/features/home/HomeFragment.kt | 3 +- .../TokensListFeatureToggles.kt | 12 - .../impl/di/TokensListFeatureTogglesModule.kt | 24 -- .../DefaultTokensListFeatureToggles.kt | 19 -- .../impl/presentation/TokensListFragment.kt | 5 +- .../presentation/models/TokensListArgs.kt | 2 +- .../presentation/states/NetworkItemState.kt | 3 +- .../viewmodels/TokensListAnalyticsSender.kt | 4 + .../viewmodels/TokensListViewModel.kt | 8 +- .../tokens/legacy/AddTokensFragment.kt | 174 ------------- .../tokens/legacy/redux/TokensAction.kt | 33 +-- .../tokens/legacy/redux/TokensMiddleware.kt | 135 +++------- .../tokens/legacy/redux/TokensReducer.kt | 71 +++--- .../tokens/legacy/redux/TokensState.kt | 68 +---- .../legacy/ui/compose/CurrenciesScreen.kt | 232 ------------------ .../legacy/ui/compose/CurrenciesWarning.kt | 56 ----- .../ui/compose/CurrencyPlaceholderIcon.kt | 36 --- .../legacy/ui/compose/ListOfCurrencies.kt | 74 ------ .../currencyItem/CurrencyExpandedContent.kt | 63 ----- .../ui/compose/currencyItem/CurrencyItem.kt | 40 --- .../currencyItem/CurrencyItemHeader.kt | 213 ---------------- .../ui/compose/currencyItem/NetworkItem.kt | 186 -------------- .../wallet/ui/wallet/MultiWalletView.kt | 11 +- .../tap/proxy/redux/DaggerGraphState.kt | 2 - .../main/res/layout/fragment_add_tokens.xml | 36 --- app/src/main/res/menu/menu_popular_tokens.xml | 19 -- .../configs/feature_toggles_config.json | 6 +- 30 files changed, 112 insertions(+), 1440 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/api/featuretoggles/TokensListFeatureToggles.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListFeatureTogglesModule.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/impl/featuretoggles/DefaultTokensListFeatureToggles.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/AddTokensFragment.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesScreen.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesWarning.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrencyPlaceholderIcon.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/ListOfCurrencies.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyExpandedContent.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItem.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItemHeader.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/NetworkItem.kt delete mode 100644 app/src/main/res/layout/fragment_add_tokens.xml delete mode 100644 app/src/main/res/menu/menu_popular_tokens.xml diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index ad51eea81f..b224a7f81a 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -12,6 +12,7 @@ import com.tangem.blockchain.common.WalletManagerFactory import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder import com.tangem.core.analytics.Analytics import com.tangem.core.featuretoggle.manager.FeatureTogglesManager +import com.tangem.data.source.preferences.PreferencesDataSource import com.tangem.datasource.api.common.MoshiConverter import com.tangem.datasource.asset.AssetReader import com.tangem.datasource.config.ConfigManager @@ -20,7 +21,6 @@ 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.data.source.preferences.PreferencesDataSource import com.tangem.tap.common.IntentHandler import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder @@ -51,7 +51,6 @@ 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.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles -import com.tangem.tap.features.tokens.api.featuretoggles.TokensListFeatureToggles import com.tangem.tap.proxy.AppStateHolder import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.wallet.BuildConfig @@ -128,9 +127,6 @@ class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var networkConnectionManager: NetworkConnectionManager - @Inject - lateinit var tokensListFeatureToggles: TokensListFeatureToggles - @Inject lateinit var customTokenFeatureToggles: CustomTokenFeatureToggles @@ -149,7 +145,6 @@ class TapApplication : Application(), ImageLoaderFactory { daggerGraphState = DaggerGraphState( assetReader = assetReader, networkConnectionManager = networkConnectionManager, - tokensListFeatureToggles = tokensListFeatureToggles, customTokenFeatureToggles = customTokenFeatureToggles, ), ), diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index fbecc6daed..806a46dd1d 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -29,7 +29,6 @@ import com.tangem.tap.features.saveWallet.ui.SaveWalletBottomSheetFragment import com.tangem.tap.features.send.ui.SendFragment import com.tangem.tap.features.shop.ui.ShopFragment import com.tangem.tap.features.tokens.impl.presentation.TokensListFragment -import com.tangem.tap.features.tokens.legacy.AddTokensFragment import com.tangem.tap.features.wallet.ui.WalletDetailsFragment import com.tangem.tap.features.wallet.ui.WalletFragment import com.tangem.tap.features.walletSelector.ui.WalletSelectorBottomSheetFragment @@ -148,12 +147,7 @@ private fun fragmentFactory(screen: AppScreen): Fragment { AppScreen.ResetToFactory -> ResetCardFragment() AppScreen.AccessCodeRecovery -> AccessCodeRecoveryFragment() AppScreen.Disclaimer -> DisclaimerFragment() - AppScreen.AddTokens -> { - val featureToggles = store.state.daggerGraphState.get( - getDependency = DaggerGraphState::tokensListFeatureToggles, - ) - if (featureToggles.isRedesignedScreenEnabled) TokensListFragment() else AddTokensFragment() - } + AppScreen.AddTokens -> TokensListFragment() AppScreen.AddCustomToken -> { val featureToggles = store.state.daggerGraphState.get( diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index 2efd12e515..de6bae2411 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -101,7 +101,7 @@ data class AppState( SendMiddleware().sendMiddleware, DetailsMiddleware().detailsMiddleware, DisclaimerMiddleware().disclaimerMiddleware, - TokensMiddleware().tokensMiddleware, + TokensMiddleware.tokensMiddleware, WalletConnectMiddleware().walletConnectMiddleware, BackupMiddleware().backupMiddleware, ShopMiddleware().shopMiddleware, diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 64ea0798e0..acf3408acf 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -91,8 +91,7 @@ class HomeFragment : Fragment(), StoreSubscriber { onSearchTokensClick = { Analytics.send(IntroductionProcess.ButtonTokensList()) store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens)) - store.dispatch(TokensAction.AllowToAddTokens(false)) - store.dispatch(TokensAction.LoadCurrencies()) + store.dispatch(TokensAction.SetArgs.ReadAccess) }, ) } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/api/featuretoggles/TokensListFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/tokens/api/featuretoggles/TokensListFeatureToggles.kt deleted file mode 100644 index 286eb6d0e0..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/api/featuretoggles/TokensListFeatureToggles.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.tangem.tap.features.tokens.api.featuretoggles - -/** - * TokensList feature toggles - * -[REDACTED_AUTHOR] - */ -interface TokensListFeatureToggles { - - /** Availability of redesigned screen (internal feature) */ - val isRedesignedScreenEnabled: Boolean -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListFeatureTogglesModule.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListFeatureTogglesModule.kt deleted file mode 100644 index d2b8ae0470..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/di/TokensListFeatureTogglesModule.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.tap.features.tokens.impl.di - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.tap.features.tokens.api.featuretoggles.TokensListFeatureToggles -import com.tangem.tap.features.tokens.impl.featuretoggles.DefaultTokensListFeatureToggles -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton - -/** -[REDACTED_AUTHOR] - */ -@Module -@InstallIn(SingletonComponent::class) -internal object TokensListFeatureTogglesModule { - - @Provides - @Singleton - fun providesTokensListFeatureToggles(featureTogglesManager: FeatureTogglesManager): TokensListFeatureToggles { - return DefaultTokensListFeatureToggles(featureTogglesManager) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/featuretoggles/DefaultTokensListFeatureToggles.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/featuretoggles/DefaultTokensListFeatureToggles.kt deleted file mode 100644 index b9aa44c70f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/featuretoggles/DefaultTokensListFeatureToggles.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.tangem.tap.features.tokens.impl.featuretoggles - -import com.tangem.core.featuretoggle.manager.FeatureTogglesManager -import com.tangem.tap.features.tokens.api.featuretoggles.TokensListFeatureToggles - -/** - * Default implementation of TokensList feature toggles - * - * @property featureTogglesManager manager for getting information about the availability of feature toggles - * -[REDACTED_AUTHOR] - */ -internal class DefaultTokensListFeatureToggles( - private val featureTogglesManager: FeatureTogglesManager, -) : TokensListFeatureToggles { - - override val isRedesignedScreenEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "REDESIGNED_TOKEN_LIST_SCREEN_ENABLED") -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt index 0a455118c1..e5ac57cfc8 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/TokensListFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.core.view.WindowCompat import androidx.fragment.app.Fragment import androidx.hilt.navigation.compose.hiltViewModel @@ -35,7 +36,9 @@ internal class TokensListFragment : Fragment() { setContent { isTransitionGroup = true - val viewModel = hiltViewModel() + val viewModel = hiltViewModel().apply { + LocalLifecycleOwner.current.lifecycle.addObserver(this) + } TangemTheme { TokensListScreen(stateHolder = viewModel.uiState) diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/TokensListArgs.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/TokensListArgs.kt index 88fdf58dd7..207976d628 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/TokensListArgs.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/models/TokensListArgs.kt @@ -12,7 +12,7 @@ import com.tangem.tap.store */ class TokensListArgs { /** Tokens list screen mode */ - val isManageAccess: Boolean get() = store.state.tokensState.allowToAdd + val isManageAccess: Boolean get() = store.state.tokensState.isManageAccess /** Tokens list that accessible from the main screen */ val mainScreenTokenList: List get() = store.state.tokensState.addedTokens diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt index 081a399e06..bfcffbdf69 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/states/NetworkItemState.kt @@ -4,7 +4,6 @@ import androidx.compose.runtime.MutableState import com.tangem.blockchain.common.Blockchain import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.tap.common.extensions.getGreyedOutIconRes -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress /** * Network item state @@ -62,7 +61,7 @@ sealed interface NetworkItemState { override val isMainNetwork: Boolean, val isAdded: MutableState, val id: String, - val address: ContractAddress?, + val address: String?, val decimalCount: Int?, val blockchain: Blockchain, val onToggleClick: (TokenItemState.ManageContent, ManageContent) -> Unit, diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt index 8e839d1ddd..95d0e9371e 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListAnalyticsSender.kt @@ -9,6 +9,10 @@ import com.tangem.tap.common.analytics.events.ManageTokens /** Analytics sender for tokens list screen */ class TokensListAnalyticsSender(private val analyticsEventHandler: AnalyticsEventHandler) { + fun sendWhenScreenOpened() { + analyticsEventHandler.send(event = ManageTokens.ScreenOpened()) + } + fun sendWhenTokenAdded(token: Token) { analyticsEventHandler.send( event = ManageTokens.TokenSwitcherChanged( diff --git a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt index eff8dd3e7d..a386333139 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/impl/presentation/viewmodels/TokensListViewModel.kt @@ -3,6 +3,8 @@ package com.tangem.tap.features.tokens.impl.presentation.viewmodels import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.LoadState @@ -59,7 +61,7 @@ internal class TokensListViewModel @Inject constructor( private val dispatchers: AppCoroutineDispatcherProvider, private val reduxStateHolder: AppStateHolder, analyticsEventHandler: AnalyticsEventHandler, -) : ViewModel() { +) : ViewModel(), DefaultLifecycleObserver { private val args = TokensListArgs() private val analyticsSender = TokensListAnalyticsSender(analyticsEventHandler) @@ -72,6 +74,10 @@ internal class TokensListViewModel @Inject constructor( private val changedTokensList: MutableList = args.mainScreenTokenList.toMutableList() private val changedBlockchainList: MutableList = args.mainScreenBlockchainList.toMutableList() + override fun onCreate(owner: LifecycleOwner) { + if (args.isManageAccess) analyticsSender.sendWhenScreenOpened() + } + private fun getInitialUiState(): TokensListStateHolder { return if (args.isManageAccess) { TokensListStateHolder.ManageContent( diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/AddTokensFragment.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/AddTokensFragment.kt deleted file mode 100644 index 3d6216bf22..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/AddTokensFragment.kt +++ /dev/null @@ -1,174 +0,0 @@ -package com.tangem.tap.features.tokens.legacy - -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.widget.SearchView -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.mutableStateOf -import androidx.transition.TransitionInflater -import by.kirich1409.viewbindingdelegate.viewBinding -import com.tangem.blockchain.common.Blockchain -import com.tangem.core.analytics.Analytics -import com.tangem.core.ui.res.TangemTheme -import com.tangem.tap.common.analytics.events.ManageTokens -import com.tangem.tap.common.extensions.copyToClipboard -import com.tangem.tap.common.extensions.dispatchNotification -import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.common.extensions.getString -import com.tangem.tap.common.redux.navigation.NavigationAction -import com.tangem.tap.features.BaseFragment -import com.tangem.tap.features.addBackPressHandler -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain -import com.tangem.tap.features.tokens.legacy.redux.TokensAction -import com.tangem.tap.features.tokens.legacy.redux.TokensState -import com.tangem.tap.features.tokens.legacy.ui.compose.CurrenciesScreen -import com.tangem.tap.mainScope -import com.tangem.tap.store -import com.tangem.wallet.R -import com.tangem.wallet.databinding.FragmentAddTokensBinding -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.rekotlin.StoreSubscriber - -@AndroidEntryPoint -internal class AddTokensFragment : BaseFragment(R.layout.fragment_add_tokens), StoreSubscriber { - - private val binding: FragmentAddTokensBinding by viewBinding(FragmentAddTokensBinding::bind) - private var tokensState: MutableState = mutableStateOf(store.state.tokensState) - private var searchInput = mutableStateOf("") - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setHasOptionsMenu(true) - addBackPressHandler(this) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) = with(binding) { - super.onViewCreated(view, savedInstanceState) - - (activity as? AppCompatActivity)?.setSupportActionBar(toolbar) - toolbar.setNavigationOnClickListener { handleOnBackPressed() } - - val onSaveChanges = { tokens: List, blockchains: List -> - Analytics.send(ManageTokens.ButtonSaveChanges()) - store.dispatch(TokensAction.SaveChanges(tokens, blockchains)) - } - val onNetworkItemClicked = { contractAddress: ContractAddress -> - context?.copyToClipboard(contractAddress) - store.dispatchNotification(R.string.contract_address_copied_message) - } - - val onLoadMore = { - store.dispatch(TokensAction.LoadMore(scanResponse = store.state.globalState.scanResponse)) - } - - cvCurrencies.setContent { - TangemTheme { - CurrenciesScreen( - tokensState = tokensState, - onSaveChanges = onSaveChanges, - onNetworkItemClick = onNetworkItemClicked, - onLoadMore = onLoadMore, - ) - } - } - } - - override fun onStart() { - super.onStart() - store.subscribe(this) { state -> - state - .skipRepeats { oldState, newState -> oldState.tokensState == newState.tokensState } - .select { it.tokensState } - } - } - - override fun onStop() { - super.onStop() - store.unsubscribe(this) - } - - override fun onDestroy() { - store.dispatch(TokensAction.ResetState) - super.onDestroy() - } - - @Suppress("MagicNumber") - override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.menu_popular_tokens, menu) - - val addCustomTokenAllowed = store.state.tokensState.allowToAdd - menu.findItem(R.id.menu_navigate_add_custom_token).isVisible = addCustomTokenAllowed - - val menuItem = menu.findItem(R.id.menu_search) - val searchView: SearchView = menuItem.actionView as SearchView - searchView.queryHint = searchView.getString(R.string.common_search) - searchView.maxWidth = android.R.attr.width - searchView.inputtedTextAsFlow() - .debounce(800) - .distinctUntilChanged() - .onEach { - searchInput.value = it.lowercase() - dispatchOnMain(TokensAction.SetSearchInput(searchInput.value)) - } - .launchIn(mainScope) - return super.onCreateOptionsMenu(menu, inflater) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.menu_search -> true - R.id.menu_navigate_add_custom_token -> { - Analytics.send(ManageTokens.ButtonCustomToken()) - store.dispatch(TokensAction.PrepareAndNavigateToAddCustomToken) - true - } - else -> super.onOptionsItemSelected(item) - } - } - - override fun configureTransitions() { - super.configureTransitions() - val inflater = TransitionInflater.from(requireContext()) - enterTransition = inflater.inflateTransition(R.transition.slide_right) - exitTransition = inflater.inflateTransition(R.transition.fade) - } - - override fun handleOnBackPressed() { - store.dispatch(NavigationAction.PopBackTo()) - store.dispatch(TokensAction.ResetState) - } - - override fun newState(state: TokensState) { - if (activity == null || view == null) return - val toolbarTitle = - if (state.allowToAdd) R.string.main_manage_tokens else R.string.search_tokens_title - tokensState.value = state - binding.toolbar.title = getString(toolbarTitle) - } - - private fun SearchView.inputtedTextAsFlow(): Flow = callbackFlow { - val watcher = setOnQueryTextListener( - object : SearchView.OnQueryTextListener { - override fun onQueryTextSubmit(query: String?): Boolean = false - - override fun onQueryTextChange(newText: String?): Boolean { - trySend(newText ?: "") - return false - } - }, - ) - awaitClose { watcher } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt index bea0320bbe..21f763e48a 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensAction.kt @@ -2,37 +2,22 @@ package com.tangem.tap.features.tokens.legacy.redux import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.DerivationStyle -import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.domain.model.WalletDataModel -import com.tangem.tap.domain.tokens.Currency import org.rekotlin.Action -sealed class TokensAction : Action { +sealed interface TokensAction : Action { - object ResetState : TokensAction() + /** Single way to pass data to the screen */ + sealed interface SetArgs : TokensAction { - data class AllowToAddTokens(val allow: Boolean) : TokensAction() + data class ManageAccess(val wallets: List, val derivationStyle: DerivationStyle?) : SetArgs - data class LoadCurrencies(val scanResponse: ScanResponse? = null) : TokensAction() { - data class Success(val currencies: List, val loadMore: Boolean) : TokensAction() - object Failure : TokensAction() + object ReadAccess : SetArgs } - data class LoadMore( - val scanResponse: ScanResponse? = null, - ) : TokensAction() + // TODO: [REDACTED_TASK_KEY] Remove this action + data class SaveChanges(val tokens: List, val blockchains: List) : TokensAction - data class SetAddedCurrencies( - val wallets: List, - val derivationStyle: DerivationStyle?, - ) : TokensAction() - - data class SaveChanges( - val addedTokens: List, - val addedBlockchains: List, - ) : TokensAction() - - object PrepareAndNavigateToAddCustomToken : TokensAction() - - data class SetSearchInput(val searchInput: String) : TokensAction() + // TODO: Remove this action in 4.7 release + object PrepareAndNavigateToAddCustomToken : TokensAction } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt index cab038d65e..70a7e1b2cd 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensMiddleware.kt @@ -8,13 +8,10 @@ import com.tangem.common.extensions.ByteArrayKey import com.tangem.common.extensions.guard import com.tangem.common.extensions.toMapKey import com.tangem.common.flatMap -import com.tangem.common.services.Result import com.tangem.core.analytics.Analytics import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.domain.DomainWrapped import com.tangem.domain.common.TapWorkarounds.derivationStyle -import com.tangem.domain.common.TapWorkarounds.isTestCard -import com.tangem.domain.common.extensions.supportedBlockchains import com.tangem.domain.common.util.hasDerivation import com.tangem.domain.common.util.supportsHdWallet import com.tangem.domain.features.addCustomToken.CustomCurrency @@ -32,132 +29,76 @@ import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.TapError import com.tangem.tap.domain.model.WalletDataModel -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 import com.tangem.tap.userWalletsListManager import com.tangem.tap.walletCurrenciesManager -import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.rekotlin.Middleware import timber.log.Timber -@Suppress("LargeClass") -class TokensMiddleware { +object TokensMiddleware { val tokensMiddleware: Middleware = { _, _ -> { next -> { action -> when (action) { - is TokensAction.LoadCurrencies -> handleLoadCurrencies(action.scanResponse) is TokensAction.SaveChanges -> handleSaveChanges(action) is TokensAction.PrepareAndNavigateToAddCustomToken -> handleAddingCustomToken() - is TokensAction.SetSearchInput -> { - Analytics.send(ManageTokens.TokenSearched()) - handleLoadCurrencies( - scanResponse = store.state.globalState.scanResponse, - newSearchInput = action.searchInput, - ) - } - is TokensAction.LoadMore -> { - if (store.state.tokensState.needToLoadMore && - store.state.tokensState.currencies.isNotEmpty() - ) { - handleLoadCurrencies(action.scanResponse) - } - } } next(action) } } } - private fun handleLoadCurrencies(scanResponse: ScanResponse?, newSearchInput: String? = null) { - val tokensState = store.state.tokensState - - val supportedBlockchains: List = scanResponse?.card?.supportedBlockchains() - ?: Blockchain.values().toList().filterNot(Blockchain::isTestnet) - - val loadCoinsService = LoadAvailableCoinsService( - tangemTechApi = store.state.domainNetworks.tangemTechService.api, - dispatchers = AppCoroutineDispatcherProvider(), - assetReader = store.state.daggerGraphState.get(DaggerGraphState::assetReader), - ) - + private fun handleSaveChanges(action: TokensAction.SaveChanges) { scope.launch { - val result = loadCoinsService.getSupportedTokens( - isTestNet = scanResponse?.card?.isTestCard ?: false, - supportedBlockchains = supportedBlockchains, - page = if (newSearchInput == null) tokensState.pageToLoad else 0, - searchInput = if (newSearchInput == null) tokensState.searchInput else newSearchInput.ifBlank { null }, + val scanResponse = store.state.globalState.scanResponse ?: return@launch + + val currentTokens = store.state.tokensState.addedTokens + val currentBlockchains = store.state.tokensState.addedBlockchains + + val blockchainsToAdd = action.blockchains.filterNot(currentBlockchains::contains) + val blockchainsToRemove = + store.state.tokensState.addedBlockchains.filterNot(action.blockchains::contains) + + val tokensToAdd = action.tokens.filterNot(currentTokens::contains) + val tokensToRemove = currentTokens.filterNot { token -> action.tokens.any { it.token == token.token } } + + removeCurrenciesIfNeeded( + currencies = convertToCurrencies( + blockchains = blockchainsToRemove, + tokens = tokensToRemove, + derivationStyle = scanResponse.card.derivationStyle, + ), ) - store.dispatchOnMain( - action = when (result) { - is Result.Success -> { - TokensAction.LoadCurrencies.Success( - currencies = result.data.currencies.filter(supportedBlockchains.toSet()), - loadMore = result.data.moreAvailable, - ) - } - is Result.Failure -> { - TokensAction.LoadCurrencies.Failure - } - }, - ) - } - } + val isNothingToDoWithTokens = tokensToAdd.isEmpty() && tokensToRemove.isEmpty() + val isNothingToDoWithBlockchain = blockchainsToAdd.isEmpty() && blockchainsToRemove.isEmpty() + if (isNothingToDoWithTokens && isNothingToDoWithBlockchain) { + store.dispatchDebugErrorNotification(message = "Nothing to save") + store.dispatchOnMain(NavigationAction.PopBackTo()) + return@launch + } - private fun handleSaveChanges(action: TokensAction.SaveChanges) = scope.launch { - val scanResponse = store.state.globalState.scanResponse ?: return@launch - - val currentTokens = store.state.tokensState.addedWallets.toNonCustomTokensWithBlockchains( - derivationStyle = scanResponse.card.derivationStyle, - ) - val currentBlockchains = store.state.tokensState.addedWallets.toNonCustomBlockchains( - derivationStyle = scanResponse.card.derivationStyle, - ) - - val blockchainsToAdd = action.addedBlockchains.filterNot(currentBlockchains::contains) - val blockchainsToRemove = currentBlockchains.filterNot(action.addedBlockchains::contains) - - val tokensToAdd = action.addedTokens.filterNot(currentTokens::contains) - val tokensToRemove = currentTokens.filterNot { token -> action.addedTokens.any { it.token == token.token } } - - removeCurrenciesIfNeeded( - currencies = convertToCurrencies( - blockchains = blockchainsToRemove, - tokens = tokensToRemove, + val currencyList = convertToCurrencies( + blockchains = blockchainsToAdd, + tokens = tokensToAdd, derivationStyle = scanResponse.card.derivationStyle, - ), - ) + ) - val isNothingToDoWithTokens = tokensToAdd.isEmpty() && tokensToRemove.isEmpty() - val isNothingToDoWithBlockchain = blockchainsToAdd.isEmpty() && blockchainsToRemove.isEmpty() - if (isNothingToDoWithTokens && isNothingToDoWithBlockchain) { - store.dispatchDebugErrorNotification(message = "Nothing to save") - store.dispatchOnMain(NavigationAction.PopBackTo()) - return@launch - } - - val currencyList = convertToCurrencies( - blockchains = blockchainsToAdd, - tokens = tokensToAdd, - derivationStyle = scanResponse.card.derivationStyle, - ) - - if (scanResponse.supportsHdWallet()) { - deriveMissingBlockchains(scanResponse, currencyList) { - submitAdd(it, currencyList) + if (scanResponse.supportsHdWallet()) { + deriveMissingBlockchains(scanResponse, currencyList) { + submitAdd(it, currencyList) + store.dispatchOnMain(NavigationAction.PopBackTo()) + } + } else { + submitAdd(scanResponse, currencyList) store.dispatchOnMain(NavigationAction.PopBackTo()) } - } else { - submitAdd(scanResponse, currencyList) - store.dispatchOnMain(NavigationAction.PopBackTo()) } } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt index 7b5d5eaef5..e2589be5b7 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensReducer.kt @@ -1,6 +1,11 @@ package com.tangem.tap.features.tokens.legacy.redux +import com.tangem.blockchain.common.Blockchain +import com.tangem.blockchain.common.DerivationStyle import com.tangem.tap.common.redux.AppState +import com.tangem.tap.domain.model.WalletDataModel +import com.tangem.tap.features.wallet.models.Currency +import com.tangem.tap.features.wallet.models.Currency.Token import org.rekotlin.Action object TokensReducer { @@ -10,47 +15,41 @@ object TokensReducer { private fun internalReduce(action: Action, state: AppState): TokensState { if (action !is TokensAction) return state.tokensState - val tokensState = state.tokensState return when (action) { - is TokensAction.ResetState -> TokensState() - is TokensAction.LoadCurrencies -> { - val loadingState = if (tokensState.currencies.isEmpty()) { - LoadCoinsState.LOADING - } else { - LoadCoinsState.LOADED - } - tokensState.copy( - scanResponse = action.scanResponse, - loadCoinsState = loadingState, - ) - } - is TokensAction.LoadCurrencies.Success -> { - tokensState.copy( - currencies = tokensState.currencies + action.currencies, - needToLoadMore = action.loadMore, - pageToLoad = tokensState.pageToLoad + 1, - loadCoinsState = LoadCoinsState.LOADED, - ) - } - is TokensAction.SetAddedCurrencies -> { - tokensState.copy( + is TokensAction.SetArgs.ManageAccess -> { + state.tokensState.copy( + isManageAccess = true, + addedWallets = action.wallets, addedBlockchains = action.wallets.toNonCustomBlockchains(action.derivationStyle), addedTokens = action.wallets.toNonCustomTokensWithBlockchains(action.derivationStyle), - addedWallets = action.wallets, ) } - is TokensAction.AllowToAddTokens -> { - tokensState.copy(allowToAdd = action.allow) + + is TokensAction.SetArgs.ReadAccess -> { + state.tokensState.copy(isManageAccess = false) } - is TokensAction.SetSearchInput -> { - tokensState.copy( - searchInput = action.searchInput.ifBlank { null }, - needToLoadMore = true, - currencies = emptyList(), - pageToLoad = 0, - loadCoinsState = LoadCoinsState.LOADING, - ) - } - else -> tokensState + + else -> state.tokensState } +} + +private fun List.toNonCustomBlockchains(derivationStyle: DerivationStyle?): List { + return mapNotNull { walletDataModel -> + if (walletDataModel.currency.isCustomCurrency(derivationStyle)) { + null + } else { + (walletDataModel.currency as? Currency.Blockchain)?.blockchain + } + }.distinct() +} + +private fun List.toNonCustomTokensWithBlockchains( + derivationStyle: DerivationStyle?, +): List { + return mapNotNull { walletDataModel -> + if (walletDataModel.currency !is Token) return@mapNotNull null + if (walletDataModel.currency.isCustomCurrency(derivationStyle)) return@mapNotNull null + + TokenWithBlockchain(walletDataModel.currency.token, walletDataModel.currency.blockchain) + }.distinct() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt index 4f77d60fac..156fd0c922 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/legacy/redux/TokensState.kt @@ -1,76 +1,16 @@ package com.tangem.tap.features.tokens.legacy.redux import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.DerivationStyle import com.tangem.blockchain.common.Token -import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.common.extensions.canHandleToken -import com.tangem.domain.common.extensions.fromNetworkId import com.tangem.tap.domain.model.WalletDataModel -import com.tangem.tap.domain.tokens.Currency import org.rekotlin.StateType -import com.tangem.tap.features.wallet.models.Currency.Token as CurrencyToken data class TokensState( + val isManageAccess: Boolean = false, val addedWallets: List = emptyList(), val addedTokens: List = emptyList(), val addedBlockchains: List = emptyList(), - val currencies: List = emptyList(), - val searchInput: String? = null, - val allowToAdd: Boolean = true, - val scanResponse: ScanResponse? = null, - val needToLoadMore: Boolean = true, - val pageToLoad: Int = 0, - val loadCoinsState: LoadCoinsState = LoadCoinsState.LOADING, -) : StateType { +) : StateType - fun canHandleToken(token: TokenWithBlockchain): Boolean { - return scanResponse?.card?.canHandleToken(token.blockchain) ?: false - } -} - -typealias ContractAddress = String - -fun List.toNonCustomTokensWithBlockchains( - derivationStyle: DerivationStyle?, -): List { - return mapNotNull { - if (it.currency !is CurrencyToken) return@mapNotNull null - if (it.currency.isCustomCurrency(derivationStyle)) return@mapNotNull null - TokenWithBlockchain(it.currency.token, it.currency.blockchain) - }.distinct() -} - -fun List.toNonCustomBlockchains(derivationStyle: DerivationStyle?): List { - return mapNotNull { - if (it.currency.isCustomCurrency(derivationStyle)) { - null - } else { - (it.currency as? com.tangem.tap.features.wallet.models.Currency.Blockchain)?.blockchain - } - }.distinct() -} - -data class TokenWithBlockchain( - val token: Token, - val blockchain: Blockchain, -) - -fun List.filter(supportedBlockchains: Set?): List { - if (supportedBlockchains == null) return this - - return map { currency -> - currency.copy( - contracts = currency.contracts.filter { contract -> - supportedBlockchains.contains(contract.blockchain) && - (contract.blockchain.canHandleTokens() || contract.address == null) - }, - ) - }.filterNot { currency -> - currency.contracts.isEmpty() && !supportedBlockchains.contains(Blockchain.fromNetworkId(currency.id)) - } -} - -enum class LoadCoinsState { - LOADING, LOADED, -} \ No newline at end of file +// TODO: [REDACTED_TASK_KEY] Remove this class +data class TokenWithBlockchain(val token: Token, val blockchain: Blockchain) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesScreen.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesScreen.kt deleted file mode 100644 index 6088fde47a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesScreen.kt +++ /dev/null @@ -1,232 +0,0 @@ -@file:Suppress("MagicNumber") - -package com.tangem.tap.features.tokens.legacy.ui.compose - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.FabPosition -import androidx.compose.material.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.stringResource -import com.tangem.blockchain.common.Blockchain -import com.tangem.core.analytics.Analytics -import com.tangem.core.ui.components.Keyboard -import com.tangem.core.ui.components.PrimaryButton -import com.tangem.core.ui.components.SystemBarsEffect -import com.tangem.core.ui.components.keyboardAsState -import com.tangem.core.ui.res.TangemTheme -import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation -import com.tangem.domain.common.extensions.fromNetworkId -import com.tangem.tap.common.analytics.events.AnalyticsParam -import com.tangem.tap.common.analytics.events.ManageTokens -import com.tangem.tap.common.compose.extensions.addAndNotify -import com.tangem.tap.common.compose.extensions.removeAndNotify -import com.tangem.tap.common.extensions.dispatchDialogShow -import com.tangem.tap.common.redux.AppDialog -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.LoadCoinsState -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain -import com.tangem.tap.features.tokens.legacy.redux.TokensState -import com.tangem.tap.features.wallet.redux.models.WalletDialog -import com.tangem.tap.store -import com.tangem.wallet.R - -@Suppress("LongMethod") -@Composable -fun CurrenciesScreen( - tokensState: MutableState, - onSaveChanges: (List, List) -> Unit, - onNetworkItemClick: (ContractAddress) -> Unit, - onLoadMore: () -> Unit, -) { - val tokensAddedOnMainScreen = remember { tokensState.value.addedTokens } - val blockchainsAddedOnMainScreen = remember { tokensState.value.addedBlockchains } - - val addedTokensState = remember { mutableStateOf(tokensState.value.addedTokens) } - val addedBlockchainsState = remember { mutableStateOf(tokensState.value.addedBlockchains) } - - val keyboardState by keyboardAsState() - - val onAddCurrencyToggleClick = { currency: Currency, token: TokenWithBlockchain? -> - val blockchain = Blockchain.fromNetworkId(currency.id) - if (blockchain != null && token == null) { - toggleBlockchain( - blockchain, - blockchainsAddedOnMainScreen, - addedBlockchainsState, - addedTokensState.value, - ) - } else if (token != null) { - toggleToken( - token, - tokensAddedOnMainScreen, - addedTokensState, - tokensState.value, - ) - } - } - - val statusBarColor = colorResource(id = R.color.backgroundLightGray) - SystemBarsEffect { - setSystemBarsColor(color = statusBarColor) - } - - Scaffold( - floatingActionButton = { - if (tokensState.value.allowToAdd) { - SaveChangesButton(keyboardState) { - onSaveChanges(addedTokensState.value, addedBlockchainsState.value) - } - } - }, - floatingActionButtonPosition = FabPosition.Center, - ) { - AnimatedVisibility( - visible = tokensState.value.loadCoinsState == LoadCoinsState.LOADING, - enter = fadeIn(), - exit = fadeOut(), - ) { - Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - CircularProgressIndicator(color = Color(0xFF1ACE80)) - } - } - AnimatedVisibility( - visible = tokensState.value.loadCoinsState == LoadCoinsState.LOADED, - enter = fadeIn(animationSpec = tween(1000)), - exit = fadeOut(animationSpec = tween(1000)), - ) { - Column { - val showHeader = tokensState.value.scanResponse?.card?.useOldStyleDerivation == true - ListOfCurrencies( - header = { if (showHeader) CurrenciesWarning() }, - currencies = tokensState.value.currencies, - addedTokens = addedTokensState.value, - addedBlockchains = addedBlockchainsState.value, - allowToAdd = tokensState.value.allowToAdd, - onAddCurrencyToggle = { currency, token -> - onAddCurrencyToggleClick(currency, token) - }, - onNetworkItemClick = onNetworkItemClick, - onLoadMore = onLoadMore, - ) - } - } - } -} - -private fun toggleBlockchain( - blockchain: Blockchain, - blockchainsAddedOnMainScreen: List, - addedBlockchainsState: MutableState>, - addedTokens: List, -) { - val isTryingToRemove = addedBlockchainsState.value.contains(blockchain) - val isAddedOnMainScreen = blockchainsAddedOnMainScreen.contains(blockchain) - val isTokenWithSameBlockchainFound = addedTokens.any { it.blockchain == blockchain } - val analyticsCurrencyTypeParam = AnalyticsParam.CurrencyType.Blockchain(blockchain) - - if (isTryingToRemove) { - if (isTokenWithSameBlockchainFound) { - store.dispatchDialogShow( - WalletDialog.TokensAreLinkedDialog( - currencyTitle = blockchain.name, - currencySymbol = blockchain.currency, - ), - ) - } else if (isAddedOnMainScreen) { - store.dispatchDialogShow( - WalletDialog.RemoveWalletDialog( - currencyTitle = blockchain.name, - onOk = { - analyticsCurrencyTypeParam.sendOn() - addedBlockchainsState.removeAndNotify(blockchain) - }, - ), - ) - } else { - analyticsCurrencyTypeParam.sendOff() - addedBlockchainsState.removeAndNotify(blockchain) - } - } else { - analyticsCurrencyTypeParam.sendOn() - addedBlockchainsState.addAndNotify(blockchain) - } -} - -private fun toggleToken( - token: TokenWithBlockchain, - tokensAddedOnMainScreen: List, - addedTokensState: MutableState>, - tokensState: TokensState, -) { - val isTryingToRemove = addedTokensState.value.contains(token) - val isAddedOnMainScreen = tokensAddedOnMainScreen.contains(token) - val isUnsupportedToken = !tokensState.canHandleToken(token) - val analyticsCurrencyTypeParam = AnalyticsParam.CurrencyType.Token(token.token) - - if (isTryingToRemove) { - if (isAddedOnMainScreen) { - store.dispatchDialogShow( - WalletDialog.RemoveWalletDialog( - currencyTitle = token.token.name, - onOk = { - analyticsCurrencyTypeParam.sendOff() - addedTokensState.removeAndNotify(token) - }, - ), - ) - } else { - analyticsCurrencyTypeParam.sendOff() - addedTokensState.removeAndNotify(token) - } - } else { - if (isUnsupportedToken) { - store.dispatchDialogShow( - AppDialog.SimpleOkDialogRes( - headerId = R.string.common_warning, - messageId = R.string.alert_manage_tokens_unsupported_message, - ), - ) - } else { - analyticsCurrencyTypeParam.sendOn() - addedTokensState.addAndNotify(token) - } - } -} - -private fun AnalyticsParam.CurrencyType.sendOn() { - Analytics.send(ManageTokens.TokenSwitcherChanged(this, AnalyticsParam.OnOffState.On)) -} - -private fun AnalyticsParam.CurrencyType.sendOff() { - Analytics.send(ManageTokens.TokenSwitcherChanged(this, AnalyticsParam.OnOffState.Off)) -} - -@Composable -fun SaveChangesButton(keyboardState: Keyboard, onSaveChanges: () -> Unit) { - PrimaryButton( - modifier = Modifier - .padding(bottom = keyboardState.height) - .padding(horizontal = TangemTheme.dimens.spacing16) - .fillMaxWidth(), - text = stringResource(id = R.string.common_save_changes), - onClick = onSaveChanges, - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesWarning.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesWarning.kt deleted file mode 100644 index b4b94b8edb..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrenciesWarning.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.tangem.wallet.R - -@Suppress("MagicNumber") -@Composable -fun CurrenciesWarning() { - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .padding(16.dp) - .background( - color = Color(0xFFF2F2F2), - shape = RoundedCornerShape(10.dp), - ), - ) { - val warning = stringResource(id = R.string.alert_manage_tokens_addresses_message) - val end = warning.indexOf(" ") - val spanStyles = listOf( - AnnotatedString.Range( - SpanStyle(fontWeight = FontWeight.Bold), - start = 0, - end = end, - ), - ) - Text( - text = AnnotatedString(text = warning, spanStyles = spanStyles), - textAlign = TextAlign.Start, - color = Color(0xFF848488), - modifier = Modifier.padding( - top = 8.dp, - bottom = 8.dp, - start = 16.dp, - end = 16.dp, - ), - fontSize = 13.sp, - fontWeight = FontWeight.Normal, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrencyPlaceholderIcon.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrencyPlaceholderIcon.kt deleted file mode 100644 index 43a2885497..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/CurrencyPlaceholderIcon.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp - -@Composable -fun CurrencyPlaceholderIcon(id: String) { - val letterColor: Color = Color.White - val circleColor: Color = Color.Black - - Box( - contentAlignment = Alignment.Center, - modifier = Modifier - .background(circleColor, shape = CircleShape), - ) { - Text( - text = id.firstOrNull()?.titlecase() ?: "", - textAlign = TextAlign.Center, - color = letterColor, - modifier = Modifier.padding(4.dp), - fontSize = 20.sp, - fontWeight = FontWeight.Bold, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/ListOfCurrencies.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/ListOfCurrencies.kt deleted file mode 100644 index 4f067daa9d..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/ListOfCurrencies.kt +++ /dev/null @@ -1,74 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.common.compose.extensions.HideKeyboardOnScroll -import com.tangem.tap.common.compose.extensions.OnBottomReached -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain -import com.tangem.tap.features.tokens.legacy.ui.compose.currencyItem.CurrencyItem - -@Suppress("LongParameterList") -@Composable -fun ListOfCurrencies( - header: @Composable () -> Unit, - currencies: List, - addedTokens: List, - addedBlockchains: List, - allowToAdd: Boolean, - onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClick: (ContractAddress) -> Unit, - onLoadMore: () -> Unit, -) { - val expandedCurrencies = remember { mutableStateOf(listOf("")) } - - val onCurrencyClick = { currencyId: String -> - val mutableList = expandedCurrencies.value.toMutableList() - if (mutableList.contains(currencyId)) { - mutableList.remove(currencyId) - } else { - mutableList.add(currencyId) - } - expandedCurrencies.value = mutableList - } - - val listState = rememberLazyListState() - listState.HideKeyboardOnScroll() - listState.OnBottomReached(loadMoreThreshold = 40) { onLoadMore() } - - LazyColumn( - state = listState, - modifier = Modifier - .fillMaxSize(), - contentPadding = PaddingValues(bottom = 90.dp), - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - item { header() } - itemsIndexed(currencies) { _, currency -> - CurrencyItem( - currency = currency, - addedTokens = addedTokens, - addedBlockchains = addedBlockchains, - allowToAdd = allowToAdd, - isExpanded = expandedCurrencies.value.contains(currency.id), - onCurrencyClick = { onCurrencyClick(currency.id) }, - onAddCurrencyToggle = onAddCurrencyToggle, - onNetworkItemClick = onNetworkItemClick, - ) - } - } -} - -val Currency.fullName: String - get() = "${this.name} (${this.symbol})" \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyExpandedContent.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyExpandedContent.kt deleted file mode 100644 index 9ea93f61d6..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyExpandedContent.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose.currencyItem - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.expandVertically -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.shrinkVertically -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.domain.tokens.Contract -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain - -@Suppress("LongParameterList") -@Composable -fun CurrencyExpandedContent( - currency: Currency, - addedTokens: List, - addedBlockchains: List, - allowToAdd: Boolean, - isExpanded: Boolean, - onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClick: (ContractAddress) -> Unit, -) { - AnimatedVisibility( - visible = isExpanded, - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically(), - ) { - val blockchains = currency.contracts.map { it.blockchain } - Column(modifier = Modifier.fillMaxWidth()) { - blockchains.mapIndexed { index, blockchain -> - val currencyContract = currency.contracts - .firstOrNull { it.blockchain == blockchain } - ?: return@mapIndexed - - val added = if (currencyContract.address != null) { - addedTokens.any(currencyContract::isInclude) - } else { - addedBlockchains.contains(blockchain) - } - NetworkItem( - currency = currency, - contract = currencyContract, - blockchain = blockchain, - allowToAdd = allowToAdd, - added = added, - index = index, - size = blockchains.size, - onAddCurrencyToggle = onAddCurrencyToggle, - onNetworkItemClick = onNetworkItemClick, - ) - } - } - } -} - -private fun Contract.isInclude(addedToken: TokenWithBlockchain): Boolean = - address == addedToken.token.contractAddress && blockchain == addedToken.blockchain \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItem.kt deleted file mode 100644 index a15c17000f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItem.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose.currencyItem - -import androidx.compose.foundation.layout.Column -import androidx.compose.runtime.Composable -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain - -@Suppress("LongParameterList") -@Composable -fun CurrencyItem( - currency: Currency, - addedTokens: List, - addedBlockchains: List, - allowToAdd: Boolean, - isExpanded: Boolean, - onCurrencyClick: () -> Unit, - onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClick: (ContractAddress) -> Unit, -) { - Column { - CurrencyItemHeader( - currency = currency, - addedTokens = addedTokens, - addedBlockchains = addedBlockchains, - isExpanded = isExpanded, - onCurrencyClick = onCurrencyClick, - ) - CurrencyExpandedContent( - currency = currency, - addedTokens = addedTokens, - addedBlockchains = addedBlockchains, - allowToAdd = allowToAdd, - isExpanded = isExpanded, - onAddCurrencyToggle = onAddCurrencyToggle, - onNetworkItemClick = onNetworkItemClick, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItemHeader.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItemHeader.kt deleted file mode 100644 index bf5fc63457..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/CurrencyItemHeader.kt +++ /dev/null @@ -1,213 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose.currencyItem - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil.compose.SubcomposeAsyncImage -import coil.request.ImageRequest -import com.tangem.blockchain.common.Blockchain -import com.tangem.core.ui.extensions.getActiveIconRes -import com.tangem.domain.common.extensions.fromNetworkId -import com.tangem.tap.common.extensions.getGreyedOutIconRes -import com.tangem.tap.domain.tokens.Contract -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain -import com.tangem.tap.features.tokens.legacy.ui.compose.CurrencyPlaceholderIcon -import com.tangem.tap.features.tokens.legacy.ui.compose.fullName -import com.tangem.wallet.R - -@Suppress("LongMethod", "MagicNumber") -@Composable -fun CurrencyItemHeader( - currency: Currency, - addedTokens: List, - addedBlockchains: List, - isExpanded: Boolean, - onCurrencyClick: () -> Unit, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 62.dp) - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onCurrencyClick, - ), - ) { - Box( - modifier = Modifier - .padding(horizontal = 16.dp) - .align(Alignment.CenterVertically) - .clip(RoundedCornerShape(6.dp)), - ) { - SubcomposeAsyncImage( - modifier = Modifier - .size(46.dp), - model = ImageRequest.Builder(LocalContext.current) - .data(currency.iconUrl) - .crossfade(true) - .build(), - contentDescription = currency.id, - loading = { CurrencyPlaceholderIcon(currency.id) }, - error = { CurrencyPlaceholderIcon(currency.id) }, - ) - } - - Column( - modifier = Modifier - .weight(1f) - .align(Alignment.CenterVertically), - ) { - Text( - text = currency.fullName, - fontSize = 17.sp, - fontWeight = FontWeight.Normal, - color = Color(0xFF1C1C1E), - ) - Spacer(modifier = Modifier.size(6.dp)) - - Box( - modifier = Modifier - .fillMaxWidth() - .height(20.dp), - ) { - if (isExpanded) { - Text( - modifier = Modifier.align(Alignment.TopStart), - text = stringResource(id = R.string.currency_subtitle_expanded), - fontSize = 13.sp, - fontWeight = FontWeight.Normal, - color = Color(0xFF8E8E93), - ) - } else { - NetworksRow( - currency = currency, - addedTokens = addedTokens, - addedBlockchains = addedBlockchains, - ) - } - } - } - - val expandCollapseArrow = if (isExpanded) R.drawable.ic_arrow_extended else R.drawable.ic_arrow_collapsed - Image( - painter = painterResource(id = expandCollapseArrow), - contentDescription = null, - Modifier - .padding(20.dp) - .align(Alignment.CenterVertically), - ) - } -} - -@Composable -private fun NetworksRow( - currency: Currency, - addedTokens: List, - addedBlockchains: List, -) { - Row { - if (currency.contracts.isNotEmpty()) { - currency.contracts.map { contract -> - if (contract.address == null) { - BlockchainNetworkItem( - blockchain = contract.blockchain, - isMainNetwork = true, - addedBlockchains = addedBlockchains, - ) - } else { - val isAdded = addedTokens.any(contract::isInclude) - val iconResId = if (isAdded) { - getActiveIconRes(contract.blockchain.id) - } else { - contract.blockchain.getGreyedOutIconRes() - } - Image( - modifier = Modifier - .size(20.dp), - painter = painterResource(id = iconResId), - contentDescription = null, - ) - Spacer(Modifier.size(5.dp)) - } - } - } else { - BlockchainNetworkItem( - blockchain = Blockchain.fromNetworkId(currency.id), - isMainNetwork = false, - addedBlockchains = addedBlockchains, - ) - } - } -} - -@Suppress("MagicNumber") -@Composable -private fun BlockchainNetworkItem( - blockchain: Blockchain?, - isMainNetwork: Boolean, - addedBlockchains: List, -) { - val added = addedBlockchains.contains(blockchain) - val icon = if (added) blockchain?.let { getActiveIconRes(it.id) } else blockchain?.getGreyedOutIconRes() - if (icon != null) { - Box( - Modifier - .size(20.dp), - ) { - Image( - painter = painterResource(id = icon), - contentDescription = null, - Modifier - .size(20.dp), - ) - if (isMainNetwork) { - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .size(7.dp) - .clip(CircleShape) - .background(Color.White), - ) { - Box( - modifier = Modifier - .align(Alignment.Center) - .size(5.dp) - .clip(CircleShape) - .background(Color(0xFF1ACE80)), - ) - } - } - } - Spacer(modifier = Modifier.size(5.dp)) - } -} - -private fun Contract.isInclude(addedToken: TokenWithBlockchain): Boolean = - address == addedToken.token.contractAddress && blockchain == addedToken.blockchain \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/NetworkItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/NetworkItem.kt deleted file mode 100644 index 4d7eab3fb6..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/legacy/ui/compose/currencyItem/NetworkItem.kt +++ /dev/null @@ -1,186 +0,0 @@ -package com.tangem.tap.features.tokens.legacy.ui.compose.currencyItem - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background -import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Switch -import androidx.compose.material.SwitchDefaults -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.AnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil.compose.SubcomposeAsyncImage -import com.tangem.blockchain.common.Blockchain -import com.tangem.blockchain.common.Token -import com.tangem.core.ui.extensions.getActiveIconRes -import com.tangem.tap.common.extensions.fullNameWithoutTestnet -import com.tangem.tap.common.extensions.getGreyedOutIconRes -import com.tangem.tap.common.extensions.getNetworkName -import com.tangem.tap.domain.tokens.Contract -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.impl.presentation.ui.NetworkItemArrow -import com.tangem.tap.features.tokens.legacy.redux.ContractAddress -import com.tangem.tap.features.tokens.legacy.redux.TokenWithBlockchain -import com.tangem.tap.features.tokens.legacy.ui.compose.CurrencyPlaceholderIcon - -@Suppress("LongParameterList", "LongMethod", "MagicNumber") -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun NetworkItem( - currency: Currency, - contract: Contract, - blockchain: Blockchain, - allowToAdd: Boolean, - added: Boolean, - index: Int, - size: Int, - onAddCurrencyToggle: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClick: (ContractAddress) -> Unit, -) { - val rowHeight = 53.dp - - Row( - modifier = Modifier - .fillMaxWidth() - .heightIn(rowHeight) - .combinedClickable( - enabled = allowToAdd, - onLongClick = { - contract.address?.let { onNetworkItemClick(it) } - }, - onClick = {}, - indication = null, - interactionSource = remember { MutableInteractionSource() }, - ), - ) { - Box( - Modifier - .width(78.dp) - .padding(start = 38.dp), - ) { - NetworkItemArrow( - itemHeight = rowHeight, - isLastItem = index == size - 1, - ) - } - Box( - modifier = Modifier - .align(Alignment.CenterVertically), - ) { - SubcomposeAsyncImage( - model = if (added) getActiveIconRes(blockchain.id) else blockchain.getGreyedOutIconRes(), - contentDescription = blockchain.fullName, - loading = { CurrencyPlaceholderIcon(blockchain.id) }, - error = { CurrencyPlaceholderIcon(blockchain.id) }, - modifier = Modifier - .size(20.dp), - ) - if (contract.address == null) { - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .size(7.dp) - .clip(CircleShape) - .background(Color.White), - ) { - Box( - modifier = Modifier - .align(Alignment.Center) - .size(5.dp) - .clip(CircleShape) - .background(Color(0xFF1ACE80)), - ) - } - } - } - Spacer(Modifier.width(6.dp)) - Text( - modifier = Modifier - .weight(1f) - .align(Alignment.CenterVertically), - text = prepareNetworkNameSpannableText( - blockchain = blockchain, - contractAddress = contract.address, - ), - fontWeight = FontWeight.SemiBold, - fontSize = 13.sp, - color = if (added) Color.Black else Color(0xFF848488), - ) - - if (allowToAdd) { - val token = if (contract.address != null) { - Token( - id = currency.id, - name = currency.name, - symbol = currency.symbol, - contractAddress = contract.address, - decimals = contract.decimalCount!!, - ) - } else { - null - } - val tokenWithBlockchain = token?.let { TokenWithBlockchain(it, contract.blockchain) } - - val currencyToSave = if (contract.address == null) { - currency.copy(id = contract.networkId) - } else { - currency - } - - Switch( - modifier = Modifier - .fillMaxHeight() - .padding(start = 16.dp, end = 16.dp), - checked = added, - onCheckedChange = { onAddCurrencyToggle(currencyToSave, tokenWithBlockchain) }, - colors = SwitchDefaults.colors( - checkedThumbColor = Color(0xFF1ACE80), - ), - ) - } - } -} - -@Suppress("MagicNumber") -@Composable -private fun prepareNetworkNameSpannableText(blockchain: Blockchain, contractAddress: String?): AnnotatedString { - val blockchainName = blockchain.fullNameWithoutTestnet.uppercase() - val additionalText = - if (contractAddress == null) "MAIN" else blockchain.getNetworkName().uppercase() - - val text = "$blockchainName $additionalText" - - val startOfAdditionalText = - if (additionalText.isNotBlank()) text.indexOf(additionalText) else text.length - - val spanStyles = listOf( - AnnotatedString.Range( - SpanStyle( - fontWeight = FontWeight.Normal, - color = if (contractAddress != null) Color(0xFF8E8E93) else Color(0xFF1ACE80), - ), - start = startOfAdditionalText, - end = text.length, - ), - ) - return AnnotatedString(text = text, spanStyles = spanStyles) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt index fbe46121d7..269f0ec071 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/wallet/MultiWalletView.kt @@ -6,7 +6,6 @@ import com.badoo.mvicore.modelWatcher import com.tangem.core.analytics.Analytics import com.tangem.domain.common.TapWorkarounds.derivationStyle import com.tangem.tap.common.analytics.events.MainScreen -import com.tangem.tap.common.analytics.events.ManageTokens import com.tangem.tap.common.analytics.events.Portfolio import com.tangem.tap.common.entities.FiatCurrency import com.tangem.tap.common.extensions.getQuantityString @@ -108,16 +107,13 @@ class MultiWalletView : WalletView() { binding.btnAddToken.setOnClickListener { val card = store.state.globalState.scanResponse!!.card Analytics.send(Portfolio.ButtonManageTokens()) - store.dispatch(TokensAction.LoadCurrencies(scanResponse = store.state.globalState.scanResponse)) - store.dispatch(TokensAction.AllowToAddTokens(true)) + store.dispatch( - TokensAction.SetAddedCurrencies( + TokensAction.SetArgs.ManageAccess( wallets = state.walletsDataFromStores, derivationStyle = card.derivationStyle, ), ) - - Analytics.send(ManageTokens.ScreenOpened()) store.dispatch(NavigationAction.NavigateTo(AppScreen.AddTokens)) } handleErrorStates(state = state, binding = binding, fragment = fragment) @@ -175,7 +171,8 @@ class MultiWalletView : WalletView() { fragment.getString(R.string.wallet_error_unsupported_blockchain_subtitle), ) } - else -> { /* no-op */ } + + else -> Unit } } 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 dd0a501489..73fc659cf8 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 @@ -4,14 +4,12 @@ import com.tangem.datasource.asset.AssetReader import com.tangem.datasource.connection.NetworkConnectionManager import com.tangem.features.tester.api.TesterRouter import com.tangem.tap.features.customtoken.api.featuretoggles.CustomTokenFeatureToggles -import com.tangem.tap.features.tokens.api.featuretoggles.TokensListFeatureToggles import org.rekotlin.StateType data class DaggerGraphState( val assetReader: AssetReader? = null, val testerRouter: TesterRouter? = null, val networkConnectionManager: NetworkConnectionManager? = null, - val tokensListFeatureToggles: TokensListFeatureToggles? = null, val customTokenFeatureToggles: CustomTokenFeatureToggles? = null, ) : StateType { diff --git a/app/src/main/res/layout/fragment_add_tokens.xml b/app/src/main/res/layout/fragment_add_tokens.xml deleted file mode 100644 index 0b5881f415..0000000000 --- a/app/src/main/res/layout/fragment_add_tokens.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/menu_popular_tokens.xml b/app/src/main/res/menu/menu_popular_tokens.xml deleted file mode 100644 index 5cc1ac82f8..0000000000 --- a/app/src/main/res/menu/menu_popular_tokens.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json index 96fb733d71..c44daa2e41 100644 --- a/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/featuretoggles/src/main/assets/configs/feature_toggles_config.json @@ -3,12 +3,8 @@ "name": "OPTIMISM_SWAP_FEATURE_ENABLED", "version": "4.3.1" }, - { - "name": "REDESIGNED_TOKEN_LIST_SCREEN_ENABLED", - "version": "4.4.0" - }, { "name": "REDESIGNED_CUSTOM_TOKEN_SCREEN_ENABLED", - "version": "undefined" + "version": "4.6.0" } ] \ No newline at end of file