Updated on 2026-08-14

This commit is contained in:
Tangem 2023-11-22 13:00:39 +03:00
commit 82f95f3e51
32 changed files with 160 additions and 56 deletions

View file

@ -3,6 +3,7 @@ package com.tangem.tap.common.redux.legacy
import com.tangem.domain.redux.LegacyAction
import com.tangem.tap.common.feedback.RateCanBeBetterEmail
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.store
import org.rekotlin.Middleware
@ -14,6 +15,11 @@ internal object LegacyMiddleware {
is LegacyAction.SendEmailRateCanBeBetter -> {
store.state.globalState.feedbackManager?.sendEmail(RateCanBeBetterEmail())
}
is LegacyAction.StartOnboardingProcess -> {
store.dispatch(
GlobalAction.Onboarding.Start(action.scanResponse, canSkipBackup = action.canSkipBackup),
)
}
}
next(action)
}

View file

@ -602,11 +602,14 @@ internal class AddCustomTokenViewModel @Inject constructor(
val networkSelectorValue = uiState.form.networkSelectorField.selectedItem.blockchain
val networkId = Blockchain.fromNetworkId(networkSelectorValue.toNetworkId())?.id
// todo after move foundToken to CryptoCurrency model, use only id
val savedTokenId = if (token.isCustom) null else token.id.rawCurrencyId
val sameId = if (!token.isCustom) {
// todo after move foundToken to CryptoCurrency model, use only id
foundToken?.id == token.id.rawCurrencyId
} else {
true
}
val sameId = foundToken?.id == savedTokenId
val sameAddress = contractAddress == token.contractAddress
val sameAddress = contractAddress.equals(token.contractAddress, ignoreCase = true)
val sameBlockchain = networkId == token.network.id.value
val isSameDerivationPath = getDerivationPath()?.rawPath == token.network.derivationPath.value

View file

@ -143,9 +143,9 @@ internal object TangemSocialAccounts {
SocialNetworkLink(SocialNetwork.Telegram, "https://t.me/tangem_chat"),
SocialNetworkLink(SocialNetwork.Discord, "https://discord.gg/tangem"),
SocialNetworkLink(SocialNetwork.Reddit, "https://www.reddit.com/r/Tangem/"),
SocialNetworkLink(SocialNetwork.Instagram, "https://instagram.com/tangemcards"),
SocialNetworkLink(SocialNetwork.Instagram, "https://www.instagram.com/tangemwallet"),
SocialNetworkLink(SocialNetwork.GitHub, "https://github.com/tangem"),
SocialNetworkLink(SocialNetwork.Facebook, "https://facebook.com/TangemCards/"),
SocialNetworkLink(SocialNetwork.Facebook, "https://www.facebook.com/tangemwallet"),
SocialNetworkLink(SocialNetwork.LinkedIn, "https://www.linkedin.com/company/tangem"),
SocialNetworkLink(SocialNetwork.YouTube, "https://youtube.com/@tangem3890"),
)
@ -154,9 +154,9 @@ internal object TangemSocialAccounts {
SocialNetworkLink(SocialNetwork.Telegram, "https://t.me/tangem_chat_ru"),
SocialNetworkLink(SocialNetwork.Discord, "https://discord.gg/tangem"),
SocialNetworkLink(SocialNetwork.Reddit, "https://www.reddit.com/r/Tangem/"),
SocialNetworkLink(SocialNetwork.Instagram, "https://instagram.com/tangemcards"),
SocialNetworkLink(SocialNetwork.Instagram, "https://www.instagram.com/tangemwallet"),
SocialNetworkLink(SocialNetwork.GitHub, "https://github.com/tangem"),
SocialNetworkLink(SocialNetwork.Facebook, "https://facebook.com/TangemCards/"),
SocialNetworkLink(SocialNetwork.Facebook, "https://www.facebook.com/tangemwallet"),
SocialNetworkLink(SocialNetwork.LinkedIn, "https://www.linkedin.com/company/tangem"),
SocialNetworkLink(SocialNetwork.YouTube, "https://youtube.com/@tangem3890"),
)

View file

@ -73,9 +73,9 @@ private fun OrderCardButton(onClick: () -> Unit, modifier: Modifier = Modifier)
}
private val LightBgScanCardButtonColors: ButtonColors = TangemButtonColors(
backgroundColor = TangemColorPalette.Light2,
backgroundColor = TangemColorPalette.Light4,
contentColor = TangemColorPalette.Dark6,
disabledBackgroundColor = TangemColorPalette.Light2,
disabledBackgroundColor = TangemColorPalette.Dark5,
disabledContentColor = TangemColorPalette.Dark6,
)

View file

@ -50,7 +50,8 @@ internal class MainViewModel @Inject constructor(
it.isBalanceHidingNotificationEnabled && it.isBalanceHidden
}
.onEach {
if (state.value.modalNotification?.isShow != true) {
if (state.value.modalNotification?.isShow != true && !it.isUpdateFromToast) {
listenToFlipsUseCase.changeUpdateEnabled(false)
stateHolder.updateWithHiddenBalancesNotification()
reduxNavController.navigate(NavigationAction.NavigateTo(AppScreen.ModalNotification))
}
@ -79,7 +80,9 @@ internal class MainViewModel @Inject constructor(
return@onEach
}
displayBalancesHiddenStatusToast(settings)
if (!settings.isUpdateFromToast) {
displayBalancesHiddenStatusToast(settings)
}
previousSettings = settings
}
@ -96,7 +99,10 @@ internal class MainViewModel @Inject constructor(
override fun onHiddenBalanceToastAction() {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
copy(isBalanceHidden = false)
copy(
isBalanceHidden = false,
isUpdateFromToast = true,
)
}
}
}
@ -104,7 +110,10 @@ internal class MainViewModel @Inject constructor(
override fun onShownBalanceToastAction() {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
copy(isBalanceHidden = true)
copy(
isBalanceHidden = true,
isUpdateFromToast = true,
)
}
}
}
@ -112,6 +121,7 @@ internal class MainViewModel @Inject constructor(
override fun onHiddenBalanceNotificationAction(isPermanent: Boolean) {
onDismissBottomSheet()
stateHolder.updateWithHiddenBalancesToast(true)
if (isPermanent) {
viewModelScope.launch {
updateBalanceHidingSettingsUseCase.invoke {
@ -122,6 +132,8 @@ internal class MainViewModel @Inject constructor(
}
override fun onDismissBottomSheet() {
listenToFlipsUseCase.changeUpdateEnabled(true)
stateHolder.updateWithoutModalNotification()
stateHolder.updateWithHiddenBalancesToast(true)
}
}

View file

@ -2,12 +2,14 @@ package com.tangem.tap.features.main.ui
import android.content.DialogInterface
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.background
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.main.MainViewModel
@ -37,7 +39,11 @@ internal class ModalNotificationBottomSheetFragment : ComposeBottomSheetFragment
when (val content = notification.content) {
is ModalNotification -> ModalNotificationContent(
modifier = modifier,
modifier = modifier
.background(
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
notification = content,
)
else -> Unit

View file

@ -88,9 +88,9 @@ private fun ModalNotificationContentPreview_Light(
) {
TangemTheme(isDark = false) {
ModalNotificationContent(
param,
notification = param,
modifier = Modifier.background(
color = TangemTheme.colors.background.plain,
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
)
@ -104,9 +104,9 @@ private fun ModalNotificationContentPreview_Dark(
) {
TangemTheme(isDark = true) {
ModalNotificationContent(
param,
notification = param,
modifier = Modifier.background(
color = TangemTheme.colors.background.plain,
color = TangemTheme.colors.background.primary,
shape = TangemTheme.shapes.bottomSheet,
),
)

View file

@ -2,7 +2,6 @@ package com.tangem.tap.features.send.ui
import androidx.lifecycle.*
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
import com.tangem.domain.tokens.FetchPendingTransactionsUseCase
import com.tangem.domain.tokens.UpdateDelayedNetworkStatusUseCase
import com.tangem.domain.tokens.model.CryptoCurrency
@ -16,11 +15,10 @@ import com.tangem.tap.proxy.AppStateHolder
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
@ -30,7 +28,6 @@ internal class SendViewModel @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
private val appStateHolder: AppStateHolder,
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
private val listenToFlipsUseCase: ListenToFlipsUseCase,
private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase,
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
private val fetchPendingTransactionsUseCase: FetchPendingTransactionsUseCase,
@ -44,17 +41,10 @@ internal class SendViewModel @Inject constructor(
getBalanceHidingSettingsUseCase()
.flowWithLifecycle(owner.lifecycle)
.onEach {
withContext(dispatchers.main) {
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(it.isBalanceHidden))
}
appStateHolder.mainStore?.dispatch(AmountAction.HideBalance(it.isBalanceHidden))
}
.flowOn(dispatchers.main)
.launchIn(viewModelScope)
viewModelScope.launch {
listenToFlipsUseCase()
.flowWithLifecycle(owner.lifecycle)
.collect()
}
}
fun updateCurrencyDelayed() {

View file

@ -10,7 +10,7 @@
<color name="button_disabled">#303030</color>
<!--<color name="button_positive">#1ACE80</color>-->
<!--<color name="button_positive_disabled">#06311F</color>-->
<color name="button_primary">#F5F5F5</color>
<color name="button_primary">#FFC9C9C9</color>
<color name="button_secondary">#303030</color>
<color name="control_checked">#1ACE80</color>

View file

@ -86,6 +86,7 @@
<string name="common_error">Ошибка</string>
<string name="common_exchange">Обменять</string>
<string name="common_explore_transaction_history">Посмотреть историю транзакций</string>
<string name="common_explore">Обозреватель</string>
<string name="common_explorer">Обозреватель</string>
<string name="common_fee_selector_footer">Сетевые комиссии за транзакции используются для поддержки безопасности сети, поощрения валидаторов, выделения ресурсов и определения приоритета транзакции.</string>
<string name="common_fee_selector_option_custom">Свое</string>

View file

@ -2,9 +2,7 @@ package com.tangem.core.ui.components.bottomsheets.tokenreceive
import android.widget.Toast
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
@ -43,6 +41,7 @@ private fun TokenReceiveBottomSheetContent(content: TokenReceiveBottomSheetConfi
var selectedAddress by remember { mutableStateOf(content.addresses.first()) }
Column(
modifier = Modifier
.verticalScroll(state = rememberScrollState())
.padding(
start = TangemTheme.dimens.spacing24,
top = TangemTheme.dimens.spacing24,

View file

@ -81,7 +81,7 @@ private fun LazyListScope.contentItems(
count = txHistoryItems.itemCount,
key = txHistoryItems.itemKey { item ->
when (item) {
is TxHistoryState.TxHistoryItemState.GroupTitle -> item.title
is TxHistoryState.TxHistoryItemState.GroupTitle -> item.itemKey
is TxHistoryState.TxHistoryItemState.Title -> item.onExploreClick.hashCode()
is TxHistoryState.TxHistoryItemState.Transaction -> item.state.txHash
}

View file

@ -10,6 +10,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.transactions.state.TxHistoryState.TxHistoryItemState
import com.tangem.core.ui.res.TangemTheme
import java.util.UUID
/**
* Transactions block group title
@ -38,7 +39,9 @@ internal fun TxHistoryGroupTitle(config: TxHistoryItemState.GroupTitle, modifier
@Composable
private fun Preview_TransactionsBlockGroupTitle_Light() {
TangemTheme(isDark = false) {
TxHistoryGroupTitle(config = TxHistoryItemState.GroupTitle(title = "Today"))
TxHistoryGroupTitle(
config = TxHistoryItemState.GroupTitle(title = "Today", itemKey = UUID.randomUUID().toString()),
)
}
}
@ -46,6 +49,8 @@ private fun Preview_TransactionsBlockGroupTitle_Light() {
@Composable
private fun Preview_TransactionsBlockGroupTitle_Dark() {
TangemTheme(isDark = true) {
TxHistoryGroupTitle(config = TxHistoryItemState.GroupTitle(title = "Today"))
TxHistoryGroupTitle(
config = TxHistoryItemState.GroupTitle(title = "Today", itemKey = UUID.randomUUID().toString()),
)
}
}

View file

@ -49,8 +49,12 @@ sealed interface TxHistoryState {
* Group title item
*
* @property title title
* @property itemKey key to use in compose
*/
data class GroupTitle(val title: String) : TxHistoryItemState
data class GroupTitle(
val title: String,
val itemKey: String,
) : TxHistoryItemState
/**
* Transaction item

View file

@ -45,6 +45,7 @@ fun getActiveIconRes(blockchainId: String): Int {
"aleph-zero", "aleph-zero/test" -> R.drawable.img_azero_22
"octaspace", "octaspace/test" -> R.drawable.img_octaspace_22
"chia", "chia/test" -> R.drawable.img_chia_22
"NEAR", "NEAR/test" -> R.drawable.img_near_22
"decimal", "decimal/testnet" -> R.drawable.img_decimal_22
else -> R.drawable.ic_alert_24
}
@ -135,6 +136,7 @@ fun getGreyedOutIconRes(blockchainId: String): Int {
"aleph-zero", "aleph-zero/test" -> R.drawable.ic_azero_22
"octaspace", "octaspace/test" -> R.drawable.ic_octaspace_22
"chia", "chia/test" -> R.drawable.ic_chia_22
"NEAR", "NEAR/test" -> R.drawable.ic_near_22
"decimal", "decimal/test" -> R.drawable.ic_decimal_22
else -> R.drawable.ic_alert_24
}

View file

@ -156,7 +156,7 @@ private fun darkThemeColors(): TangemColors {
attention = TangemColorPalette.Mustard,
),
button = TangemColors.Button(
primary = TangemColorPalette.Light1,
primary = TangemColorPalette.Light4,
secondary = TangemColorPalette.Dark5,
disabled = TangemColorPalette.Dark5,
positiveDisabled = TangemColorPalette.DarkGreen,

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:pathData="M15.721,5C15.277,5 14.864,5.23 14.632,5.609L12.123,9.333C12.042,9.456 12.075,9.622 12.197,9.703C12.297,9.77 12.429,9.761 12.519,9.683L14.988,7.542C15.029,7.505 15.092,7.509 15.129,7.55C15.146,7.569 15.155,7.593 15.155,7.618V14.323C15.155,14.378 15.11,14.423 15.055,14.423C15.025,14.423 14.997,14.41 14.978,14.387L7.515,5.453C7.272,5.166 6.915,5 6.539,5H6.278C5.572,5 5,5.572 5,6.278V15.722C5,16.428 5.572,17 6.278,17C6.723,17 7.135,16.77 7.368,16.391L9.876,12.667C9.958,12.544 9.925,12.378 9.802,12.297C9.703,12.23 9.571,12.239 9.481,12.317L7.012,14.458C6.971,14.495 6.907,14.491 6.87,14.45C6.854,14.432 6.845,14.407 6.845,14.382V7.676C6.845,7.62 6.89,7.576 6.945,7.576C6.975,7.576 7.003,7.589 7.022,7.612L14.484,16.547C14.727,16.834 15.084,17 15.46,17H15.721C16.427,17 16.999,16.428 17,15.722V6.278C17,5.572 16.428,5 15.722,5H15.721Z"
android:fillColor="#000000" />
</vector>

View file

@ -13,6 +13,8 @@ internal class DefaultBalanceHidingRepository(
private val appPreferencesStore: AppPreferencesStore,
) : BalanceHidingRepository {
override var isUpdateEnabled: Boolean = true
override fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings> {
return appPreferencesStore.getObject(
key = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY,

View file

@ -17,6 +17,12 @@ class DefaultMarketCryptoCurrencyRepository(
return userMarketCoinsStore.getSyncOrNull(userWalletId)?.coins
?.firstOrNull { it.id == cryptoCurrencyId.rawCurrencyId }
?.networks
?.firstOrNull { it.networkId == apiNetworkId }?.exchangeable ?: false
?.firstOrNull {
if (it.contractAddress != null) {
it.networkId == apiNetworkId && it.contractAddress == cryptoCurrencyId.contractAddress
} else {
it.networkId == apiNetworkId
}
}?.exchangeable ?: false
}
}

View file

@ -4,4 +4,5 @@ data class BalanceHidingSettings(
val isHidingEnabledInSettings: Boolean,
val isBalanceHidden: Boolean,
val isBalanceHidingNotificationEnabled: Boolean,
val isUpdateFromToast: Boolean = false,
)

View file

@ -24,12 +24,13 @@ class ListenToFlipsUseCase(
},
)
if (balanceHidingSettings.isHidingEnabledInSettings) {
if (balanceHidingSettings.isHidingEnabledInSettings && balanceHidingRepository.isUpdateEnabled) {
catch(
block = {
balanceHidingRepository.storeBalanceHidingSettings(
balanceHidingSettings.copy(
isBalanceHidden = !balanceHidingSettings.isBalanceHidden,
isUpdateFromToast = false,
),
)
},
@ -40,4 +41,8 @@ class ListenToFlipsUseCase(
}
}
}
fun changeUpdateEnabled(isUpdateEnabled: Boolean) {
balanceHidingRepository.isUpdateEnabled = isUpdateEnabled
}
}

View file

@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow
interface BalanceHidingRepository {
var isUpdateEnabled: Boolean
fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings>
suspend fun storeBalanceHidingSettings(isBalanceHidden: BalanceHidingSettings)

View file

@ -224,4 +224,6 @@ private const val NODL_AMOUNT_TO_CREATE_ACCOUNT = 1.5
private val excludedBlockchains = listOf(
Blockchain.Unknown,
Blockchain.Ducatus,
Blockchain.Decimal,
Blockchain.DecimalTestnet,
)

View file

@ -1,8 +1,16 @@
package com.tangem.domain.redux
import com.tangem.domain.models.scan.ScanResponse
import org.rekotlin.Action
sealed interface LegacyAction : Action {
object SendEmailRateCanBeBetter : LegacyAction
/**
* Initiate an onboarding process.
* For resuming unfinished backup of standard Wallet see
* BackupAction.CheckForUnfinishedBackup, GlobalAction.Onboarding.StartForUnfinishedBackup
*/
data class StartOnboardingProcess(val scanResponse: ScanResponse, val canSkipBackup: Boolean = true) : LegacyAction
}

View file

@ -94,6 +94,8 @@ sealed class CryptoCurrency : Parcelable {
/** Represents a raw cryptocurrency ID. If it is a custom token, the value will be `null`. */
val rawCurrencyId: String? get() = (suffix as? Suffix.RawID)?.rawId
val contractAddress: String? get() = (suffix as? Suffix.RawID)?.contractAddress
/** Represents a raw cryptocurrency's network ID. */
val rawNetworkId: String
get() = when (body) {

View file

@ -23,6 +23,7 @@ import timber.log.Timber
import java.math.BigDecimal
import java.math.RoundingMode
import javax.inject.Inject
import com.tangem.lib.crypto.models.Currency as LibCurrency
@Suppress("LargeClass", "LongParameterList")
internal class SwapInteractorImpl @Inject constructor(
@ -70,7 +71,14 @@ internal class SwapInteractorImpl @Inject constructor(
isExcludeCustom = true,
)
.map { token ->
allLoadedTokens.firstOrNull { it.symbol == token.symbol }?.let {
val contractAddress = (token as? LibCurrency.NonNativeToken)?.contractAddress
allLoadedTokens.firstOrNull {
if (it is Currency.NonNativeToken) {
it.symbol == token.symbol && it.contractAddress == contractAddress
} else {
it.symbol == token.symbol
}
}?.let {
loadedOnWalletsMap.add(it.symbol)
it
} ?: swapCurrencyConverter.convertBack(token)

View file

@ -14,6 +14,7 @@ import com.tangem.utils.converter.Converter
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import java.util.UUID
internal class TokenDetailsTxHistoryItemFlowConverter(
private val currentStateProvider: Provider<TokenDetailsState>,
@ -71,7 +72,10 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
// If [afterDate] is the first transaction in the flow, add the group title
val afterDate = after.getTimestamp()?.toDateFormat() ?: return@insertSeparators null
if (before is TxHistoryItemState.Title) {
return@insertSeparators TxHistoryItemState.GroupTitle(afterDate)
return@insertSeparators TxHistoryItemState.GroupTitle(
title = afterDate,
itemKey = UUID.randomUUID().toString(),
)
}
/*
@ -80,7 +84,10 @@ internal class TokenDetailsTxHistoryItemFlowConverter(
*/
val beforeDate = before.getTimestamp()?.toDateFormat() ?: return@insertSeparators null
return@insertSeparators if (beforeDate != afterDate) {
TxHistoryItemState.GroupTitle(afterDate)
TxHistoryItemState.GroupTitle(
title = afterDate,
itemKey = UUID.randomUUID().toString(),
)
} else {
null
}

View file

@ -418,7 +418,10 @@ internal object WalletPreviewData {
contentItems = MutableStateFlow(
PagingData.from(
listOf(
TxHistoryState.TxHistoryItemState.GroupTitle("Today"),
TxHistoryState.TxHistoryItemState.GroupTitle(
title = "Today",
itemKey = UUID.randomUUID().toString(),
),
TxHistoryState.TxHistoryItemState.Transaction(
TransactionState.Content(
txHash = UUID.randomUUID().toString(),
@ -432,7 +435,10 @@ internal object WalletPreviewData {
onClick = {},
),
),
TxHistoryState.TxHistoryItemState.GroupTitle("Yesterday"),
TxHistoryState.TxHistoryItemState.GroupTitle(
title = "Yesterday",
itemKey = UUID.randomUUID().toString(),
),
TxHistoryState.TxHistoryItemState.Transaction(
TransactionState.Content(
txHash = UUID.randomUUID().toString(),

View file

@ -45,13 +45,18 @@ internal fun TokenItem(
.tokenClickable(state = state)
.background(color = TangemTheme.colors.background.primary),
) {
TokenIcon(state = state.iconState, modifier = Modifier.layoutId(layoutId = LayoutId.ICON))
TokenIcon(
state = state.iconState,
modifier = Modifier
.layoutId(layoutId = LayoutId.ICON)
.padding(end = TangemTheme.dimens.spacing8),
)
TokenTitle(
state = state.titleState,
modifier = Modifier
.layoutId(layoutId = LayoutId.TITLE)
.padding(horizontal = TangemTheme.dimens.spacing8)
.padding(end = TangemTheme.dimens.spacing8)
.padding(bottom = betweenRowsMargin),
)
@ -67,7 +72,7 @@ internal fun TokenItem(
state = state.cryptoPriceState,
modifier = Modifier
.layoutId(layoutId = LayoutId.CRYPTO_PRICE)
.padding(horizontal = TangemTheme.dimens.spacing8),
.padding(end = TangemTheme.dimens.spacing8),
)
TokenCryptoAmount(
@ -233,7 +238,10 @@ private fun CustomContainer(state: TokenItemState, modifier: Modifier = Modifier
)
cryptoAmount?.placeRelative(
x = layoutWidth - cryptoAmount.width - layoutPadding,
x = when (state) {
is TokenItemState.Draggable -> layoutPadding + icon.width
else -> layoutWidth - cryptoAmount.width - layoutPadding
},
y = layoutHeight - cryptoAmount.height - layoutPadding,
)

View file

@ -20,6 +20,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import java.util.UUID
/**
* Convert from [Flow] of [TxHistoryItem] to [TxHistoryState]
@ -83,7 +84,10 @@ internal class WalletTxHistoryItemFlowConverter(
// If [afterDate] is the first transaction in the flow, add the group title
val afterDate = after.getTimestamp()?.toDateFormat() ?: return@insertSeparators null
if (before is TxHistoryItemState.Title) {
return@insertSeparators TxHistoryItemState.GroupTitle(afterDate)
return@insertSeparators TxHistoryItemState.GroupTitle(
title = afterDate,
itemKey = UUID.randomUUID().toString(),
)
}
/*
@ -92,7 +96,7 @@ internal class WalletTxHistoryItemFlowConverter(
*/
val beforeDate = before.getTimestamp()?.toDateFormat() ?: return@insertSeparators null
return@insertSeparators if (beforeDate != afterDate) {
TxHistoryItemState.GroupTitle(afterDate)
TxHistoryItemState.GroupTitle(title = afterDate, itemKey = UUID.randomUUID().toString())
} else {
null
}

View file

@ -431,6 +431,12 @@ internal class WalletViewModel @Inject constructor(
override fun onBackupCardClick() {
analyticsEventsHandler.send(WalletScreenAnalyticsEvent.MainScreen.NoticeBackupYourWalletTapped)
reduxStateHolder.dispatch(
LegacyAction.StartOnboardingProcess(
scanResponse = getSelectedWallet().scanResponse,
canSkipBackup = false,
),
)
router.openOnboardingScreen()
}

View file

@ -88,9 +88,9 @@ spr-client = "3.6.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-393"
tangemBlockchainSdk = "develop-394"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-310"
tangemCardSdk = "develop-312"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds
# endregion Tangem