diff --git a/app/src/main/assets/tangem-app-config b/app/src/main/assets/tangem-app-config index f5a90466d2..2a612cd92b 160000 --- a/app/src/main/assets/tangem-app-config +++ b/app/src/main/assets/tangem-app-config @@ -1 +1 @@ -Subproject commit f5a90466d2245ca5cfde59b49dc7fa82a6b7cbc2 +Subproject commit 2a612cd92b1c78b99c917d0fe66342831f801e5e diff --git a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt index 495a45f59b..81d40b5307 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/legacy/LegacyMiddleware.kt @@ -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) } diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt index 0a38a59439..b1f939c0f6 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt @@ -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 diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt index 6675322128..5a1c6150cf 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt @@ -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"), ) diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/views/HomeButtons.kt b/app/src/main/java/com/tangem/tap/features/home/compose/views/HomeButtons.kt index 1bd1a192c6..aebf48b161 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/views/HomeButtons.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/views/HomeButtons.kt @@ -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, ) diff --git a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt index e919fa41ec..5725564ef4 100644 --- a/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/main/MainViewModel.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/main/ui/ModalNotificationBottomSheetFragment.kt b/app/src/main/java/com/tangem/tap/features/main/ui/ModalNotificationBottomSheetFragment.kt index 2a40e92ef8..ec7cb8d416 100644 --- a/app/src/main/java/com/tangem/tap/features/main/ui/ModalNotificationBottomSheetFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/main/ui/ModalNotificationBottomSheetFragment.kt @@ -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 diff --git a/app/src/main/java/com/tangem/tap/features/main/ui/components/ModalNotificationScreen.kt b/app/src/main/java/com/tangem/tap/features/main/ui/components/ModalNotificationScreen.kt index 3ebb87e8dd..587b734dc0 100644 --- a/app/src/main/java/com/tangem/tap/features/main/ui/components/ModalNotificationScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/main/ui/components/ModalNotificationScreen.kt @@ -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, ), ) diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/SendViewModel.kt b/app/src/main/java/com/tangem/tap/features/send/ui/SendViewModel.kt index fe7c000ae6..de5e810b88 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/SendViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/SendViewModel.kt @@ -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() { diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 29535c674f..7b2c91dd38 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -10,7 +10,7 @@ #303030 - #F5F5F5 + #FFC9C9C9 #303030 #1ACE80 diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt index bded21d266..2c4b2b364f 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt @@ -90,7 +90,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { infuraProjectId = configValues.infuraProjectId, tronGridApiKey = configValues.tronGridApiKey, nowNodeCredentials = NowNodeCredentials(configValues.nowNodesApiKey), - getBlockCredentials = GetBlockCredentials(configValues.getBlockApiKey), + getBlockCredentials = createGetBlockCredentials(configValues), kaspaSecondaryApiUrl = configValues.kaspaSecondaryApiUrl, tonCenterCredentials = TonCenterCredentials( mainnetApiKey = configValues.tonCenterKeys.mainnet, @@ -109,4 +109,45 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { tangemExpressApiKey = configValues.tangemExpressApiKey, ) } + + private fun createGetBlockCredentials(configValues: ConfigValueModel): GetBlockCredentials? { + return configValues.getBlockAccessTokens?.let { accessTokens -> + GetBlockCredentials( + xrp = GetBlockAccessToken(jsonRpc = accessTokens.xrp?.jsonRPC), + cardano = GetBlockAccessToken(rosetta = accessTokens.cardano?.rosetta), + avalanche = GetBlockAccessToken(jsonRpc = accessTokens.avalanche?.jsonRPC), + eth = GetBlockAccessToken(jsonRpc = accessTokens.eth?.jsonRPC), + etc = GetBlockAccessToken(jsonRpc = accessTokens.etc?.jsonRPC), + fantom = GetBlockAccessToken(jsonRpc = accessTokens.fantom?.jsonRPC), + rsk = GetBlockAccessToken(jsonRpc = accessTokens.rsk?.jsonRPC), + bsc = GetBlockAccessToken(jsonRpc = accessTokens.bsc?.jsonRPC), + polygon = GetBlockAccessToken(jsonRpc = accessTokens.polygon?.jsonRPC), + gnosis = GetBlockAccessToken(jsonRpc = accessTokens.gnosis?.jsonRPC), + cronos = GetBlockAccessToken(jsonRpc = accessTokens.cronos?.jsonRPC), + solana = GetBlockAccessToken(jsonRpc = accessTokens.solana?.jsonRPC), + stellar = GetBlockAccessToken(rest = accessTokens.stellar?.rest), + ton = GetBlockAccessToken(jsonRpc = accessTokens.ton?.jsonRPC), + tron = GetBlockAccessToken(rest = accessTokens.tron?.rest), + cosmos = GetBlockAccessToken(rest = accessTokens.cosmos?.rest), + near = GetBlockAccessToken(jsonRpc = accessTokens.near?.jsonRPC), + luna = GetBlockAccessToken(rest = accessTokens.luna?.rest), + dogecoin = GetBlockAccessToken( + jsonRpc = accessTokens.dogecoin?.jsonRPC, + blockBookRest = accessTokens.dogecoin?.blockBookRest, + ), + litecoin = GetBlockAccessToken( + jsonRpc = accessTokens.litecoin?.jsonRPC, + blockBookRest = accessTokens.litecoin?.blockBookRest, + ), + dash = GetBlockAccessToken( + jsonRpc = accessTokens.dash?.jsonRPC, + blockBookRest = accessTokens.dash?.blockBookRest, + ), + bitcoin = GetBlockAccessToken( + jsonRpc = accessTokens.bitcoin?.jsonRPC, + blockBookRest = accessTokens.bitcoin?.blockBookRest, + ), + ) + } + } } \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt index 47210def4b..a7b0d44453 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt @@ -1,6 +1,7 @@ package com.tangem.datasource.config.models import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass /** [REDACTED_AUTHOR] @@ -25,7 +26,7 @@ class ConfigValueModel( val bscQuiknodeSubdomain: String, val bscQuiknodeApiKey: String, val nowNodesApiKey: String, - val getBlockApiKey: String, + @Json(name = "getBlockAccessTokens") val getBlockAccessTokens: GetBlockAccessTokens?, @Json(name = "tonCenterApiKey") val tonCenterKeys: TonCenterKeys, val blockcypherTokens: Set?, val infuraProjectId: String?, @@ -43,6 +44,40 @@ class ConfigValueModel( val tangemExpressApiKey: String, ) +@JsonClass(generateAdapter = true) +data class GetBlockAccessTokens( + @Json(name = "xrp") val xrp: GetBlockToken?, + @Json(name = "cardano") val cardano: GetBlockToken?, + @Json(name = "avalanche") val avalanche: GetBlockToken?, + @Json(name = "ethereum") val eth: GetBlockToken?, + @Json(name = "ethereumClassic") val etc: GetBlockToken?, + @Json(name = "fantom") val fantom: GetBlockToken?, + @Json(name = "rsk") val rsk: GetBlockToken?, + @Json(name = "bsc") val bsc: GetBlockToken?, + @Json(name = "polygon") val polygon: GetBlockToken?, + @Json(name = "xdai") val gnosis: GetBlockToken?, + @Json(name = "cronos") val cronos: GetBlockToken?, + @Json(name = "solana") val solana: GetBlockToken?, + @Json(name = "stellar") val stellar: GetBlockToken?, + @Json(name = "ton") val ton: GetBlockToken?, + @Json(name = "tron") val tron: GetBlockToken?, + @Json(name = "cosmos-hub") val cosmos: GetBlockToken?, + @Json(name = "near") val near: GetBlockToken?, + @Json(name = "terra-2") val luna: GetBlockToken?, + @Json(name = "dogecoin") val dogecoin: GetBlockToken?, + @Json(name = "litecoin") val litecoin: GetBlockToken?, + @Json(name = "dash") val dash: GetBlockToken?, + @Json(name = "bitcoin") val bitcoin: GetBlockToken?, +) + +@JsonClass(generateAdapter = true) +data class GetBlockToken( + @Json(name = "jsonRpc") val jsonRPC: String?, + @Json(name = "blockBookRest") val blockBookRest: String?, + @Json(name = "rest") val rest: String?, + @Json(name = "rosetta") val rosetta: String?, +) + data class AppsFlyer( val appsFlyerDevKey: String, val appsFlyerAppID: String, diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index 857c2f4ff1..cba2a01896 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -86,6 +86,7 @@ Ошибка Обменять Посмотреть историю транзакций + Обозреватель Обозреватель Сетевые комиссии за транзакции используются для поддержки безопасности сети, поощрения валидаторов, выделения ресурсов и определения приоритета транзакции. Свое diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/tokenreceive/TokenReceiveBottomSheet.kt b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/tokenreceive/TokenReceiveBottomSheet.kt index b9dc31d04f..704418b5ec 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/tokenreceive/TokenReceiveBottomSheet.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/bottomsheets/tokenreceive/TokenReceiveBottomSheet.kt @@ -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, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TransactionList.kt b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TransactionList.kt index 5920e09e81..202930549a 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TransactionList.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TransactionList.kt @@ -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 } diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TxHistoryGroupTitle.kt b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TxHistoryGroupTitle.kt index c7eaaa7978..4676fd5c49 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TxHistoryGroupTitle.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/TxHistoryGroupTitle.kt @@ -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()), + ) } } \ No newline at end of file diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/state/TxHistoryState.kt b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/state/TxHistoryState.kt index 6e297a4196..9801f79276 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/transactions/state/TxHistoryState.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/transactions/state/TxHistoryState.kt @@ -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 diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt index 3c29a58544..e418da8ea3 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/BlockchainIcons.kt @@ -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 } diff --git a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt index db286e6d51..93dae822ba 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/res/TangemTheme.kt @@ -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, diff --git a/core/ui/src/main/res/drawable/ic_near_22.xml b/core/ui/src/main/res/drawable/ic_near_22.xml new file mode 100644 index 0000000000..31661112fb --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_near_22.xml @@ -0,0 +1,9 @@ + + + diff --git a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt index 948ec336de..f2fdcd320e 100644 --- a/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt +++ b/data/balance-hiding/src/main/java/com/tangem/data/balancehiding/DefaultBalanceHidingRepository.kt @@ -13,6 +13,8 @@ internal class DefaultBalanceHidingRepository( private val appPreferencesStore: AppPreferencesStore, ) : BalanceHidingRepository { + override var isUpdateEnabled: Boolean = true + override fun getBalanceHidingSettingsFlow(): Flow { return appPreferencesStore.getObject( key = PreferencesKeys.BALANCE_HIDING_SETTINGS_KEY, diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt index 9e8d9a059d..a1b79d9bce 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultMarketCryptoCurrencyRepository.kt @@ -16,8 +16,7 @@ class DefaultMarketCryptoCurrencyRepository( return assetsStore.getSyncOrNull(userWalletId)?.find { it.network == cryptoCurrency.network.backendId && it.token == cryptoCurrency.id.rawCurrencyId && - it.contractAddress == contractAddress && - it.isActive + it.contractAddress == contractAddress }?.exchangeAvailable ?: false } } \ No newline at end of file diff --git a/domain/balance-hiding/models/src/main/kotlin/com/tangem/domain/balancehiding/BalanceHidingSettings.kt b/domain/balance-hiding/models/src/main/kotlin/com/tangem/domain/balancehiding/BalanceHidingSettings.kt index 2432bbc2ec..b646dd8c30 100644 --- a/domain/balance-hiding/models/src/main/kotlin/com/tangem/domain/balancehiding/BalanceHidingSettings.kt +++ b/domain/balance-hiding/models/src/main/kotlin/com/tangem/domain/balancehiding/BalanceHidingSettings.kt @@ -4,4 +4,5 @@ data class BalanceHidingSettings( val isHidingEnabledInSettings: Boolean, val isBalanceHidden: Boolean, val isBalanceHidingNotificationEnabled: Boolean, + val isUpdateFromToast: Boolean = false, ) \ No newline at end of file diff --git a/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/ListenToFlipsUseCase.kt b/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/ListenToFlipsUseCase.kt index c80577e10e..d518006d05 100644 --- a/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/ListenToFlipsUseCase.kt +++ b/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/ListenToFlipsUseCase.kt @@ -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 + } } \ No newline at end of file diff --git a/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/repositories/BalanceHidingRepository.kt b/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/repositories/BalanceHidingRepository.kt index 84161a07d9..93d21ef4b2 100644 --- a/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/repositories/BalanceHidingRepository.kt +++ b/domain/balance-hiding/src/main/kotlin/com/tangem/domain/balancehiding/repositories/BalanceHidingRepository.kt @@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow interface BalanceHidingRepository { + var isUpdateEnabled: Boolean + fun getBalanceHidingSettingsFlow(): Flow suspend fun storeBalanceHidingSettings(isBalanceHidden: BalanceHidingSettings) diff --git a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt index df437d1241..2e72d3e67f 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt @@ -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, ) \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt index 2565d2f226..f715061ac7 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/redux/LegacyAction.kt @@ -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 } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt index a581d0d2fa..15010e8b52 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/walletmanager/DefaultWalletManagersFacade.kt @@ -201,6 +201,7 @@ class DefaultWalletManagersFacade( val itemsResult = walletManager.getTransactionsHistory( request = TransactionHistoryRequest( address = walletManager.wallet.address, + decimals = currency.decimals, page = TransactionHistoryRequest.Page(number = page, size = pageSize), filterType = when (currency) { is CryptoCurrency.Coin -> TransactionHistoryRequest.FilterType.Coin diff --git a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt index e360bda6e4..87015b1305 100644 --- a/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt +++ b/domain/tokens/models/src/main/java/com/tangem/domain/tokens/model/CryptoCurrency.kt @@ -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) { diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/txhistory/TokenDetailsTxHistoryItemFlowConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/txhistory/TokenDetailsTxHistoryItemFlowConverter.kt index 819d32e1de..5af7329676 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/txhistory/TokenDetailsTxHistoryItemFlowConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/txhistory/TokenDetailsTxHistoryItemFlowConverter.kt @@ -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, @@ -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 } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt index e4f7243ad9..9ffd482c85 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt @@ -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(), diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/TokenItem.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/TokenItem.kt index ac0fac75db..9a3d17502f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/TokenItem.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/component/TokenItem.kt @@ -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, ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/txhistory/WalletTxHistoryItemFlowConverter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/txhistory/WalletTxHistoryItemFlowConverter.kt index 8f3e20271e..32b55caef0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/txhistory/WalletTxHistoryItemFlowConverter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/factory/txhistory/WalletTxHistoryItemFlowConverter.kt @@ -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 } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index d943c0f76a..bc1c275b2f 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -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() } diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index eed86ea134..95e9a29cf5 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -88,9 +88,9 @@ spr-client = "3.6.2" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "develop-387" +tangemBlockchainSdk = "develop-396" #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