Updated on 2026-08-14
This commit is contained in:
commit
4d62896c8e
27 changed files with 78 additions and 189 deletions
|
|
@ -156,8 +156,6 @@ dependencies {
|
|||
implementation(deps.appsflyer)
|
||||
implementation(deps.amplitude)
|
||||
implementation(deps.kotsonGson)
|
||||
implementation(deps.zendesk.chat)
|
||||
implementation(deps.zendesk.messaging)
|
||||
implementation(deps.spongecastle.core)
|
||||
implementation(deps.lottie)
|
||||
implementation(deps.shopify.buy) {
|
||||
|
|
|
|||
|
|
@ -141,10 +141,6 @@
|
|||
android:name="com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
|
||||
<activity
|
||||
android:name="zendesk.messaging.MessagingActivity"
|
||||
android:theme="@style/ZendeskTheme" />
|
||||
|
||||
<activity
|
||||
android:name="com.tangem.feature.learn2earn.presentation.webView.Learn2earnWebViewActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import com.tangem.tap.common.shop.googlepay.GooglePayService
|
|||
import com.tangem.tap.common.shop.googlepay.GooglePayService.Companion.LOAD_PAYMENT_DATA_REQUEST_CODE
|
||||
import com.tangem.tap.common.shop.googlepay.GooglePayUtil.createPaymentsClient
|
||||
import com.tangem.tap.domain.TangemSdkManager
|
||||
import com.tangem.tap.domain.userWalletList.implementation.BiometricUserWalletsListManager
|
||||
import com.tangem.tap.domain.walletconnect2.domain.WalletConnectInteractor
|
||||
import com.tangem.tap.features.intentHandler.IntentProcessor
|
||||
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
|
||||
|
|
@ -349,7 +350,10 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
|
|||
}
|
||||
|
||||
private fun navigateToInitialScreen(intentWhichStartedActivity: Intent?) {
|
||||
if (store.state.globalState.userWalletsListManager?.hasUserWallets == true) {
|
||||
val canSaveWallets = userWalletsListManager is BiometricUserWalletsListManager
|
||||
val hasSavedWallets = userWalletsListManager.hasUserWallets
|
||||
|
||||
if (canSaveWallets && hasSavedWallets) {
|
||||
store.dispatch(
|
||||
NavigationAction.NavigateTo(
|
||||
screen = AppScreen.Welcome,
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ internal class TapApplication : Application(), ImageLoaderFactory {
|
|||
private fun initWithConfigDependency(config: Config) {
|
||||
shopService = TangemShopService(this, config.shopify!!)
|
||||
initAnalytics(this, config)
|
||||
initFeedbackManager(this, preferencesStorage, foregroundActivityObserver, store)
|
||||
initFeedbackManager(this, foregroundActivityObserver, store)
|
||||
}
|
||||
|
||||
private fun initAnalytics(application: Application, config: Config) {
|
||||
|
|
@ -360,7 +360,6 @@ internal class TapApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
private fun initFeedbackManager(
|
||||
context: Context,
|
||||
preferencesStorage: PreferencesDataSource,
|
||||
foregroundActivityObserver: ForegroundActivityObserver,
|
||||
store: Store<AppState>,
|
||||
) {
|
||||
|
|
@ -399,7 +398,7 @@ internal class TapApplication : Application(), ImageLoaderFactory {
|
|||
val feedbackManager = FeedbackManager(
|
||||
infoHolder = additionalFeedbackInfo,
|
||||
logCollector = tangemLogCollector,
|
||||
chatManager = ChatManager(preferencesStorage, foregroundActivityObserver),
|
||||
chatManager = ChatManager(foregroundActivityObserver),
|
||||
)
|
||||
store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,23 @@
|
|||
package com.tangem.tap.common.chat
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import com.tangem.data.source.preferences.PreferencesDataSource
|
||||
import com.tangem.datasource.config.models.ChatConfig
|
||||
import com.tangem.datasource.config.models.SprinklrConfig
|
||||
import com.tangem.datasource.config.models.ZendeskConfig
|
||||
import com.tangem.tap.ForegroundActivityObserver
|
||||
import com.tangem.tap.common.chat.opener.ChatOpener
|
||||
import com.tangem.tap.common.chat.opener.implementation.SprinklrChatOpener
|
||||
import com.tangem.tap.common.chat.opener.implementation.ZendeskChatOpener
|
||||
import java.io.File
|
||||
|
||||
class ChatManager(
|
||||
private val preferencesStorage: PreferencesDataSource,
|
||||
private val foregroundActivityObserver: ForegroundActivityObserver,
|
||||
) {
|
||||
class ChatManager(private val foregroundActivityObserver: ForegroundActivityObserver) {
|
||||
private val openers = mutableMapOf<ChatConfig, ChatOpener>()
|
||||
|
||||
fun open(config: ChatConfig, createLogsFile: (Context) -> File?, createFeedbackFile: (Context) -> File?) {
|
||||
val opener = openers.getOrPut(config) {
|
||||
when (config) {
|
||||
is SprinklrConfig -> SprinklrChatOpener(config, foregroundActivityObserver)
|
||||
is ZendeskConfig -> ZendeskChatOpener(getZendeskUserId(), config, foregroundActivityObserver)
|
||||
}
|
||||
}
|
||||
|
||||
opener.open(createFeedbackFile, createLogsFile)
|
||||
}
|
||||
|
||||
private fun getZendeskUserId(): String {
|
||||
if (preferencesStorage.zendeskFirstLaunchTime == null) {
|
||||
preferencesStorage.zendeskFirstLaunchTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
return "${preferencesStorage.zendeskFirstLaunchTime}${Build.MODEL}".hashCode().toString()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
package com.tangem.tap.common.chat.opener.implementation
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.datasource.config.models.ZendeskConfig
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.tap.ForegroundActivityObserver
|
||||
import com.tangem.tap.common.chat.opener.ChatOpener
|
||||
import com.tangem.tap.withForegroundActivity
|
||||
import com.tangem.wallet.R
|
||||
import com.zendesk.logger.Logger
|
||||
import timber.log.Timber
|
||||
import zendesk.chat.*
|
||||
import zendesk.configurations.Configuration
|
||||
import zendesk.messaging.MessagingActivity
|
||||
import java.io.File
|
||||
|
||||
internal class ZendeskChatOpener(
|
||||
private val userId: String,
|
||||
private val config: ZendeskConfig,
|
||||
private val foregroundActivityObserver: ForegroundActivityObserver,
|
||||
) : ChatOpener {
|
||||
|
||||
private var isInitialized = false
|
||||
private var isFilesSent = false
|
||||
|
||||
override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) {
|
||||
foregroundActivityObserver.withForegroundActivity { activity ->
|
||||
initZendeskIfNeeded(activity.applicationContext)
|
||||
setChatVisitorInfo()
|
||||
showMessagingActivity(activity)
|
||||
sendFeedbackFile(createFeedbackFile(activity))
|
||||
sendLogsFile(createLogsFile(activity))
|
||||
}
|
||||
}
|
||||
|
||||
private fun initZendeskIfNeeded(context: Context) {
|
||||
if (isInitialized) return
|
||||
isInitialized = true
|
||||
|
||||
Chat.INSTANCE.init(context, config.accountKey, config.appId)
|
||||
Logger.setLoggable(LogConfig.zendesk)
|
||||
}
|
||||
|
||||
private fun setChatVisitorInfo() {
|
||||
val visitorInfo = VisitorInfo.builder().withName("User $userId").build()
|
||||
|
||||
Chat.INSTANCE.chatProvidersConfiguration =
|
||||
ChatProvidersConfiguration.builder().withVisitorInfo(visitorInfo).build()
|
||||
}
|
||||
|
||||
private fun sendFeedbackFile(feedbackFile: File?) {
|
||||
if (isInitialized && feedbackFile != null && !isFilesSent) {
|
||||
Chat.INSTANCE.providers()?.chatProvider()?.sendFile(feedbackFile) { _, bytesUploaded, _ ->
|
||||
Timber.d("Log file sent", "bytesUploaded: $bytesUploaded")
|
||||
}
|
||||
isFilesSent = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendLogsFile(logsFile: File?) {
|
||||
if (isInitialized && logsFile != null && !isFilesSent) {
|
||||
Chat.INSTANCE.providers()?.chatProvider()?.sendFile(logsFile) { _, bytesUploaded, _ ->
|
||||
Timber.d("Log file sent", "bytesUploaded: $bytesUploaded")
|
||||
}
|
||||
isFilesSent = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun showMessagingActivity(context: Context) {
|
||||
Analytics.send(com.tangem.tap.common.analytics.events.Chat.ScreenOpened())
|
||||
MessagingActivity.builder()
|
||||
.withMultilineResponseOptionsEnabled(false)
|
||||
.withBotLabelStringRes(R.string.chat_bot_name)
|
||||
.withBotAvatarDrawable(R.mipmap.ic_launcher)
|
||||
.withEngines(ChatEngine.engine())
|
||||
.show(context, buildChatConfig())
|
||||
}
|
||||
|
||||
private fun buildChatConfig(): Configuration {
|
||||
return ChatConfiguration.builder()
|
||||
.withOfflineFormEnabled(true)
|
||||
.withAgentAvailabilityEnabled(true)
|
||||
.withPreChatFormEnabled(false)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
@ -36,8 +36,7 @@ class AdditionalFeedbackInfo {
|
|||
var userWalletId: String = ""
|
||||
|
||||
// wallets
|
||||
var walletsInfo = emptyList<EmailWalletInfo>()
|
||||
private set
|
||||
val walletsInfo = mutableListOf<EmailWalletInfo>()
|
||||
var onSendErrorWalletInfo: EmailWalletInfo? = null
|
||||
private set
|
||||
var signedHashesCount: String = ""
|
||||
|
|
@ -74,7 +73,10 @@ class AdditionalFeedbackInfo {
|
|||
|
||||
@Deprecated("Don't use it directly")
|
||||
fun setWalletsInfo(walletManagers: List<WalletManager>) {
|
||||
walletsInfo = walletManagers.map(::createEmailWalletInfo)
|
||||
walletsInfo.clear()
|
||||
walletManagers.forEach {
|
||||
walletsInfo.add(createEmailWalletInfo(it))
|
||||
}
|
||||
}
|
||||
|
||||
fun updateOnSendError(
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="ZendeskTheme" parent="ZendeskThemeBase">
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="ZendeskTheme" parent="ZendeskThemeBase" />
|
||||
|
||||
<style name="ZendeskThemeBase" parent="ZendeskSdkTheme.Light">
|
||||
<item name="colorPrimary">@color/darkGray6</item>
|
||||
<item name="colorPrimaryDark">@color/darkGray6</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -102,7 +102,6 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager {
|
|||
appsFlyerDevKey = configValues.appsFlyer.appsFlyerDevKey,
|
||||
amplitudeApiKey = configValues.amplitudeApiKey,
|
||||
shopify = configValues.shopifyShop,
|
||||
zendesk = configValues.zendesk,
|
||||
sprinklr = configValues.sprinklr,
|
||||
swapReferrerAccount = configValues.swapReferrerAccount,
|
||||
walletConnectProjectId = configValues.walletConnectProjectId,
|
||||
|
|
|
|||
|
|
@ -5,26 +5,9 @@ import com.squareup.moshi.JsonClass
|
|||
|
||||
sealed interface ChatConfig
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ZendeskConfig(
|
||||
@Json(name = "zendeskApiKey")
|
||||
val apiKey: String,
|
||||
@Json(name = "zendeskAppId")
|
||||
val appId: String,
|
||||
@Json(name = "zendeskClientId")
|
||||
val clientId: String,
|
||||
@Json(name = "zendeskAccountKey")
|
||||
val accountKey: String,
|
||||
@Json(name = "zendeskUrl")
|
||||
val url: String,
|
||||
) : ChatConfig
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class SprinklrConfig(
|
||||
@Json(name = "appID")
|
||||
val appId: String,
|
||||
@Json(name = "apiKey")
|
||||
val apiKey: String,
|
||||
@Json(name = "environment")
|
||||
val environment: String,
|
||||
@Json(name = "appID") val appId: String,
|
||||
@Json(name = "apiKey") val apiKey: String,
|
||||
@Json(name = "environment") val environment: String,
|
||||
) : ChatConfig
|
||||
|
|
@ -15,7 +15,6 @@ data class Config(
|
|||
@Deprecated("Not relevant since version 3.23")
|
||||
val isCreatingTwinCardsAllowed: Boolean = false,
|
||||
val shopify: ShopifyShop? = null,
|
||||
val zendesk: ZendeskConfig? = null,
|
||||
val sprinklr: SprinklrConfig? = null,
|
||||
val swapReferrerAccount: SwapReferrerAccount? = null,
|
||||
val walletConnectProjectId: String = "",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ class ConfigValueModel(
|
|||
val infuraProjectId: String?,
|
||||
val appsFlyer: AppsFlyer,
|
||||
val shopifyShop: ShopifyShop?,
|
||||
val zendesk: ZendeskConfig?,
|
||||
val sprinklr: SprinklrConfig?,
|
||||
val tronGridApiKey: String,
|
||||
val amplitudeApiKey: String,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,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
|
||||
|
|
@ -23,7 +24,6 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.MiddleEllipsisText
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconStart
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
|
|
@ -113,6 +113,7 @@ private fun QrCodeContent(content: TokenReceiveBottomSheetConfig, onAddressChang
|
|||
state = pagerState,
|
||||
) { currentPage ->
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
||||
) {
|
||||
|
|
@ -134,7 +135,7 @@ private fun QrCodeContent(content: TokenReceiveBottomSheetConfig, onAddressChang
|
|||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size248),
|
||||
)
|
||||
MiddleEllipsisText(
|
||||
Text(
|
||||
text = content.addresses[currentPage].value,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -156,11 +157,9 @@ private fun QrCodeContent(content: TokenReceiveBottomSheetConfig, onAddressChang
|
|||
) {
|
||||
repeat(pagerState.pageCount) { iteration ->
|
||||
item(key = iteration) {
|
||||
val color = if (pagerState.currentPage == iteration) {
|
||||
selectedColor
|
||||
} else {
|
||||
unselectedColor
|
||||
}
|
||||
val color by animateColorAsState(
|
||||
if (pagerState.currentPage == iteration) selectedColor else unselectedColor,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@ class PreferencesDataSource @Inject internal constructor(applicationContext: Con
|
|||
toppedUpWalletStorage = ToppedUpWalletStorage(preferences, moshiConverter)
|
||||
}
|
||||
|
||||
var zendeskFirstLaunchTime: Long?
|
||||
get() = preferences.getLong(ZENDESK_FIRST_LAUNCH_KEY, 0).takeIf { it != 0L }
|
||||
set(value) = preferences.edit { putLong(ZENDESK_FIRST_LAUNCH_KEY, value ?: 0) }
|
||||
|
||||
var sprinklrFirstLaunchTime: Long?
|
||||
get() = preferences.getLong(SPRINKLR_FIRST_LAUNCH_KEY, 0).takeIf { it != 0L }
|
||||
set(value) = preferences.edit { putLong(SPRINKLR_FIRST_LAUNCH_KEY, value ?: 0) }
|
||||
|
|
@ -93,7 +89,6 @@ class PreferencesDataSource @Inject internal constructor(applicationContext: Con
|
|||
private const val PREFERENCES_NAME = "tapPrefs"
|
||||
private const val TWINS_ONBOARDING_SHOWN_KEY = "twinsOnboardingShown"
|
||||
private const val APP_LAUNCH_COUNT_KEY = "launchCount"
|
||||
private const val ZENDESK_FIRST_LAUNCH_KEY = "chatFirstLaunchKey"
|
||||
private const val SPRINKLR_FIRST_LAUNCH_KEY = "sprinklrFirstLaunch"
|
||||
private const val SAVE_WALLET_DIALOG_SHOWN_KEY = "saveUserWalletShown"
|
||||
private const val SAVE_ACCESS_CODES_KEY = "saveAccessCodes"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import com.tangem.domain.common.util.hasDerivation
|
|||
import com.tangem.domain.core.error.DataError
|
||||
import com.tangem.domain.demo.DemoConfig
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -302,6 +303,20 @@ internal class DefaultCurrenciesRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override fun hasPendingTransactions(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
coinStatus: CryptoCurrencyStatus?,
|
||||
): Boolean {
|
||||
val blockchain = Blockchain.fromId(cryptoCurrencyStatus.currency.network.id.value)
|
||||
val isBitcoinBlockchain = blockchain == Blockchain.Bitcoin || blockchain == Blockchain.BitcoinTestnet
|
||||
return if (cryptoCurrencyStatus.currency is CryptoCurrency.Coin && isBitcoinBlockchain) {
|
||||
val outgoingTransactions = cryptoCurrencyStatus.value.pendingTransactions.filter { it.isOutgoing }
|
||||
outgoingTransactions.isNotEmpty()
|
||||
} else {
|
||||
coinStatus?.value?.hasCurrentNetworkTransactions == true
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMultiCurrencyWalletCurrencies(userWallet: UserWallet): Flow<List<CryptoCurrency>> {
|
||||
return userTokensStore.get(userWallet.walletId).map { storedTokens ->
|
||||
responseCurrenciesFactory.createCurrencies(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.domain.features.BuildConfig
|
|||
object LogConfig {
|
||||
const val imageLoader: Boolean = false
|
||||
val storeAction: Boolean = BuildConfig.DEBUG
|
||||
const val zendesk: Boolean = false
|
||||
val network: NetworkLogConfig = NetworkLogConfig
|
||||
val analyticsHandlers: AnalyticsHandlersLogConfig = AnalyticsHandlersLogConfig
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,10 +102,7 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
}
|
||||
|
||||
// send
|
||||
if (cryptoCurrencyStatus.value.amount.isNullOrZero() ||
|
||||
coinStatus?.value?.amount.isNullOrZero() ||
|
||||
coinStatus?.value?.hasCurrentNetworkTransactions == true
|
||||
) {
|
||||
if (isSendDisabled(cryptoCurrencyStatus = cryptoCurrencyStatus, coinStatus = coinStatus)) {
|
||||
disabledList.add(TokenActionsState.ActionState.Send(false))
|
||||
} else {
|
||||
activeList.add(TokenActionsState.ActionState.Send(true))
|
||||
|
|
@ -151,4 +148,12 @@ class GetCryptoCurrencyActionsUseCase(
|
|||
activeList.add(TokenActionsState.ActionState.HideToken(true))
|
||||
return activeList + disabledList
|
||||
}
|
||||
|
||||
private fun isSendDisabled(cryptoCurrencyStatus: CryptoCurrencyStatus, coinStatus: CryptoCurrencyStatus?): Boolean =
|
||||
cryptoCurrencyStatus.value.amount.isNullOrZero() ||
|
||||
coinStatus?.value?.amount.isNullOrZero() ||
|
||||
currenciesRepository.hasPendingTransactions(
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
coinStatus = coinStatus,
|
||||
)
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ class GetCurrencyWarningsUseCase(
|
|||
when {
|
||||
tokenStatus != null && coinStatus != null -> {
|
||||
buildList {
|
||||
if (tokenStatus.value.hasCurrentNetworkTransactions) {
|
||||
if (currenciesRepository.hasPendingTransactions(tokenStatus, coinStatus)) {
|
||||
add(CryptoCurrencyWarning.HasPendingTransactions(coinStatus.currency.symbol))
|
||||
}
|
||||
if (!tokenStatus.value.amount.isZero() && coinStatus.value.amount.isZero()) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.domain.tokens.repository
|
||||
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -173,4 +174,12 @@ interface CurrenciesRepository {
|
|||
fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Boolean>
|
||||
|
||||
fun getMissedAddressesCryptoCurrencies(userWalletId: UserWalletId): Flow<List<CryptoCurrency>>
|
||||
|
||||
/**
|
||||
* Determines whether the currency has pending transaction or currency network has pending transaction
|
||||
*
|
||||
* @param cryptoCurrencyStatus currency status
|
||||
* @param coinStatus main currency status in [cryptoCurrencyStatus] network
|
||||
*/
|
||||
fun hasPendingTransactions(cryptoCurrencyStatus: CryptoCurrencyStatus, coinStatus: CryptoCurrencyStatus?): Boolean
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import arrow.core.Either
|
|||
import arrow.core.getOrElse
|
||||
import com.tangem.domain.core.error.DataError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrency
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
|
@ -109,4 +110,11 @@ internal class MockCurrenciesRepository(
|
|||
override fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
return isSortedByBalance.map { it.getOrElse { e -> throw e } }
|
||||
}
|
||||
|
||||
override fun hasPendingTransactions(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
coinStatus: CryptoCurrencyStatus?,
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
|
@ -239,7 +239,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
showErrorIfDemoModeOrElse {
|
||||
val status = cryptoCurrencyStatus ?: return@showErrorIfDemoModeOrElse
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
reduxStateHolder.dispatch(
|
||||
TradeCryptoAction.New.Buy(
|
||||
userWallet = getUserWalletUseCase(userWalletId).getOrElse { return@launch },
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ internal class TokenActionsProvider(
|
|||
fun provideActions(tokenActions: TokenActionsState): ImmutableList<TokenActionButtonConfig> {
|
||||
return tokenActions.states
|
||||
.filterIfSingleWithToken()
|
||||
.filterIfS2C()
|
||||
.mapNotNull {
|
||||
mapTokenActionState(
|
||||
actionsState = it,
|
||||
|
|
@ -47,14 +46,6 @@ internal class TokenActionsProvider(
|
|||
}
|
||||
}
|
||||
|
||||
private fun List<TokenActionsState.ActionState>.filterIfS2C(): List<TokenActionsState.ActionState> {
|
||||
return if (currentWalletProvider().scanResponse.cardTypesResolver.isStart2Coin()) {
|
||||
filterNot { it is TokenActionsState.ActionState.Buy || it is TokenActionsState.ActionState.Sell }
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapTokenActionState(
|
||||
actionsState: TokenActionsState.ActionState,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.factory
|
||||
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.tokens.model.TokenActionsState
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
|
|
@ -12,6 +14,7 @@ import kotlinx.collections.immutable.PersistentList
|
|||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
internal class WalletCryptoCurrencyActionsConverter(
|
||||
private val currentWalletProvider: Provider<UserWallet>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<TokenActionsState, WalletState> {
|
||||
|
|
@ -28,6 +31,7 @@ internal class WalletCryptoCurrencyActionsConverter(
|
|||
|
||||
private fun TokenActionsState.mapToManageButtons(): PersistentList<WalletManageButton> {
|
||||
return this.states
|
||||
.filterIfS2C()
|
||||
.mapNotNull { action ->
|
||||
when (action) {
|
||||
is TokenActionsState.ActionState.Buy -> {
|
||||
|
|
@ -60,4 +64,12 @@ internal class WalletCryptoCurrencyActionsConverter(
|
|||
}
|
||||
.toPersistentList()
|
||||
}
|
||||
|
||||
private fun List<TokenActionsState.ActionState>.filterIfS2C(): List<TokenActionsState.ActionState> {
|
||||
return if (currentWalletProvider().scanResponse.cardTypesResolver.isStart2Coin()) {
|
||||
filterNot { it is TokenActionsState.ActionState.Buy || it is TokenActionsState.ActionState.Sell }
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -127,6 +127,7 @@ internal class WalletStateFactory(
|
|||
|
||||
private val cryptoCurrencyActionsConverter by lazy {
|
||||
WalletCryptoCurrencyActionsConverter(
|
||||
currentWalletProvider = currentWalletProvider,
|
||||
currentStateProvider = currentStateProvider,
|
||||
clickIntents = clickIntents,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -67,8 +67,6 @@ spongycastleCryptoCore = "1.58.0.0"
|
|||
timber = "4.7.1"
|
||||
viewBindingDelegate = "1.5.9"
|
||||
xmlShimmer = "1.1.3"
|
||||
zendeskChat = "3.3.5"
|
||||
zendeskMessaging = "5.2.4"
|
||||
zxingQrBarcodeScanner = "1.9.8"
|
||||
zxingQrCode = "3.5.1"
|
||||
mviCore = "1.3.1"
|
||||
|
|
@ -219,8 +217,6 @@ retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.re
|
|||
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
|
||||
viewBindingDelegate = { module = "com.github.kirich1409:viewbindingpropertydelegate-noreflection", version.ref = "viewBindingDelegate" }
|
||||
xmlShimmer = { module = "com.github.skydoves:androidveil", version.ref = "xmlShimmer" }
|
||||
zendesk-chat = { module = "com.zendesk:chat", version.ref = "zendeskChat" }
|
||||
zendesk-messaging = { module = "com.zendesk:messaging", version.ref = "zendeskMessaging" }
|
||||
zxing-qrBarcodeScanner = { module = "me.dm7.barcodescanner:zxing", version.ref = "zxingQrBarcodeScanner" }
|
||||
zxing-qrCore = { module = "com.google.zxing:core", version.ref = "zxingQrCode" }
|
||||
mviCore-watcher = { module = "com.github.badoo.mvicore:mvicore-diff", version.ref = "mviCore" }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ dependencyResolutionManagement {
|
|||
}
|
||||
}
|
||||
maven("https://jitpack.io")
|
||||
maven("https://zendesk.jfrog.io/zendesk/repo")
|
||||
maven("https://clients-nexus.sprinklr.com/")
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue