Updated on 2026-08-14
This commit is contained in:
commit
780686645b
17 changed files with 70 additions and 35 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
@ -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,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 |
Loading…
Add table
Add a link
Reference in a new issue