diff --git a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt index de24b448ec..697065bb97 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/NFTDomainModule.kt @@ -35,6 +35,16 @@ internal object NFTDomainModule { nftRepository = nftRepository, ) + @Provides + @Singleton + fun providesRefreshAllUseCase( + currenciesRepository: CurrenciesRepository, + nftRepository: NFTRepository, + ): RefreshAllNFTUseCase = RefreshAllNFTUseCase( + currenciesRepository = currenciesRepository, + nftRepository = nftRepository, + ) + @Provides @Singleton fun providesFetchNFTCollectionAssetsUseCase(nftRepository: NFTRepository): FetchNFTCollectionAssetsUseCase = diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt index d69616e5d6..a302980668 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/fields/SearchBar.kt @@ -41,6 +41,7 @@ fun SearchBar( state: SearchBarUM, modifier: Modifier = Modifier, colors: TextFieldColors = TangemSearchBarDefaults.defaultTextFieldColors, + enabled: Boolean = true, ) { val keyboardController = LocalSoftwareKeyboardController.current val focusManager = LocalFocusManager.current @@ -57,6 +58,7 @@ fun SearchBar( state.onActiveChange(false) } }, + enabled = enabled, value = state.query, onValueChange = state.onQueryChange, interactionSource = interactionSource, diff --git a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt index 7b806c688a..7fe4317d15 100644 --- a/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt +++ b/data/nft/src/main/kotlin/com/tangem/data/nft/DefaultNFTRepository.kt @@ -64,38 +64,11 @@ internal class DefaultNFTRepository @Inject constructor( flowOf(NFTCollections.empty(network)) } - override suspend fun refreshCollections(userWalletId: UserWalletId, networks: List) = coroutineScope { - networks.mapNotNull { network -> - if (network.canHandleNFTs()) { - launch(dispatchers.io) { - Either.catch { - expireCollections(userWalletId, network) + override suspend fun refreshCollections(userWalletId: UserWalletId, networks: List) = + refreshCollectionsInternal(userWalletId, networks, refreshAssets = false) - val collections = walletManagersFacade.getNFTCollections(userWalletId, network) - val mergedCollections = collections.mergeWithStoredAssets(userWalletId, network) - - saveCollectionsInRuntime( - userWalletId = userWalletId, - network = network, - collections = mergedCollections, - ) - saveCollectionsInPersistence( - userWalletId = userWalletId, - network = network, - collections = mergedCollections, - ) - }.onLeft { - saveFailedStateInRuntime( - userWalletId = userWalletId, - network = network, - error = it, - ) - } - }.saveIn(getNetworkJobHolder(network)) - } else { - null - } - }.joinAll() + override suspend fun refreshAll(userWalletId: UserWalletId, networks: List) { + refreshCollectionsInternal(userWalletId, networks, refreshAssets = true) } override suspend fun refreshAssets( @@ -162,6 +135,54 @@ internal class DefaultNFTRepository @Inject constructor( assetIdentifier = NFTSdkAssetIdentifierConverter.convertBack(assetIdentifier), ) + private suspend fun refreshCollectionsInternal( + userWalletId: UserWalletId, + networks: List, + refreshAssets: Boolean, + ) = coroutineScope { + networks.mapNotNull { network -> + if (network.canHandleNFTs()) { + launch(dispatchers.io) { + Either.catch { + expireCollections(userWalletId, network) + + val collections = walletManagersFacade.getNFTCollections(userWalletId, network) + val mergedCollections = collections.mergeWithStoredAssets(userWalletId, network) + + saveCollectionsInRuntime( + userWalletId = userWalletId, + network = network, + collections = mergedCollections, + ) + saveCollectionsInPersistence( + userWalletId = userWalletId, + network = network, + collections = mergedCollections, + ) + + if (refreshAssets) { + mergedCollections.forEach { collection -> + refreshAssets( + userWalletId = userWalletId, + network = network, + collectionId = NFTSdkCollectionIdentifierConverter.convert(collection.identifier), + ) + } + } + }.onLeft { + saveFailedStateInRuntime( + userWalletId = userWalletId, + network = network, + error = it, + ) + } + }.saveIn(getNetworkJobHolder(network)) + } else { + null + } + }.joinAll() + } + private suspend fun refreshSalePrice( userWalletId: UserWalletId, network: Network, diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt new file mode 100644 index 0000000000..2e365e88a8 --- /dev/null +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/RefreshAllNFTUseCase.kt @@ -0,0 +1,16 @@ +package com.tangem.domain.nft + +import com.tangem.domain.nft.repository.NFTRepository +import com.tangem.domain.tokens.repository.CurrenciesRepository +import com.tangem.domain.wallets.models.UserWalletId + +class RefreshAllNFTUseCase( + private val currenciesRepository: CurrenciesRepository, + private val nftRepository: NFTRepository, +) { + + suspend operator fun invoke(userWalletId: UserWalletId) { + val currencies = currenciesRepository.getMultiCurrencyWalletCurrenciesSync(userWalletId) + nftRepository.refreshAll(userWalletId, currencies.map { it.network }.distinct()) + } +} \ No newline at end of file diff --git a/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt b/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt index 36ca075957..ea99cbca2a 100644 --- a/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt +++ b/domain/nft/src/main/kotlin/com/tangem/domain/nft/repository/NFTRepository.kt @@ -14,6 +14,8 @@ interface NFTRepository { suspend fun refreshAssets(userWalletId: UserWalletId, network: Network, collectionId: NFTCollection.Identifier) + suspend fun refreshAll(userWalletId: UserWalletId, networks: List) + suspend fun isNFTSupported(network: Network): Boolean suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String? diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsStateUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsStateUM.kt index 14267e3120..11a6d37285 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsStateUM.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsStateUM.kt @@ -1,6 +1,9 @@ package com.tangem.features.nft.collections.entity +import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig + internal data class NFTCollectionsStateUM( val onBackClick: () -> Unit, + val pullToRefreshConfig: PullToRefreshConfig, val content: NFTCollectionsUM, ) \ No newline at end of file diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt index 394144b65d..a8287ca423 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/NFTCollectionsUM.kt @@ -12,6 +12,7 @@ internal sealed class NFTCollectionsUM { ) : NFTCollectionsUM() data class Loading( + val search: SearchBarUM, val onReceiveClick: () -> Unit, ) : NFTCollectionsUM() diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/ChangeRefreshingStateTransformer.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/ChangeRefreshingStateTransformer.kt new file mode 100644 index 0000000000..7a2face48c --- /dev/null +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/ChangeRefreshingStateTransformer.kt @@ -0,0 +1,15 @@ +package com.tangem.features.nft.collections.entity.transformer + +import com.tangem.features.nft.collections.entity.NFTCollectionsStateUM +import com.tangem.utils.transformer.Transformer + +internal class ChangeRefreshingStateTransformer( + private val isRefreshing: Boolean, +) : Transformer { + + override fun transform(prevState: NFTCollectionsStateUM): NFTCollectionsStateUM = prevState.copy( + pullToRefreshConfig = prevState.pullToRefreshConfig.copy( + isRefreshing = isRefreshing, + ), + ) +} \ No newline at end of file diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/UpdateDataStateTransformer.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/UpdateDataStateTransformer.kt index a0cfab6956..bb684cf18b 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/UpdateDataStateTransformer.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/entity/transformer/UpdateDataStateTransformer.kt @@ -4,6 +4,7 @@ import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.components.notifications.NotificationConfig import com.tangem.core.ui.extensions.TextReference import com.tangem.core.ui.extensions.getActiveIconRes +import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.wrappedList import com.tangem.domain.nft.models.* import com.tangem.features.nft.collections.entity.* @@ -24,8 +25,8 @@ internal class UpdateDataStateTransformer( private val initialSearchBarFactory: () -> SearchBarUM, ) : Transformer { - override fun transform(prevState: NFTCollectionsStateUM): NFTCollectionsStateUM = prevState.copy( - content = when { + override fun transform(prevState: NFTCollectionsStateUM): NFTCollectionsStateUM { + val content = when { nftCollections.allCollectionsFailed() -> NFTCollectionsUM.Failed(onRetryClick, onReceiveClick) nftCollections.anyCollectionFailed() && nftCollections.allLoadedCollectionsEmpty() -> @@ -33,7 +34,16 @@ internal class UpdateDataStateTransformer( nftCollections.allCollectionsLoaded() && nftCollections.allCollectionsEmpty() -> NFTCollectionsUM.Empty(onReceiveClick) !nftCollections.allCollectionsLoaded() && nftCollections.allCollectionsEmpty() -> - NFTCollectionsUM.Loading(onReceiveClick) + NFTCollectionsUM.Loading( + onReceiveClick = onReceiveClick, + search = SearchBarUM( + placeholderText = resourceReference(R.string.common_search), + query = "", + isActive = false, + onQueryChange = { }, + onActiveChange = { }, + ), + ) else -> { NFTCollectionsUM.Content( search = if (prevState.content is NFTCollectionsUM.Content) { @@ -54,8 +64,17 @@ internal class UpdateDataStateTransformer( onReceiveClick = onReceiveClick, ) } - }, - ) + } + return prevState.copy( + content = content, + pullToRefreshConfig = when (content) { + is NFTCollectionsUM.Loading -> prevState.pullToRefreshConfig.copy( + isRefreshing = false, + ) + else -> prevState.pullToRefreshConfig + }, + ) + } private fun List.transform( state: NFTCollectionsStateUM, diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/model/NFTCollectionsModel.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/model/NFTCollectionsModel.kt index 2e1ddc7a19..c35c9fc81f 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/model/NFTCollectionsModel.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/model/NFTCollectionsModel.kt @@ -3,15 +3,18 @@ package com.tangem.features.nft.collections.model import com.tangem.core.decompose.di.ModelScoped import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer +import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig import com.tangem.core.ui.components.fields.InputManager import com.tangem.core.ui.components.fields.entity.SearchBarUM import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.nft.FetchNFTCollectionAssetsUseCase import com.tangem.domain.nft.GetNFTCollectionsUseCase +import com.tangem.domain.nft.RefreshAllNFTUseCase import com.tangem.domain.nft.models.NFTCollection import com.tangem.features.nft.collections.NFTCollectionsComponent import com.tangem.features.nft.collections.entity.NFTCollectionsStateUM import com.tangem.features.nft.collections.entity.NFTCollectionsUM +import com.tangem.features.nft.collections.entity.transformer.* import com.tangem.features.nft.collections.entity.transformer.ChangeCollectionExpandedStateTransformer import com.tangem.features.nft.collections.entity.transformer.ToggleSearchBarTransformer import com.tangem.features.nft.collections.entity.transformer.UpdateDataStateTransformer @@ -29,6 +32,7 @@ internal class NFTCollectionsModel @Inject constructor( private val searchManager: InputManager, private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase, private val fetchNFTCollectionAssetsUseCase: FetchNFTCollectionAssetsUseCase, + private val refreshAllNFTUseCase: RefreshAllNFTUseCase, paramsContainer: ParamsContainer, ) : Model() { @@ -37,7 +41,20 @@ internal class NFTCollectionsModel @Inject constructor( private val _state = MutableStateFlow( value = NFTCollectionsStateUM( onBackClick = params.onBackClick, - content = NFTCollectionsUM.Loading(params.onBackClick), + content = NFTCollectionsUM.Loading( + search = SearchBarUM( + placeholderText = resourceReference(R.string.common_search), + query = "", + isActive = false, + onQueryChange = { }, + onActiveChange = { }, + ), + onReceiveClick = params.onReceiveClick, + ), + pullToRefreshConfig = PullToRefreshConfig( + isRefreshing = false, + onRefresh = { onRefresh() }, + ), ), ) @@ -59,7 +76,7 @@ internal class NFTCollectionsModel @Inject constructor( onReceiveClick = { params.onReceiveClick() }, - onRetryClick = ::onRetryClick, + onRetryClick = ::onRefresh, onExpandCollectionClick = ::onExpandCollectionClick, onRetryAssetsClick = ::onRetryAssetsClick, onAssetClick = { asset, collectionName -> @@ -69,9 +86,21 @@ internal class NFTCollectionsModel @Inject constructor( ).transform(it) } } + .onStart { onRefresh() } .launchIn(modelScope) } + private fun onRefresh() { + modelScope.launch { + _state.update { ChangeRefreshingStateTransformer(true).transform(it) } + try { + refreshAllNFTUseCase(params.userWalletId) + } finally { + _state.update { ChangeRefreshingStateTransformer(false).transform(it) } + } + } + } + private fun onSearchQueryChange(newQuery: String) { modelScope.launch { _state.update { UpdateSearchQueryTransformer(newQuery).transform(it) } @@ -111,10 +140,6 @@ internal class NFTCollectionsModel @Inject constructor( loadCollectionAssets(collection) } - private fun onRetryClick() { - // TODO refresh all - } - private fun loadCollectionAssets(collection: NFTCollection) { modelScope.launch { fetchNFTCollectionAssetsUseCase( diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollections.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollections.kt index 9dd7e06ffc..2d42caaf85 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollections.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollections.kt @@ -1,12 +1,12 @@ package com.tangem.features.nft.collections.ui import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedContent import androidx.compose.foundation.layout.* import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.tangem.core.ui.components.appbar.AppBarWithBackButton +import com.tangem.core.ui.components.containers.pullToRefresh.TangemPullToRefreshContainer import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme import com.tangem.features.nft.collections.entity.NFTCollectionsStateUM @@ -29,19 +29,17 @@ internal fun NFTCollections(state: NFTCollectionsStateUM, modifier: Modifier = M ) }, content = { innerPadding -> - AnimatedContent( - targetState = state.content, - contentKey = { it::class }, - label = "NFT Collections", - ) { - val contentModifier = Modifier + TangemPullToRefreshContainer( + config = state.pullToRefreshConfig, + modifier = Modifier .padding(innerPadding) - .fillMaxSize() - when (val content = it) { - is NFTCollectionsUM.Content -> NFTCollectionsContent(content, contentModifier) - is NFTCollectionsUM.Empty -> NFTCollectionsEmpty(content, contentModifier) - is NFTCollectionsUM.Failed -> NFTCollectionsFailed(content, contentModifier) - is NFTCollectionsUM.Loading -> Unit + .fillMaxSize(), + ) { + when (val content = state.content) { + is NFTCollectionsUM.Content -> NFTCollectionsContent(content) + is NFTCollectionsUM.Empty -> NFTCollectionsEmpty(content) + is NFTCollectionsUM.Failed -> NFTCollectionsFailed(content) + is NFTCollectionsUM.Loading -> NFTCollectionsLoading(content) } } }, diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt index 1376f56e72..1566f4d125 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsEmpty.kt @@ -3,6 +3,8 @@ package com.tangem.features.nft.collections.ui import android.content.res.Configuration import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -23,6 +25,7 @@ internal fun NFTCollectionsEmpty(state: NFTCollectionsUM.Empty, modifier: Modifi Box( modifier = modifier .fillMaxSize() + .verticalScroll(rememberScrollState()) .padding(TangemTheme.dimens.spacing16), ) { Column( diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt index d4d99bc548..2020fc02c6 100644 --- a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsFailed.kt @@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -22,6 +24,7 @@ internal fun NFTCollectionsFailed(state: NFTCollectionsUM.Failed, modifier: Modi Box( modifier = modifier .fillMaxSize() + .verticalScroll(rememberScrollState()) .padding(TangemTheme.dimens.spacing16), ) { UnableToLoadData( diff --git a/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsLoading.kt b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsLoading.kt new file mode 100644 index 0000000000..0a50c87c68 --- /dev/null +++ b/features/nft/impl/src/main/kotlin/com/tangem/features/nft/collections/ui/NFTCollectionsLoading.kt @@ -0,0 +1,142 @@ +package com.tangem.features.nft.collections.ui + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.components.PrimaryButton +import com.tangem.core.ui.components.TextShimmer +import com.tangem.core.ui.components.fields.SearchBar +import com.tangem.core.ui.components.fields.TangemSearchBarDefaults +import com.tangem.core.ui.components.fields.entity.SearchBarUM +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.features.nft.collections.entity.NFTCollectionsUM +import com.tangem.features.nft.impl.R + +private const val SHIMMER_ITEMS_COUNT = 5 + +@Composable +internal fun NFTCollectionsLoading(state: NFTCollectionsUM.Loading, modifier: Modifier = Modifier) { + Box( + modifier = modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(TangemTheme.dimens.spacing16), + ) { + Column { + SearchBar( + state = state.search, + colors = TangemSearchBarDefaults.secondaryTextFieldColors, + enabled = false, + ) + Card( + modifier = modifier + .fillMaxWidth() + .padding( + top = TangemTheme.dimens.spacing16, + ), + shape = RoundedCornerShape(TangemTheme.dimens.radius16), + colors = CardDefaults.cardColors( + containerColor = TangemTheme.colors.background.primary, + contentColor = TangemTheme.colors.text.primary1, + disabledContainerColor = TangemTheme.colors.background.primary, + disabledContentColor = TangemTheme.colors.text.primary1, + ), + ) { + Column { + repeat(SHIMMER_ITEMS_COUNT) { + CollectionPlaceholder() + } + } + } + } + PrimaryButton( + modifier = Modifier + .fillMaxWidth() + .align(Alignment.BottomCenter), + text = stringResourceSafe(R.string.nft_collections_receive), + onClick = state.onReceiveClick, + ) + } +} + +@Composable +private fun CollectionPlaceholder(modifier: Modifier = Modifier) { + Row( + modifier = modifier + .padding( + horizontal = TangemTheme.dimens.spacing12, + vertical = TangemTheme.dimens.spacing16, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + Box( + contentAlignment = Alignment.Center, + ) { + Box( + modifier = Modifier + .size(TangemTheme.dimens.size36) + .clip(RoundedCornerShape(TangemTheme.dimens.radius8)) + .background(TangemTheme.colors.field.primary), + ) + } + Column( + modifier = Modifier + .padding( + horizontal = TangemTheme.dimens.spacing12, + ) + .weight(1f), + horizontalAlignment = Alignment.Start, + ) { + TextShimmer( + modifier = Modifier.width(TangemTheme.dimens.size110), + style = TangemTheme.typography.caption2, + textSizeHeight = true, + ) + TextShimmer( + modifier = Modifier + .width(TangemTheme.dimens.size80) + .padding(top = TangemTheme.dimens.spacing4), + style = TangemTheme.typography.caption2, + textSizeHeight = true, + ) + } + } + } +} + +@Preview(widthDp = 360, showBackground = true) +@Preview(widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun Preview_NFTCollectionsLoading() { + TangemThemePreview { + NFTCollectionsLoading( + state = NFTCollectionsUM.Loading( + search = SearchBarUM( + placeholderText = resourceReference(R.string.common_search), + query = "", + isActive = false, + onQueryChange = { }, + onActiveChange = { }, + ), + onReceiveClick = { }, + ), + ) + } +} \ No newline at end of file diff --git a/gradle/tangem_dependencies.toml b/gradle/tangem_dependencies.toml index 0c3b257143..a0bc01da42 100644 --- a/gradle/tangem_dependencies.toml +++ b/gradle/tangem_dependencies.toml @@ -5,7 +5,7 @@ # https://github.com/tangem/tangem-sdk-android/ # https://github.com/tangem/vico -tangemBlockchainSdk = "develop-1041" +tangemBlockchainSdk = "develop-1042" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "develop-455" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^