From b5a7f3b38148370d0ac4e82c3425c480e27ad132 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 25 Sep 2024 22:01:06 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../java/com/tangem/tap/TangemApplication.kt | 10 +--- .../common/feedback/LegacyFeedbackManager.kt | 20 -------- .../common/feedback/ProxyFeedbackManager.kt | 20 -------- .../tap/common/redux/global/GlobalAction.kt | 2 - .../tap/common/redux/global/GlobalReducer.kt | 3 -- .../tap/common/redux/global/GlobalState.kt | 2 - .../common/redux/legacy/LegacyMiddleware.kt | 49 ------------------- .../tangem/tap/common/ui/ScanFailsDialog.kt | 9 +++- .../java/com/tangem/tap/di/UtilsModule.kt | 6 --- .../onboarding/OnboardingMenuProvider.kt | 7 ++- .../wallet/ui/OnboardingWalletFragment.kt | 6 ++- .../ui/dialogs/WalletActivationErrorDialog.kt | 7 ++- .../tangem/domain/feedback/FeedbackManager.kt | 8 --- .../com/tangem/domain/redux/LegacyAction.kt | 27 ---------- .../features/details/model/DetailsModel.kt | 9 +++- .../presentation/viewmodel/SendViewModel.kt | 43 +++++++++++----- .../viewmodel/StakingViewModel.kt | 6 +-- features/wallet/impl/build.gradle.kts | 1 + .../intents/WalletWarningsClickIntents.kt | 27 +++++----- 19 files changed, 85 insertions(+), 177 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt delete mode 100644 app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt delete mode 100644 domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackManager.kt diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index 3a5aaedb74..ea096779fa 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -44,7 +44,6 @@ import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder import com.tangem.tap.common.analytics.handlers.amplitude.AmplitudeAnalyticsHandler import com.tangem.tap.common.analytics.handlers.firebase.FirebaseAnalyticsHandler -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.common.images.createCoilImageLoader import com.tangem.tap.common.log.TangemAppLoggerInitializer import com.tangem.tap.common.redux.AppState @@ -288,7 +287,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private fun initWithConfigDependency(config: Config) { initAnalytics(this, config) - initFeedbackManager(store) + Log.addLogger(logger = tangemSdkLogger) } private fun initAnalytics(application: Application, config: Config) { @@ -308,11 +307,4 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { factory.build(Analytics, buildData) // ExceptionHandler.append(blockchainExceptionHandler) TODO: [REDACTED_JIRA] } - - private fun initFeedbackManager(store: Store) { - Log.addLogger(logger = tangemSdkLogger) - - val feedbackManager = LegacyFeedbackManager(sendFeedbackEmailUseCase = sendFeedbackEmailUseCase) - store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager)) - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt deleted file mode 100644 index 2fe68c1130..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/LegacyFeedbackManager.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.common.feedback - -import com.tangem.domain.feedback.SendFeedbackEmailUseCase -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.tap.scope -import kotlinx.coroutines.launch - -/** -[REDACTED_AUTHOR] - */ -class LegacyFeedbackManager( - private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, -) { - - fun sendEmail(type: FeedbackEmailType) { - scope.launch { - sendFeedbackEmailUseCase(type = type) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt deleted file mode 100644 index d013937813..0000000000 --- a/app/src/main/java/com/tangem/tap/common/feedback/ProxyFeedbackManager.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.tangem.tap.common.feedback - -import com.tangem.domain.feedback.FeedbackManager -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.tap.store -import timber.log.Timber - -internal class ProxyFeedbackManager : FeedbackManager { - - override fun sendEmail(type: FeedbackEmailType) { - val manager = store.state.globalState.feedbackManager - - if (manager == null) { - Timber.e("Feedback manager is not initialized") - return - } - - manager.sendEmail(type) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index f43551942e..ae7d06f836 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -6,7 +6,6 @@ import com.tangem.datasource.config.ConfigManager import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.common.redux.DebugErrorAction import com.tangem.tap.common.redux.ErrorAction import com.tangem.tap.common.redux.NotificationAction @@ -69,7 +68,6 @@ sealed class GlobalAction : Action { ) : GlobalAction() data class SetConfigManager(val configManager: ConfigManager) : GlobalAction() - data class SetFeedbackManager(val feedbackManager: LegacyFeedbackManager) : GlobalAction() object ExchangeManager : GlobalAction() { object Init : GlobalAction() { diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index 02c839de1f..cec7015f94 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -68,9 +68,6 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde ) globalState.copy(scanResponse = globalState.scanResponse.copy(card = newCardInstance)) } - is GlobalAction.SetFeedbackManager -> { - globalState.copy(feedbackManager = action.feedbackManager) - } is GlobalAction.ShowDialog -> { globalState.copy(dialog = action.stateDialog) } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 86573ec741..199835d5ef 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -5,7 +5,6 @@ import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.apptheme.model.AppThemeMode import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.feedback.LegacyFeedbackManager import com.tangem.tap.domain.TapWalletManager import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager @@ -18,7 +17,6 @@ data class GlobalState( val cardVerifiedOnline: Boolean = false, val tapWalletManager: TapWalletManager = TapWalletManager(), val configManager: ConfigManager? = null, - val feedbackManager: LegacyFeedbackManager? = null, val appCurrency: AppCurrency = AppCurrency.Default, val scanCardFailsCounter: Int = 0, val dialog: StateDialog? = null, 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 03c2b409a0..1dc41c90bd 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 @@ -1,12 +1,6 @@ package com.tangem.tap.common.redux.legacy -import com.tangem.blockchain.common.AmountType -import com.tangem.domain.feedback.models.BlockchainErrorInfo -import com.tangem.domain.feedback.models.CardInfo -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.redux.LegacyAction -import com.tangem.domain.utils.convertToSdkAmount import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.inject import com.tangem.tap.common.redux.AppState @@ -17,7 +11,6 @@ import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.utils.coroutines.JobHolder import com.tangem.utils.coroutines.saveIn -import com.tangem.utils.extensions.stripZeroPlainString import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn @@ -40,42 +33,6 @@ internal object LegacyMiddleware { ), ) } - is LegacyAction.SendEmailRateCanBeBetter -> { - store.state.globalState.feedbackManager?.sendEmail( - type = FeedbackEmailType.RateCanBeBetter(cardInfo = getCardInfo(action.scanResponse)), - ) - } - is LegacyAction.SendEmailSupport -> { - store.state.globalState.feedbackManager?.sendEmail( - type = FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo(action.scanResponse)), - ) - } - is LegacyAction.SendEmailTransactionFailed -> { - val amount = action.amount?.convertToSdkAmount(action.cryptoCurrency) - - store.inject(DaggerGraphState::saveBlockchainErrorUseCase).invoke( - error = BlockchainErrorInfo( - errorMessage = action.errorMessage, - blockchainId = action.cryptoCurrency.network.id.value, - derivationPath = action.cryptoCurrency.network.derivationPath.value, - destinationAddress = action.destinationAddress.orEmpty(), - tokenSymbol = if (amount?.type is AmountType.Token) { - amount.currencySymbol - } else { - "" - }, - amount = amount?.value?.stripZeroPlainString() ?: "unknown", - fee = action.fee?.convertToSdkAmount(action.cryptoCurrency) - ?.value?.stripZeroPlainString() ?: "unknown", - ), - ) - - store.state.globalState.feedbackManager?.sendEmail( - type = FeedbackEmailType.TransactionSendingProblem( - cardInfo = getCardInfo(action.scanResponse), - ), - ) - } is LegacyAction.PrepareDetailsScreen -> { val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager) val walletsRepository = store.inject(DaggerGraphState::walletsRepository) @@ -99,10 +56,4 @@ internal object LegacyMiddleware { } } } - - private fun getCardInfo(scanResponse: ScanResponse): CardInfo { - return store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse) - .getOrNull() - ?: error("Card info not found") - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt b/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt index 41c6405521..6096730a8e 100644 --- a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt +++ b/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt @@ -13,10 +13,14 @@ import com.tangem.domain.redux.StateDialog import com.tangem.tap.common.analytics.events.ScanFailsDialogAnalytics import com.tangem.tap.common.extensions.dispatchDialogHide import com.tangem.tap.common.extensions.dispatchOpenUrl +import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.home.LocaleRegionProvider import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE +import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.wallet.R +import kotlinx.coroutines.launch /** [REDACTED_AUTHOR] @@ -65,7 +69,10 @@ internal object ScanFailsDialog { customView.findViewById(R.id.request_support_button)?.setOnClickListener { Analytics.send(Basic.ButtonSupport(sourceAnalytics)) - store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.ScanningProblem) + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.ScanningProblem) + } } customView.findViewById(R.id.cancel_button)?.setOnClickListener { store.dispatchDialogHide() diff --git a/app/src/main/java/com/tangem/tap/di/UtilsModule.kt b/app/src/main/java/com/tangem/tap/di/UtilsModule.kt index 9c29c8598b..7fdf0263cc 100644 --- a/app/src/main/java/com/tangem/tap/di/UtilsModule.kt +++ b/app/src/main/java/com/tangem/tap/di/UtilsModule.kt @@ -5,8 +5,6 @@ import com.tangem.core.navigation.finisher.AppFinisher import com.tangem.core.navigation.settings.SettingsManager import com.tangem.core.navigation.share.ShareManager import com.tangem.core.navigation.url.UrlOpener -import com.tangem.domain.feedback.FeedbackManager -import com.tangem.tap.common.feedback.ProxyFeedbackManager import com.tangem.tap.common.finisher.AndroidAppFinisher import com.tangem.tap.common.settings.IntentSettingsManager import com.tangem.tap.common.share.IntentShareManager @@ -30,10 +28,6 @@ internal object UtilsModule { @Singleton fun provideUrlOpener(): UrlOpener = CustomTabsUrlOpener() - @Provides - @Singleton - fun provideFeedbackManager(): FeedbackManager = ProxyFeedbackManager() - @Provides @Singleton fun provideAppFinisher(@ApplicationContext context: Context): AppFinisher = AndroidAppFinisher(context) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt index 19ae4a9f8b..c619d4bd17 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingMenuProvider.kt @@ -11,9 +11,11 @@ import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.models.scan.ScanResponse import com.tangem.tap.common.extensions.inject import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.utils.Provider import com.tangem.wallet.R +import kotlinx.coroutines.launch /** [REDACTED_AUTHOR] @@ -33,7 +35,10 @@ class OnboardingMenuProvider( val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponseProvider()).getOrNull() ?: error("CardInfo must be not null") - store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } true } diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index bfeffcdc42..6ffddd4a21 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -46,6 +46,7 @@ import com.tangem.tap.features.onboarding.products.wallet.redux.* import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.AccessCodeDialog import com.tangem.tap.mainScope import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.utils.Provider import com.tangem.wallet.R @@ -516,7 +517,10 @@ class OnboardingWalletFragment : val getCardInfoUseCase = store.inject(DaggerGraphState::getCardInfoUseCase) val cardInfo = requireNotNull(getCardInfoUseCase.invoke(scanResponse).getOrNull()) - store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } }, onOpenUriClick = { uri -> store.dispatchOpenUrl(uri.toString()) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt index ed2b8493a1..aa0bf35450 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt @@ -11,8 +11,10 @@ import com.tangem.tap.common.extensions.dispatchDialogHide import com.tangem.tap.common.extensions.inject import com.tangem.tap.features.onboarding.OnboardingDialog import com.tangem.tap.proxy.redux.DaggerGraphState +import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.wallet.R +import kotlinx.coroutines.launch object WalletActivationErrorDialog { @@ -31,7 +33,10 @@ object WalletActivationErrorDialog { val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull() ?: error("CardInfo must be not null") - store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + scope.launch { + store.inject(DaggerGraphState::sendFeedbackEmailUseCase) + .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) + } } setOnDismissListener { store.dispatchDialogHide() } setCancelable(false) diff --git a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackManager.kt b/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackManager.kt deleted file mode 100644 index bc18ec66ec..0000000000 --- a/domain/feedback/src/main/java/com/tangem/domain/feedback/FeedbackManager.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.tangem.domain.feedback - -import com.tangem.domain.feedback.models.FeedbackEmailType - -interface FeedbackManager { - - fun sendEmail(type: FeedbackEmailType) -} \ 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 29003a8330..1bc55396bb 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,17 +1,10 @@ package com.tangem.domain.redux import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.tokens.model.CryptoCurrency -import com.tangem.domain.wallets.models.UserWalletId import org.rekotlin.Action -import java.math.BigDecimal sealed interface LegacyAction : Action { - data class SendEmailSupport(val scanResponse: ScanResponse) : LegacyAction - - data class SendEmailRateCanBeBetter(val scanResponse: ScanResponse) : LegacyAction - /** * Initiate an onboarding process. * For resuming unfinished backup of standard Wallet see @@ -19,25 +12,5 @@ sealed interface LegacyAction : Action { */ data class StartOnboardingProcess(val scanResponse: ScanResponse, val canSkipBackup: Boolean = true) : LegacyAction - /** - * Sending an email to support when sending transaction failed - * - * @param cryptoCurrency current currency - * @param userWalletId selected user wallet id - * @param amount sending amount - * @param fee spending fee - * @param destinationAddress recipient address - * @param errorMessage sending error - */ - data class SendEmailTransactionFailed( - val cryptoCurrency: CryptoCurrency, - val userWalletId: UserWalletId, - val amount: BigDecimal?, - val fee: BigDecimal?, - val destinationAddress: String?, - val errorMessage: String, - val scanResponse: ScanResponse, - ) : LegacyAction - data object PrepareDetailsScreen : LegacyAction } \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt index 9903c588e9..e6694cee44 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/model/DetailsModel.kt @@ -7,6 +7,9 @@ import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.navigation.Router import com.tangem.core.navigation.url.UrlOpener +import com.tangem.domain.feedback.GetCardInfoUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.redux.LegacyAction import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.walletconnect.CheckIsWalletConnectAvailableUseCase @@ -42,6 +45,8 @@ internal class DetailsModel @Inject constructor( paramsContainer: ParamsContainer, private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase, private val appStateHolder: ReduxStateHolder, + private val getCardInfoUseCase: GetCardInfoUseCase, + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, override val dispatchers: CoroutineDispatcherProvider, ) : Model() { @@ -94,7 +99,9 @@ internal class DetailsModel @Inject constructor( val scanResponse = getSelectedWalletSyncUseCase().getOrNull()?.scanResponse ?: error("Selected wallet is null") - appStateHolder.dispatch(LegacyAction.SendEmailSupport(scanResponse)) + val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch + + sendFeedbackEmailUseCase(type = FeedbackEmailType.DirectUserRequest(cardInfo = cardInfo)) } } diff --git a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt index 47c9697faa..468482bb95 100644 --- a/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt +++ b/features/send/impl/src/main/java/com/tangem/features/send/impl/presentation/viewmodel/SendViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.* import arrow.core.Either import arrow.core.getOrElse import arrow.core.left +import com.tangem.blockchain.common.AmountType import com.tangem.blockchain.common.TransactionData import com.tangem.blockchain.common.transaction.TransactionFee import com.tangem.common.routing.AppRoute @@ -18,11 +19,14 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.common.util.cardTypesResolver +import com.tangem.domain.feedback.GetCardInfoUseCase +import com.tangem.domain.feedback.SaveBlockchainErrorUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase +import com.tangem.domain.feedback.models.BlockchainErrorInfo +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.qrscanning.models.SourceType import com.tangem.domain.qrscanning.usecases.ListenToQrScanningUseCase import com.tangem.domain.qrscanning.usecases.ParseQrCodeUseCase -import com.tangem.domain.redux.LegacyAction -import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.settings.IsSendTapHelpEnabledUseCase import com.tangem.domain.settings.NeverShowTapHelpUseCase import com.tangem.domain.tokens.* @@ -55,6 +59,7 @@ import com.tangem.features.send.impl.presentation.state.recipient.RecipientSendF import com.tangem.lib.crypto.BlockchainUtils import com.tangem.utils.Provider import com.tangem.utils.coroutines.* +import com.tangem.utils.extensions.stripZeroPlainString import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* import kotlinx.coroutines.flow.* @@ -82,7 +87,6 @@ internal class SendViewModel @Inject constructor( private val sendTransactionUseCase: SendTransactionUseCase, private val createTransactionUseCase: CreateTransactionUseCase, private val validateWalletAddressUseCase: ValidateWalletAddressUseCase, - private val reduxStateHolder: ReduxStateHolder, private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase, private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase, private val analyticsEventHandler: AnalyticsEventHandler, @@ -96,6 +100,9 @@ internal class SendViewModel @Inject constructor( private val fetchPendingTransactionsUseCase: FetchPendingTransactionsUseCase, private val isUtxoConsolidationAvailableUseCase: IsUtxoConsolidationAvailableUseCase, private val validateWalletMemoUseCase: ValidateWalletMemoUseCase, + private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase, + private val getCardInfoUseCase: GetCardInfoUseCase, + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, @DelayedWork private val coroutineScope: CoroutineScope, validateTransactionUseCase: ValidateTransactionUseCase, getCurrencyCheckUseCase: GetCurrencyCheckUseCase, @@ -521,17 +528,31 @@ internal class SendViewModel @Inject constructor( } else { null } - reduxStateHolder.dispatch( - LegacyAction.SendEmailTransactionFailed( - cryptoCurrency = cryptoCurrency, - userWalletId = userWalletId, - amount = receivingAmount, - fee = feeValue, - destinationAddress = recipient, + + val amount = receivingAmount?.convertToSdkAmount(cryptoCurrency) + + saveBlockchainErrorUseCase( + error = BlockchainErrorInfo( errorMessage = errorMessage, - scanResponse = userWallet.scanResponse, + blockchainId = cryptoCurrency.network.id.value, + derivationPath = cryptoCurrency.network.derivationPath.value, + destinationAddress = recipient.orEmpty(), + tokenSymbol = if (amount?.type is AmountType.Token) { + amount.currencySymbol + } else { + "" + }, + amount = amount?.value?.stripZeroPlainString() ?: "unknown", + fee = feeValue?.convertToSdkAmount(cryptoCurrency) + ?.value?.stripZeroPlainString() ?: "unknown", ), ) + + val cardInfo = getCardInfoUseCase(userWallet.scanResponse).getOrNull() ?: return + + viewModelScope.launch { + sendFeedbackEmailUseCase(type = FeedbackEmailType.TransactionSendingProblem(cardInfo = cardInfo)) + } } override fun onTokenDetailsClick(currency: CryptoCurrency) = innerRouter.openTokenDetails(userWalletId, currency) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt index a5afd54f97..41c2ef064a 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/viewmodel/StakingViewModel.kt @@ -18,9 +18,9 @@ import com.tangem.core.ui.haptic.VibratorHapticManager import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase -import com.tangem.domain.feedback.FeedbackManager import com.tangem.domain.feedback.GetCardInfoUseCase import com.tangem.domain.feedback.SaveBlockchainErrorUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase import com.tangem.domain.feedback.models.BlockchainErrorInfo import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.staking.InvalidatePendingTransactionsUseCase @@ -92,7 +92,6 @@ internal class StakingViewModel @Inject constructor( private val getAllowanceUseCase: GetAllowanceUseCase, private val isApproveNeededUseCase: IsApproveNeededUseCase, private val vibratorHapticManager: VibratorHapticManager, - private val feedbackManager: FeedbackManager, private val getCardInfoUseCase: GetCardInfoUseCase, private val saveBlockchainErrorUseCase: SaveBlockchainErrorUseCase, private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase, @@ -105,6 +104,7 @@ internal class StakingViewModel @Inject constructor( private val stakingFeeTransactionLoader: StakingFeeTransactionLoader.Factory, private val stakingBalanceUpdater: StakingBalanceUpdater.Factory, private val analyticsEventHandler: AnalyticsEventHandler, + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, @DelayedWork private val coroutineScope: CoroutineScope, savedStateHandle: SavedStateHandle, ) : ViewModel(), DefaultLifecycleObserver, StakingClickIntents { @@ -716,7 +716,7 @@ internal class StakingViewModel @Inject constructor( unsignedTransactions = transactionsInProgress.map { it.unsignedTransaction }, ) - feedbackManager.sendEmail(email) + sendFeedbackEmailUseCase(email) } } diff --git a/features/wallet/impl/build.gradle.kts b/features/wallet/impl/build.gradle.kts index db8ba49b05..6164b3a3cc 100644 --- a/features/wallet/impl/build.gradle.kts +++ b/features/wallet/impl/build.gradle.kts @@ -80,6 +80,7 @@ dependencies { implementation(projects.domain.visa) implementation(projects.domain.staking.models) implementation(projects.domain.markets.models) + implementation(projects.domain.feedback) //TODO: Create api/impl modules for onboarding [REDACTED_JIRA] implementation(projects.features.onboarding) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt index 6798d988ff..a911c09913 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletWarningsClickIntents.kt @@ -6,6 +6,9 @@ import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.core.ui.extensions.resourceReference import com.tangem.domain.card.DerivePublicKeysUseCase import com.tangem.domain.card.SetCardWasScannedUseCase +import com.tangem.domain.feedback.GetCardInfoUseCase +import com.tangem.domain.feedback.SendFeedbackEmailUseCase +import com.tangem.domain.feedback.models.FeedbackEmailType import com.tangem.domain.redux.LegacyAction import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.settings.NeverToSuggestRateAppUseCase @@ -84,6 +87,8 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( private val dispatchers: CoroutineDispatcherProvider, private val shouldShowSwapPromoWalletUseCase: ShouldShowSwapPromoWalletUseCase, private val shouldShowTravalaPromoWalletUseCase: ShouldShowTravalaPromoWalletUseCase, + private val getCardInfoUseCase: GetCardInfoUseCase, + private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase, ) : BaseWalletClickIntents(), WalletWarningsClickIntents { override fun onAddBackupCardClick() { @@ -209,12 +214,10 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( viewModelScope.launch(dispatchers.main) { neverToSuggestRateAppUseCase() - reduxStateHolder.dispatch( - LegacyAction.SendEmailRateCanBeBetter( - scanResponse = getSelectedUserWallet()?.scanResponse - ?: error("ScanResponse must be not null"), - ), - ) + val scanResponse = getSelectedUserWallet()?.scanResponse ?: return@launch + val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return@launch + + sendFeedbackEmailUseCase(type = FeedbackEmailType.RateCanBeBetter(cardInfo = cardInfo)) } } @@ -268,12 +271,12 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor( } override fun onSupportClick() { - reduxStateHolder.dispatch( - LegacyAction.SendEmailSupport( - scanResponse = getSelectedUserWallet()?.scanResponse - ?: error("ScanResponse must be not null"), - ), - ) + val scanResponse = getSelectedUserWallet()?.scanResponse ?: return + val cardInfo = getCardInfoUseCase(scanResponse).getOrNull() ?: return + + viewModelScope.launch { + sendFeedbackEmailUseCase(type = FeedbackEmailType.DirectUserRequest(cardInfo = cardInfo)) + } } private fun getSelectedUserWallet(): UserWallet? {