Updated on 2026-08-14
This commit is contained in:
parent
c300a5eaf3
commit
d99c4e1405
15 changed files with 316 additions and 56 deletions
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -64,38 +64,11 @@ internal class DefaultNFTRepository @Inject constructor(
|
|||
flowOf(NFTCollections.empty(network))
|
||||
}
|
||||
|
||||
override suspend fun refreshCollections(userWalletId: UserWalletId, networks: List<Network>) = coroutineScope {
|
||||
networks.mapNotNull { network ->
|
||||
if (network.canHandleNFTs()) {
|
||||
launch(dispatchers.io) {
|
||||
Either.catch {
|
||||
expireCollections(userWalletId, network)
|
||||
override suspend fun refreshCollections(userWalletId: UserWalletId, networks: List<Network>) =
|
||||
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<Network>) {
|
||||
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<Network>,
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,8 @@ interface NFTRepository {
|
|||
|
||||
suspend fun refreshAssets(userWalletId: UserWalletId, network: Network, collectionId: NFTCollection.Identifier)
|
||||
|
||||
suspend fun refreshAll(userWalletId: UserWalletId, networks: List<Network>)
|
||||
|
||||
suspend fun isNFTSupported(network: Network): Boolean
|
||||
|
||||
suspend fun getNFTExploreUrl(network: Network, assetIdentifier: NFTAsset.Identifier): String?
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
@ -12,6 +12,7 @@ internal sealed class NFTCollectionsUM {
|
|||
) : NFTCollectionsUM()
|
||||
|
||||
data class Loading(
|
||||
val search: SearchBarUM,
|
||||
val onReceiveClick: () -> Unit,
|
||||
) : NFTCollectionsUM()
|
||||
|
||||
|
|
|
|||
|
|
@ -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<NFTCollectionsStateUM> {
|
||||
|
||||
override fun transform(prevState: NFTCollectionsStateUM): NFTCollectionsStateUM = prevState.copy(
|
||||
pullToRefreshConfig = prevState.pullToRefreshConfig.copy(
|
||||
isRefreshing = isRefreshing,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -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<NFTCollectionsStateUM> {
|
||||
|
||||
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<NFTCollection>.transform(
|
||||
state: NFTCollectionsStateUM,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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 = { },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue