Updated on 2026-08-14

This commit is contained in:
Tangem 2025-01-20 10:12:18 +03:00
commit 780686645b
17 changed files with 70 additions and 35 deletions

View file

@ -19,6 +19,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import timber.log.Timber import timber.log.Timber
@Suppress("LargeClass")
internal class DefaultLegacyWalletConnectRepository( internal class DefaultLegacyWalletConnectRepository(
private val application: Application, private val application: Application,
private val wcRequestDeserializer: WcJrpcRequestsDeserializer, private val wcRequestDeserializer: WcJrpcRequestsDeserializer,
@ -72,19 +73,23 @@ internal class DefaultLegacyWalletConnectRepository(
} }
} }
WalletKit.initialize(Wallet.Params.Init(core = CoreClient)) { error -> WalletKit.initialize(
Timber.e("Error while initializing Web3Wallet: $error") Wallet.Params.Init(core = CoreClient),
scope.launch { onSuccess = {
_events.emit( val walletDelegate = defineWalletDelegate()
WalletConnectEvents.SessionApprovalError( WalletKit.setWalletDelegate(walletDelegate)
WalletConnectError.ExternalApprovalError(error.throwable.message), },
), onError = { error ->
) Timber.e("Error while initializing Web3Wallet: $error")
} scope.launch {
} _events.emit(
WalletConnectEvents.SessionApprovalError(
val walletDelegate = defineWalletDelegate() WalletConnectError.ExternalApprovalError(error.throwable.message),
WalletKit.setWalletDelegate(walletDelegate) ),
)
}
},
)
} }
private fun defineWalletDelegate(): WalletKit.WalletDelegate { private fun defineWalletDelegate(): WalletKit.WalletDelegate {

View file

@ -2,6 +2,7 @@ package com.tangem.datasource.local.datastore
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
/** /**
* Runtime store * Runtime store
@ -16,6 +17,8 @@ interface RuntimeStateStore<T> {
/** Store [value] */ /** Store [value] */
suspend fun store(value: T) suspend fun store(value: T)
suspend fun update(function: (T) -> T)
companion object { companion object {
/** /**
@ -32,6 +35,10 @@ interface RuntimeStateStore<T> {
override suspend fun store(value: T) { override suspend fun store(value: T) {
flow.value = value flow.value = value
} }
override suspend fun update(function: (T) -> T) {
flow.update(function)
}
} }
} }
} }

View file

@ -1,6 +1,5 @@
package com.tangem.core.ui.components.transactions package com.tangem.core.ui.components.transactions
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -119,13 +118,12 @@ private fun PendingTxsBlock(pendingTxs: ImmutableList<TransactionState>, isBalan
} }
} }
@OptIn(ExperimentalFoundationApi::class)
private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) { private fun LazyListScope.nonContentItem(state: EmptyTransactionsBlockState, modifier: Modifier = Modifier) {
item(key = state::class.java, contentType = state::class.java) { item(key = state::class.java, contentType = state::class.java) {
EmptyTransactionBlock( EmptyTransactionBlock(
state = state, state = state,
modifier = modifier modifier = modifier
.animateItemPlacement() .animateItem(fadeInSpec = null, fadeOutSpec = null)
.padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12) .padding(horizontal = TangemTheme.dimens.spacing16, vertical = TangemTheme.dimens.spacing12)
.fillMaxWidth(), .fillMaxWidth(),
) )

View file

@ -20,13 +20,14 @@ import com.tangem.utils.coroutines.runCatching
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
internal class DefaultWalletsRepository( internal class DefaultWalletsRepository(
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val tangemTechApi: TangemTechApi, private val tangemTechApi: TangemTechApi,
private val userWalletsStore: UserWalletsStore, private val userWalletsStore: UserWalletsStore,
private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<Boolean>, private val seedPhraseNotificationVisibilityStore: RuntimeStateStore<Map<UserWalletId, Boolean>>,
private val dispatchers: CoroutineDispatcherProvider, private val dispatchers: CoroutineDispatcherProvider,
) : WalletsRepository { ) : WalletsRepository {
@ -59,7 +60,9 @@ internal class DefaultWalletsRepository(
override fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<Boolean> { override fun seedPhraseNotificationStatus(userWalletId: UserWalletId): Flow<Boolean> {
return channelFlow { return channelFlow {
launch { launch {
seedPhraseNotificationVisibilityStore.get().collectLatest(::send) seedPhraseNotificationVisibilityStore.get()
.map { it.getOrDefault(key = userWalletId, defaultValue = false) }
.collectLatest(::send)
} }
fetchSeedPhraseNotificationStatus(userWalletId) fetchSeedPhraseNotificationStatus(userWalletId)
@ -81,7 +84,7 @@ internal class DefaultWalletsRepository(
) )
} }
seedPhraseNotificationVisibilityStore.store(value = status) updateNotificationVisibility(id = userWalletId, value = status)
} }
override suspend fun notifiedSeedPhraseNotification(userWalletId: UserWalletId) { override suspend fun notifiedSeedPhraseNotification(userWalletId: UserWalletId) {
@ -101,7 +104,7 @@ internal class DefaultWalletsRepository(
).getOrThrow() ).getOrThrow()
} }
seedPhraseNotificationVisibilityStore.store(value = false) updateNotificationVisibility(id = userWalletId, value = false)
} }
override suspend fun declineSeedPhraseNotification(userWalletId: UserWalletId) { override suspend fun declineSeedPhraseNotification(userWalletId: UserWalletId) {
@ -112,7 +115,7 @@ internal class DefaultWalletsRepository(
).getOrThrow() ).getOrThrow()
} }
seedPhraseNotificationVisibilityStore.store(value = false) updateNotificationVisibility(id = userWalletId, value = false)
} }
override suspend fun markWallet2WasCreated(userWalletId: UserWalletId) { override suspend fun markWallet2WasCreated(userWalletId: UserWalletId) {
@ -122,4 +125,12 @@ internal class DefaultWalletsRepository(
) )
} }
} }
private suspend fun updateNotificationVisibility(id: UserWalletId, value: Boolean) {
return seedPhraseNotificationVisibilityStore.update {
it.toMutableMap().apply {
this[id] = value
}
}
}
} }

View file

@ -31,7 +31,7 @@ internal object WalletsDataModule {
appPreferencesStore = appPreferencesStore, appPreferencesStore = appPreferencesStore,
tangemTechApi = tangemTechApi, tangemTechApi = tangemTechApi,
userWalletsStore = userWalletsStore, userWalletsStore = userWalletsStore,
seedPhraseNotificationVisibilityStore = RuntimeStateStore(defaultValue = false), seedPhraseNotificationVisibilityStore = RuntimeStateStore(defaultValue = emptyMap()),
dispatchers = dispatchers, dispatchers = dispatchers,
) )
} }

View file

@ -1,6 +1,5 @@
package com.tangem.features.send.impl.presentation.ui.common package com.tangem.features.send.impl.presentation.ui.common
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
@ -10,7 +9,6 @@ import com.tangem.core.ui.components.notifications.Notification
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@OptIn(ExperimentalFoundationApi::class)
internal fun LazyListScope.notifications( internal fun LazyListScope.notifications(
notifications: ImmutableList<NotificationUM>, notifications: ImmutableList<NotificationUM>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@ -31,7 +29,7 @@ internal fun LazyListScope.notifications(
config = item.config, config = item.config,
modifier = modifier modifier = modifier
.padding(top = topPadding) .padding(top = topPadding)
.animateItemPlacement(), .animateItem(fadeInSpec = null, fadeOutSpec = null),
containerColor = when (item) { containerColor = when (item) {
is NotificationUM.Error.TokenExceedsBalance, is NotificationUM.Error.TokenExceedsBalance,
is NotificationUM.Warning.NetworkFeeUnreachable, is NotificationUM.Warning.NetworkFeeUnreachable,

View file

@ -85,6 +85,12 @@ internal enum class Wallet2CobrandImage(
batchIds = setOf("AF32"), batchIds = setOf("AF32"),
), ),
GetsMine(
cards2ResId = R.drawable.ill_gets_mine_card2_120_106,
cards3ResId = R.drawable.ill_gets_mine_card3_120_106,
batchIds = setOf("BB000008"),
),
Grim( Grim(
cards2ResId = R.drawable.ill_grim_card2_120_106, cards2ResId = R.drawable.ill_grim_card2_120_106,
cards3ResId = R.drawable.ill_grim_card3_120_106, cards3ResId = R.drawable.ill_grim_card3_120_106,
@ -194,6 +200,12 @@ internal enum class Wallet2CobrandImage(
batchIds = setOf("AF07"), batchIds = setOf("AF07"),
), ),
USA(
cards2ResId = R.drawable.ill_usa_card2_120_106,
cards3ResId = R.drawable.ill_usa_card3_120_106,
batchIds = setOf("AF91"),
),
VeChain( VeChain(
cards2ResId = R.drawable.ill_vechain_card2_120_106, cards2ResId = R.drawable.ill_vechain_card2_120_106,
cards3ResId = R.drawable.ill_vechain_card3_120_106, cards3ResId = R.drawable.ill_vechain_card3_120_106,
@ -218,4 +230,10 @@ internal enum class Wallet2CobrandImage(
cards3ResId = R.drawable.ill_white_card3_120_106, cards3ResId = R.drawable.ill_white_card3_120_106,
batchIds = setOf("AF15"), batchIds = setOf("AF15"),
), ),
Winter(
cards2ResId = R.drawable.ill_winter_card2_120_106,
cards3ResId = R.drawable.ill_winter_card3_120_106,
batchIds = setOf("AF85", "AF86", "AF87", "AF990013", "AF990012", "AF990011"),
),
} }

View file

@ -35,7 +35,7 @@ internal fun LazyListScope.lazyActions(
item(key = ACTIONS_CONTENT_TYPE + selectedWalletIndex, contentType = ACTIONS_CONTENT_TYPE) { item(key = ACTIONS_CONTENT_TYPE + selectedWalletIndex, contentType = ACTIONS_CONTENT_TYPE) {
HorizontalActionChips( HorizontalActionChips(
buttons = actions.map(WalletManageButton::config).toImmutableList(), buttons = actions.map(WalletManageButton::config).toImmutableList(),
modifier = modifier.animateItem(), modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16), contentPadding = PaddingValues(horizontal = TangemTheme.dimens.spacing16),
) )
} }
@ -62,7 +62,7 @@ internal fun LazyListScope.actions(
modifier = modifier modifier = modifier
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
.fillMaxWidth() .fillMaxWidth()
.animateItem(), .animateItem(fadeInSpec = null, fadeOutSpec = null),
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8), horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing8),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {

View file

@ -30,25 +30,25 @@ internal fun LazyListScope.notifications(configs: ImmutableList<WalletNotificati
is WalletNotification.SwapPromo -> { is WalletNotification.SwapPromo -> {
OkxPromoNotification( OkxPromoNotification(
config = it.config, config = it.config,
modifier = modifier.animateItem(), modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
) )
} }
is WalletNotification.RingPromo -> { is WalletNotification.RingPromo -> {
RingPromoNotification( RingPromoNotification(
config = it.config, config = it.config,
modifier = modifier.animateItem(), modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
) )
} }
is WalletNotification.NoteMigration -> { is WalletNotification.NoteMigration -> {
NoteMigrationNotification( NoteMigrationNotification(
config = it.config, config = it.config,
modifier = modifier.animateItem(), modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
) )
} }
else -> { else -> {
Notification( Notification(
config = it.config, config = it.config,
modifier = modifier.animateItem(), modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
iconTint = when (it) { iconTint = when (it) {
is WalletNotification.Critical -> TangemTheme.colors.icon.warning is WalletNotification.Critical -> TangemTheme.colors.icon.warning
is WalletNotification.Informational -> TangemTheme.colors.icon.accent is WalletNotification.Informational -> TangemTheme.colors.icon.accent

View file

@ -78,7 +78,7 @@ private fun LazyListScope.nonContentItem(modifier: Modifier = Modifier) {
) { ) {
Column( Column(
modifier = modifier modifier = modifier
.animateItem() .animateItem(fadeInSpec = null, fadeOutSpec = null)
.padding(top = TangemTheme.dimens.spacing96), .padding(top = TangemTheme.dimens.spacing96),
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing16), verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing16),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,

View file

@ -1,6 +1,5 @@
package com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency package com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.marketprice.MarketPriceBlock import com.tangem.core.ui.components.marketprice.MarketPriceBlock
@ -14,12 +13,11 @@ import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
* *
[REDACTED_AUTHOR] [REDACTED_AUTHOR]
*/ */
@OptIn(ExperimentalFoundationApi::class)
internal fun LazyListScope.marketPriceBlock(state: MarketPriceBlockState, modifier: Modifier = Modifier) { internal fun LazyListScope.marketPriceBlock(state: MarketPriceBlockState, modifier: Modifier = Modifier) {
item( item(
key = MarketPriceBlockState::class.java, key = MarketPriceBlockState::class.java,
contentType = MarketPriceBlockState::class.java, contentType = MarketPriceBlockState::class.java,
) { ) {
MarketPriceBlock(state = state, modifier = modifier.animateItemPlacement()) MarketPriceBlock(state = state, modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null))
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB