Updated on 2026-08-14
This commit is contained in:
parent
1d589158a5
commit
ad582bfc1a
21 changed files with 81 additions and 667 deletions
|
|
@ -17,7 +17,6 @@ import com.tangem.domain.apptheme.repository.AppThemeModeRepository
|
|||
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||
import com.tangem.domain.feedback.GetFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
||||
|
|
@ -94,8 +93,6 @@ interface ApplicationEntryPoint {
|
|||
|
||||
fun getCardRepository(): CardRepository
|
||||
|
||||
fun getFeedbackManagerFeatureToggles(): FeedbackManagerFeatureToggles
|
||||
|
||||
fun getTangemSdkLogger(): TangemSdkLogger
|
||||
|
||||
fun getSettingsRepository(): SettingsRepository
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
package com.tangem.tap
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||
import com.tangem.Log
|
||||
import com.tangem.LogFormat
|
||||
import com.tangem.TangemSdkLogger
|
||||
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
|
|
@ -30,7 +27,6 @@ import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
|||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||
import com.tangem.domain.feedback.GetFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
||||
|
|
@ -48,11 +44,9 @@ 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.AdditionalFeedbackInfo
|
||||
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.log.TangemLogCollector
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.appReducer
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
|
|
@ -153,9 +147,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
private val cardRepository: CardRepository
|
||||
get() = entryPoint.getCardRepository()
|
||||
|
||||
private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles
|
||||
get() = entryPoint.getFeedbackManagerFeatureToggles()
|
||||
|
||||
private val tangemSdkLogger: TangemSdkLogger
|
||||
get() = entryPoint.getTangemSdkLogger()
|
||||
|
||||
|
|
@ -260,7 +251,6 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
saveTwinsOnboardingShownUseCase = saveTwinsOnboardingShownUseCase,
|
||||
generateWalletNameUseCase = generateWalletNameUseCase,
|
||||
cardRepository = cardRepository,
|
||||
feedbackManagerFeatureToggles = feedbackManagerFeatureToggles,
|
||||
tangemSdkLogger = tangemSdkLogger,
|
||||
settingsRepository = settingsRepository,
|
||||
blockchainSDKFactory = blockchainSDKFactory,
|
||||
|
|
@ -298,7 +288,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
|
||||
private fun initWithConfigDependency(config: Config) {
|
||||
initAnalytics(this, config)
|
||||
initFeedbackManager(this, store)
|
||||
initFeedbackManager(store)
|
||||
}
|
||||
|
||||
private fun initAnalytics(application: Application, config: Config) {
|
||||
|
|
@ -319,50 +309,10 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
|
|||
// ExceptionHandler.append(blockchainExceptionHandler) TODO: [REDACTED_JIRA]
|
||||
}
|
||||
|
||||
private fun initFeedbackManager(context: Context, store: Store<AppState>) {
|
||||
fun initAdditionalFeedbackInfo(context: Context): AdditionalFeedbackInfo {
|
||||
return AdditionalFeedbackInfo().apply {
|
||||
appVersion = try {
|
||||
// TODO don't use deprecated method
|
||||
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
||||
pInfo.versionName
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
"x.y.z"
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun initFeedbackManager(store: Store<AppState>) {
|
||||
Log.addLogger(logger = tangemSdkLogger)
|
||||
|
||||
fun initTangemLogCollector(): TangemLogCollector {
|
||||
val logLevels = listOf(
|
||||
Log.Level.ApduCommand,
|
||||
Log.Level.Apdu,
|
||||
Log.Level.Tlv,
|
||||
Log.Level.Nfc,
|
||||
Log.Level.Command,
|
||||
Log.Level.Session,
|
||||
Log.Level.View,
|
||||
Log.Level.Network,
|
||||
Log.Level.Error,
|
||||
Log.Level.Biometric,
|
||||
Log.Level.Info,
|
||||
)
|
||||
return TangemLogCollector(logLevels, LogFormat.StairsFormatter())
|
||||
}
|
||||
|
||||
val additionalFeedbackInfo = initAdditionalFeedbackInfo(context)
|
||||
val tangemLogCollector = initTangemLogCollector()
|
||||
|
||||
Log.addLogger(
|
||||
logger = if (feedbackManagerFeatureToggles.isLocalLogsEnabled) tangemSdkLogger else tangemLogCollector,
|
||||
)
|
||||
|
||||
val feedbackManager = LegacyFeedbackManager(
|
||||
infoHolder = additionalFeedbackInfo,
|
||||
logCollector = tangemLogCollector,
|
||||
feedbackManagerFeatureToggles = feedbackManagerFeatureToggles,
|
||||
getFeedbackEmailUseCase = getFeedbackEmailUseCase,
|
||||
)
|
||||
val feedbackManager = LegacyFeedbackManager(getFeedbackEmailUseCase = getFeedbackEmailUseCase)
|
||||
store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
package com.tangem.tap.common.feedback
|
||||
|
||||
import android.os.Build
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.crypto.NetworkType
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
|
||||
import com.tangem.tap.common.extensions.stripZeroPlainString
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
class AdditionalFeedbackInfo {
|
||||
|
||||
class EmailWalletInfo(
|
||||
val blockchain: Blockchain = Blockchain.Unknown,
|
||||
val derivationPath: String = "",
|
||||
val outputsCount: String? = null,
|
||||
val host: String = "",
|
||||
val addresses: String = "",
|
||||
val explorerLink: String = "",
|
||||
val tokens: List<EmailTokenInfo> = emptyList(),
|
||||
)
|
||||
|
||||
class EmailTokenInfo(
|
||||
val id: String?,
|
||||
val name: String,
|
||||
val contractAddress: String,
|
||||
)
|
||||
|
||||
var appVersion: String = ""
|
||||
|
||||
// card
|
||||
var cardId: String = ""
|
||||
var cardFirmwareVersion: String = ""
|
||||
var cardIssuer: String = ""
|
||||
var cardBlockchain: String = ""
|
||||
var userWalletId: String = ""
|
||||
var extendedPublicKey: String = ""
|
||||
|
||||
// wallets
|
||||
val walletsInfo = CopyOnWriteArrayList<EmailWalletInfo>()
|
||||
var onSendErrorWalletInfo: EmailWalletInfo? = null
|
||||
private set
|
||||
var signedHashesCount: String = ""
|
||||
private set
|
||||
|
||||
// device
|
||||
var phoneModel: String = Build.MODEL
|
||||
private set
|
||||
var osVersion: String = Build.VERSION.SDK_INT.toString()
|
||||
private set
|
||||
|
||||
// send error
|
||||
var destinationAddress: String = ""
|
||||
private set
|
||||
var amount: String = ""
|
||||
private set
|
||||
var fee: String = ""
|
||||
private set
|
||||
var token: String = ""
|
||||
private set
|
||||
|
||||
private val Address.name: String
|
||||
get() = type.javaClass.simpleName
|
||||
|
||||
@Deprecated("Don't use it directly")
|
||||
fun setCardInfo(data: ScanResponse) {
|
||||
cardId = data.card.cardId
|
||||
cardBlockchain = data.walletData?.blockchain ?: ""
|
||||
cardFirmwareVersion = data.card.firmwareVersion.stringValue
|
||||
cardIssuer = data.card.issuer.name
|
||||
signedHashesCount = formatSignedHashes(data.card.wallets)
|
||||
userWalletId = UserWalletIdBuilder.scanResponse(data).build()?.stringValue ?: ""
|
||||
extendedPublicKey = runCatching {
|
||||
data.card.wallets.firstOrNull { it.extendedPublicKey != null }
|
||||
?.extendedPublicKey
|
||||
?.serialize(networkType = NetworkType.Mainnet).orEmpty()
|
||||
}.getOrDefault("couldn't retrieve extended public key")
|
||||
}
|
||||
|
||||
@Deprecated("Don't use it directly")
|
||||
fun setWalletsInfo(walletManagers: List<WalletManager>) {
|
||||
synchronized(walletsInfo) {
|
||||
walletsInfo.clear()
|
||||
walletsInfo.addAll(elements = walletManagers.map(::createEmailWalletInfo))
|
||||
}
|
||||
}
|
||||
|
||||
fun updateOnSendError(
|
||||
walletManager: WalletManager,
|
||||
amountToSend: Amount?,
|
||||
feeAmount: Amount?,
|
||||
destinationAddress: String?,
|
||||
) {
|
||||
onSendErrorWalletInfo = createEmailWalletInfo(walletManager)
|
||||
this.destinationAddress = destinationAddress ?: "0"
|
||||
amount = amountToSend?.value?.stripZeroPlainString() ?: "0"
|
||||
fee = if (feeAmount != null) {
|
||||
feeAmount.value?.stripZeroPlainString() ?: "0"
|
||||
} else {
|
||||
"Unable to receive"
|
||||
}
|
||||
token = if (amountToSend?.type is AmountType.Token) amountToSend.currencySymbol else ""
|
||||
}
|
||||
|
||||
private fun createEmailWalletInfo(walletManager: WalletManager): EmailWalletInfo {
|
||||
return EmailWalletInfo(
|
||||
blockchain = walletManager.wallet.blockchain,
|
||||
derivationPath = walletManager.wallet.publicKey.derivationPath?.rawPath ?: "",
|
||||
outputsCount = walletManager.outputsCount?.toString(),
|
||||
host = walletManager.currentHost,
|
||||
addresses = formatAddresses(walletManager.wallet),
|
||||
explorerLink = formatExploreUrls(walletManager.wallet),
|
||||
tokens = walletManager.cardTokens.map { token ->
|
||||
EmailTokenInfo(token.id, token.name, token.contractAddress)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun formatSignedHashes(wallets: List<CardDTO.Wallet>): String {
|
||||
return wallets.joinToString("\n") { "Signed hashes: ${it.curve.curve} - ${it.totalSignedHashes}" }
|
||||
}
|
||||
|
||||
private fun formatAddresses(wallet: Wallet): String {
|
||||
return wallet.formatAddressWith("Multiple address:") {
|
||||
"${it.name} - ${it.value}"
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatExploreUrls(wallet: Wallet): String {
|
||||
return wallet.formatAddressWith("Multiple explorers links:") {
|
||||
"${it.name} - ${wallet.getExploreUrl(it.value)}"
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun Wallet.formatAddressWith(with: String, mapAddress: (Address) -> String): String {
|
||||
return if (addresses.size == 1) {
|
||||
getExploreUrl(address)
|
||||
} else {
|
||||
addresses.map { mapAddress(it) }.toMutableList()
|
||||
.apply { add(0, with) }
|
||||
.joinToString("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
package com.tangem.tap.common.feedback
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
|
||||
internal class DefaultFeedbackManagerFeatureToggles(
|
||||
private val featureTogglesManager: FeatureTogglesManager,
|
||||
) : FeedbackManagerFeatureToggles {
|
||||
|
||||
override val isLocalLogsEnabled: Boolean
|
||||
get() = featureTogglesManager.isFeatureEnabled(name = "LOCAL_USER_LOGS_ENABLED")
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
package com.tangem.tap.common.feedback
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.domain.common.TapWorkarounds
|
||||
import com.tangem.tap.common.extensions.breakLine
|
||||
import com.tangem.wallet.R
|
||||
|
||||
interface FeedbackData {
|
||||
val subjectResId: Int
|
||||
val mainMessageResId: Int
|
||||
|
||||
fun getDataCollectionMessageResId(): Int = R.string.feedback_data_collection_message
|
||||
|
||||
fun prepare(infoHolder: AdditionalFeedbackInfo) {}
|
||||
|
||||
fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun joinTogether(context: Context, infoHolder: AdditionalFeedbackInfo): String {
|
||||
return StringBuilder().apply {
|
||||
append(context.getString(mainMessageResId))
|
||||
breakLine(3)
|
||||
append(context.getString(getDataCollectionMessageResId()))
|
||||
breakLine()
|
||||
append(createOptionalMessage(infoHolder))
|
||||
}.toString()
|
||||
}
|
||||
}
|
||||
|
||||
class RateCanBeBetterEmail : FeedbackData {
|
||||
override val subjectResId: Int = R.string.feedback_subject_rate_negative
|
||||
override val mainMessageResId: Int = R.string.feedback_preface_rate_negative
|
||||
|
||||
override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder)
|
||||
.appendCardInfo()
|
||||
.breakLine()
|
||||
.appendPhoneInfo()
|
||||
.build()
|
||||
}
|
||||
|
||||
class ScanFailsEmail : FeedbackData {
|
||||
|
||||
override val subjectResId: Int = R.string.feedback_subject_scan_failed
|
||||
override val mainMessageResId: Int = R.string.feedback_preface_scan_failed
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
override fun joinTogether(context: Context, infoHolder: AdditionalFeedbackInfo): String = StringBuilder().apply {
|
||||
append(context.getString(mainMessageResId))
|
||||
breakLine(4)
|
||||
append(createOptionalMessage(infoHolder))
|
||||
}.toString()
|
||||
|
||||
override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder)
|
||||
.appendPhoneInfo()
|
||||
.build()
|
||||
}
|
||||
|
||||
class SendTransactionFailedEmail(
|
||||
val error: String,
|
||||
) : FeedbackData {
|
||||
|
||||
override val subjectResId: Int = R.string.feedback_subject_tx_failed
|
||||
override val mainMessageResId: Int = R.string.feedback_preface_tx_failed
|
||||
|
||||
override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder)
|
||||
.appendCardInfo()
|
||||
.appendDelimiter()
|
||||
.appendTxFailedBlockchainInfo(error)
|
||||
.breakLine()
|
||||
.appendPhoneInfo()
|
||||
.build()
|
||||
}
|
||||
|
||||
class FeedbackEmail : FeedbackData {
|
||||
override val subjectResId: Int
|
||||
get() = if (isS2CCard) R.string.feedback_subject_support else R.string.feedback_subject_support_tangem
|
||||
|
||||
override val mainMessageResId: Int = R.string.feedback_preface_support
|
||||
|
||||
private var isS2CCard = false
|
||||
|
||||
override fun prepare(infoHolder: AdditionalFeedbackInfo) {
|
||||
isS2CCard = TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer)
|
||||
}
|
||||
|
||||
override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String = FeedbackDataBuilder(infoHolder)
|
||||
.appendCardInfo()
|
||||
.appendWalletsInfo()
|
||||
.breakLine()
|
||||
.appendPhoneInfo()
|
||||
.build()
|
||||
}
|
||||
|
||||
class SupportInfo : FeedbackData {
|
||||
override val subjectResId: Int = R.string.details_chat
|
||||
override val mainMessageResId: Int = R.string.details_chat
|
||||
|
||||
override fun createOptionalMessage(infoHolder: AdditionalFeedbackInfo): String {
|
||||
return FeedbackDataBuilder(infoHolder)
|
||||
.appendCardInfo()
|
||||
.appendDelimiter()
|
||||
.appendPhoneInfo()
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
package com.tangem.tap.common.feedback
|
||||
|
||||
import com.tangem.tap.common.extensions.breakLine
|
||||
|
||||
class FeedbackDataBuilder(
|
||||
private val infoHolder: AdditionalFeedbackInfo,
|
||||
) {
|
||||
val builder = StringBuilder()
|
||||
|
||||
fun appendDelimiter(): FeedbackDataBuilder {
|
||||
builder.appendDelimiter()
|
||||
return this
|
||||
}
|
||||
|
||||
fun breakLine(count: Int = 1): FeedbackDataBuilder {
|
||||
builder.breakLine(count)
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendCardInfo(): FeedbackDataBuilder {
|
||||
builder.appendKeyValue("Card ID", infoHolder.cardId)
|
||||
builder.appendKeyValue("Firmware version", infoHolder.cardFirmwareVersion)
|
||||
builder.appendKeyValue("Card Blockchain", infoHolder.cardBlockchain)
|
||||
builder.appendKeyValue("", infoHolder.signedHashesCount)
|
||||
builder.appendKeyValue("User Wallet ID", infoHolder.userWalletId)
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendWalletsInfo(): FeedbackDataBuilder {
|
||||
infoHolder.walletsInfo.forEach { walletInfo ->
|
||||
builder.appendDelimiter()
|
||||
builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
|
||||
builder.appendKeyValue("Derivation path", walletInfo.derivationPath)
|
||||
builder.appendKeyValue("Outputs count", walletInfo.outputsCount)
|
||||
|
||||
if (walletInfo.tokens.isNotEmpty()) {
|
||||
builder.append("Tokens:")
|
||||
breakLine()
|
||||
walletInfo.tokens.forEach { token ->
|
||||
builder.appendKeyValue("ID", token.id ?: "[custom token]")
|
||||
builder.appendKeyValue("Name", token.name)
|
||||
builder.appendKeyValue("Contract address", token.contractAddress)
|
||||
}
|
||||
}
|
||||
|
||||
builder.appendKeyValue("Host", walletInfo.host)
|
||||
builder.appendKeyValue("Wallet address", walletInfo.addresses)
|
||||
builder.appendKeyValue("Explorer link", walletInfo.explorerLink)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendTxFailedBlockchainInfo(error: String): FeedbackDataBuilder {
|
||||
val walletInfo = infoHolder.onSendErrorWalletInfo ?: AdditionalFeedbackInfo.EmailWalletInfo()
|
||||
builder.appendKeyValue("Blockchain", walletInfo.blockchain.fullName)
|
||||
builder.appendKeyValue("Derivation path", walletInfo.derivationPath)
|
||||
builder.appendKeyValue("Host", walletInfo.host)
|
||||
builder.appendKeyValue("Token", infoHolder.token)
|
||||
builder.appendKeyValue("Error", error)
|
||||
builder.appendDelimiter()
|
||||
builder.appendKeyValue("Source address", walletInfo.addresses)
|
||||
builder.appendKeyValue("Destination address", infoHolder.destinationAddress)
|
||||
builder.appendKeyValue("Amount", infoHolder.amount)
|
||||
builder.appendKeyValue("Fee", infoHolder.fee)
|
||||
return this
|
||||
}
|
||||
|
||||
fun appendPhoneInfo(): FeedbackDataBuilder {
|
||||
builder.appendKeyValue("Phone model", infoHolder.phoneModel)
|
||||
builder.appendKeyValue("OS version", infoHolder.osVersion)
|
||||
builder.appendKeyValue("App version", infoHolder.appVersion)
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): String = builder.toString()
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendKeyValue(key: String, value: String?): StringBuilder = when {
|
||||
value.isNullOrBlank() -> this
|
||||
key.isBlank() -> this.append("$value\n")
|
||||
else -> this.append("$key: $value\n")
|
||||
}
|
||||
|
||||
private fun StringBuilder.appendDelimiter(): StringBuilder = append("----------\n")
|
||||
|
|
@ -1,84 +1,23 @@
|
|||
package com.tangem.tap.common.feedback
|
||||
|
||||
import android.content.Context
|
||||
import com.tangem.core.navigation.email.EmailSender
|
||||
import com.tangem.domain.common.TapWorkarounds
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.domain.feedback.GetFeedbackEmailUseCase
|
||||
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.common.extensions.sendEmail
|
||||
import com.tangem.tap.common.log.TangemLogCollector
|
||||
import com.tangem.tap.foregroundActivityObserver
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.withForegroundActivity
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.io.StringWriter
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class LegacyFeedbackManager(
|
||||
val infoHolder: AdditionalFeedbackInfo,
|
||||
private val logCollector: TangemLogCollector,
|
||||
private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles,
|
||||
private val getFeedbackEmailUseCase: GetFeedbackEmailUseCase,
|
||||
) {
|
||||
|
||||
private var sessionLogsFile: File? = null
|
||||
|
||||
fun sendEmail(feedbackData: FeedbackData, scanResponse: ScanResponse?) {
|
||||
if (feedbackManagerFeatureToggles.isLocalLogsEnabled) {
|
||||
scope.launch {
|
||||
val getCardInfo = suspend {
|
||||
scanResponse ?: error("ScanResponse must be not null")
|
||||
store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull()
|
||||
?: error("CardInfo must be not null")
|
||||
}
|
||||
|
||||
val email = getFeedbackEmailUseCase(
|
||||
type = when (feedbackData) {
|
||||
is FeedbackEmail -> FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo())
|
||||
is RateCanBeBetterEmail -> FeedbackEmailType.RateCanBeBetter(cardInfo = getCardInfo())
|
||||
is ScanFailsEmail -> FeedbackEmailType.ScanningProblem
|
||||
is SendTransactionFailedEmail -> {
|
||||
FeedbackEmailType.TransactionSendingProblem(cardInfo = getCardInfo())
|
||||
}
|
||||
else -> FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo())
|
||||
},
|
||||
)
|
||||
|
||||
store.inject(DaggerGraphState::emailSender).send(
|
||||
email = EmailSender.Email(
|
||||
address = email.address,
|
||||
subject = email.subject,
|
||||
message = email.message,
|
||||
attachment = email.file,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
feedbackData.prepare(infoHolder)
|
||||
foregroundActivityObserver.withForegroundActivity { activity ->
|
||||
activity.sendEmail(
|
||||
email = getSupportEmail(),
|
||||
subject = activity.getString(feedbackData.subjectResId),
|
||||
message = feedbackData.joinTogether(activity, infoHolder),
|
||||
file = getLogFile(activity),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
fun sendEmail(type: FeedbackEmailType) {
|
||||
if (!feedbackManagerFeatureToggles.isLocalLogsEnabled) error("LOCAL_LOGS feature toggle must be enabled")
|
||||
|
||||
scope.launch {
|
||||
val email = getFeedbackEmailUseCase(type = type)
|
||||
|
||||
|
|
@ -92,45 +31,4 @@ class LegacyFeedbackManager(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLogFile(context: Context): File? {
|
||||
return try {
|
||||
if (sessionLogsFile != null) {
|
||||
return sessionLogsFile
|
||||
}
|
||||
val file = File(context.filesDir, LOGS_FILE)
|
||||
file.delete()
|
||||
file.createNewFile()
|
||||
|
||||
val stringWriter = StringWriter()
|
||||
logCollector.getLogs().forEach { stringWriter.append(it) }
|
||||
val fileWriter = FileWriter(file)
|
||||
fileWriter.write(stringWriter.toString())
|
||||
fileWriter.close()
|
||||
logCollector.clearLogs()
|
||||
if (file.exists()) {
|
||||
sessionLogsFile = file
|
||||
sessionLogsFile
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex, "Can't create the logs file")
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSupportEmail(): String {
|
||||
return if (TapWorkarounds.isStart2CoinIssuer(infoHolder.cardIssuer)) {
|
||||
S2C_SUPPORT_EMAIL
|
||||
} else {
|
||||
DEFAULT_SUPPORT_EMAIL
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DEFAULT_SUPPORT_EMAIL = "support@tangem.com"
|
||||
const val S2C_SUPPORT_EMAIL = "cardsupport@start2coin.com"
|
||||
const val LOGS_FILE = "logs.txt"
|
||||
}
|
||||
}
|
||||
|
|
@ -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.FeedbackData
|
||||
import com.tangem.tap.common.feedback.LegacyFeedbackManager
|
||||
import com.tangem.tap.common.redux.DebugErrorAction
|
||||
import com.tangem.tap.common.redux.ErrorAction
|
||||
|
|
@ -72,8 +71,6 @@ sealed class GlobalAction : Action {
|
|||
data class SetConfigManager(val configManager: ConfigManager) : GlobalAction()
|
||||
data class SetFeedbackManager(val feedbackManager: LegacyFeedbackManager) : GlobalAction()
|
||||
|
||||
data class SendEmail(val feedbackData: FeedbackData, val scanResponse: ScanResponse?) : GlobalAction()
|
||||
|
||||
object ExchangeManager : GlobalAction() {
|
||||
object Init : GlobalAction() {
|
||||
data class Success(
|
||||
|
|
|
|||
|
|
@ -55,12 +55,6 @@ private fun handleAction(action: Action, appState: () -> AppState?) {
|
|||
is GlobalAction.RestoreAppCurrency -> {
|
||||
restoreAppCurrency()
|
||||
}
|
||||
is GlobalAction.SendEmail -> {
|
||||
store.state.globalState.feedbackManager?.sendEmail(
|
||||
feedbackData = action.feedbackData,
|
||||
scanResponse = action.scanResponse,
|
||||
)
|
||||
}
|
||||
is GlobalAction.ExchangeManager.Init -> {
|
||||
val appStateSafe = appState() ?: return
|
||||
val config = appStateSafe.globalState.configManager?.config ?: return
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@ 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.extensions.stripZeroPlainString
|
||||
import com.tangem.tap.common.feedback.FeedbackEmail
|
||||
import com.tangem.tap.common.feedback.RateCanBeBetterEmail
|
||||
import com.tangem.tap.common.feedback.SendTransactionFailedEmail
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
|
|
@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
|||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
internal object LegacyMiddleware {
|
||||
|
|
@ -33,68 +32,49 @@ internal object LegacyMiddleware {
|
|||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is LegacyAction.StartOnboardingProcess -> {
|
||||
store.dispatch(
|
||||
GlobalAction.Onboarding.Start(
|
||||
scanResponse = action.scanResponse,
|
||||
canSkipBackup = action.canSkipBackup,
|
||||
),
|
||||
)
|
||||
}
|
||||
is LegacyAction.SendEmailRateCanBeBetter -> {
|
||||
store.state.globalState.feedbackManager?.sendEmail(
|
||||
feedbackData = RateCanBeBetterEmail(),
|
||||
scanResponse = action.scanResponse,
|
||||
type = FeedbackEmailType.RateCanBeBetter(cardInfo = getCardInfo(action.scanResponse)),
|
||||
)
|
||||
}
|
||||
is LegacyAction.SendEmailSupport -> {
|
||||
store.state.globalState.feedbackManager?.sendEmail(
|
||||
feedbackData = FeedbackEmail(),
|
||||
scanResponse = action.scanResponse,
|
||||
)
|
||||
}
|
||||
is LegacyAction.StartOnboardingProcess -> {
|
||||
store.dispatch(
|
||||
GlobalAction.Onboarding.Start(action.scanResponse, canSkipBackup = action.canSkipBackup),
|
||||
type = FeedbackEmailType.DirectUserRequest(cardInfo = getCardInfo(action.scanResponse)),
|
||||
)
|
||||
}
|
||||
is LegacyAction.SendEmailTransactionFailed -> {
|
||||
if (store.inject(DaggerGraphState::feedbackManagerFeatureToggles).isLocalLogsEnabled) {
|
||||
val amount = action.amount?.convertToSdkAmount(action.cryptoCurrency)
|
||||
|
||||
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.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(
|
||||
feedbackData = SendTransactionFailedEmail(action.errorMessage),
|
||||
scanResponse = action.scanResponse,
|
||||
)
|
||||
} else {
|
||||
scope.launch {
|
||||
store.inject(DaggerGraphState::walletManagersFacade)
|
||||
.getOrCreateWalletManager(
|
||||
userWalletId = action.userWalletId,
|
||||
network = action.cryptoCurrency.network,
|
||||
)?.let { walletManager ->
|
||||
store.state.globalState.feedbackManager?.infoHolder?.updateOnSendError(
|
||||
walletManager = walletManager,
|
||||
amountToSend = action.amount?.convertToSdkAmount(action.cryptoCurrency),
|
||||
feeAmount = action.fee?.convertToSdkAmount(action.cryptoCurrency),
|
||||
destinationAddress = action.destinationAddress,
|
||||
)
|
||||
}
|
||||
store.state.globalState.feedbackManager?.sendEmail(
|
||||
feedbackData = SendTransactionFailedEmail(action.errorMessage),
|
||||
scanResponse = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
store.state.globalState.feedbackManager?.sendEmail(
|
||||
type = FeedbackEmailType.TransactionSendingProblem(
|
||||
cardInfo = getCardInfo(action.scanResponse),
|
||||
),
|
||||
)
|
||||
}
|
||||
is LegacyAction.PrepareDetailsScreen -> {
|
||||
val userWalletsListManager = store.inject(DaggerGraphState::generalUserWalletsListManager)
|
||||
|
|
@ -119,4 +99,10 @@ internal object LegacyMiddleware {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCardInfo(scanResponse: ScanResponse): CardInfo {
|
||||
return store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse)
|
||||
.getOrNull()
|
||||
?: error("Card info not found")
|
||||
}
|
||||
}
|
||||
|
|
@ -8,12 +8,11 @@ import androidx.core.view.isVisible
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
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.feedback.ScanFailsEmail
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.home.LocaleRegionProvider
|
||||
import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -65,7 +64,8 @@ internal object ScanFailsDialog {
|
|||
}
|
||||
customView.findViewById<TextView>(R.id.request_support_button)?.setOnClickListener {
|
||||
Analytics.send(Basic.ButtonSupport(sourceAnalytics))
|
||||
store.dispatch(GlobalAction.SendEmail(feedbackData = ScanFailsEmail(), scanResponse = null))
|
||||
|
||||
store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.ScanningProblem)
|
||||
}
|
||||
customView.findViewById<TextView>(R.id.cancel_button)?.setOnClickListener {
|
||||
store.dispatchDialogHide()
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.core.featuretoggle.manager.FeatureTogglesManager
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.tap.common.feedback.DefaultFeedbackManagerFeatureToggles
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object FeedbackManagerFeatureTogglesModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFeedbackManagerFeatureToggles(
|
||||
featureTogglesManager: FeatureTogglesManager,
|
||||
): FeedbackManagerFeatureToggles {
|
||||
return DefaultFeedbackManagerFeatureToggles(featureTogglesManager)
|
||||
}
|
||||
}
|
||||
|
|
@ -10,11 +10,9 @@ import com.tangem.domain.common.util.cardTypesResolver
|
|||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.operations.attestation.Attestation
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
import com.tangem.utils.coroutines.AppCoroutineDispatcherProvider
|
||||
|
|
@ -52,11 +50,6 @@ class TapWalletManager(
|
|||
|
||||
tangemSdkManager.changeDisplayedCardIdNumbersCount(scanResponse)
|
||||
|
||||
val featureToggles = store.inject(DaggerGraphState::feedbackManagerFeatureToggles)
|
||||
if (!featureToggles.isLocalLogsEnabled) {
|
||||
store.state.globalState.feedbackManager?.infoHolder?.setCardInfo(scanResponse)
|
||||
}
|
||||
|
||||
updateConfigManager(scanResponse)
|
||||
withMainContext {
|
||||
// Order is important
|
||||
|
|
|
|||
|
|
@ -13,18 +13,15 @@ import com.tangem.domain.balancehiding.BalanceHidingSettings
|
|||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.balancehiding.ListenToFlipsUseCase
|
||||
import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.domain.settings.DeleteDeprecatedLogsUseCase
|
||||
import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
|
||||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
import com.tangem.tap.features.home.featuretoggles.HomeFeatureToggles
|
||||
import com.tangem.tap.features.main.model.MainScreenState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
|
@ -43,13 +40,11 @@ internal class MainViewModel @Inject constructor(
|
|||
private val incrementAppLaunchCounterUseCase: IncrementAppLaunchCounterUseCase,
|
||||
private val blockchainSDKFactory: BlockchainSDKFactory,
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
stakingFeatureToggles: StakingFeatureToggles,
|
||||
private val fetchStakingTokensUseCase: FetchStakingTokensUseCase,
|
||||
private val apiConfigsManager: ApiConfigsManager,
|
||||
private val homeFeatureToggles: HomeFeatureToggles,
|
||||
homeFeatureToggles: HomeFeatureToggles,
|
||||
private val fetchUserCountryUseCase: FetchUserCountryUseCase,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
) : ViewModel(), MainIntents {
|
||||
|
|
@ -109,19 +104,6 @@ internal class MainViewModel @Inject constructor(
|
|||
.onEach { userWallet ->
|
||||
Analytics.setContext(userWallet.scanResponse)
|
||||
Analytics.send(Basic.WalletOpened())
|
||||
|
||||
if (!feedbackManagerFeatureToggles.isLocalLogsEnabled) {
|
||||
store.state.globalState.feedbackManager?.infoHolder?.let { infoHolder ->
|
||||
infoHolder.setCardInfo(userWallet.scanResponse)
|
||||
|
||||
walletManagersFacade
|
||||
.getAll(userWallet.walletId)
|
||||
.distinctUntilChanged()
|
||||
.onEach(infoHolder::setWalletsInfo)
|
||||
.catch { Timber.e(it) }
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(viewModelScope)
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ import androidx.core.view.MenuProvider
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.tap.common.feedback.SupportInfo
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.extensions.inject
|
||||
import com.tangem.tap.proxy.redux.DaggerGraphState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -28,13 +29,12 @@ class OnboardingMenuProvider(
|
|||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
||||
R.id.menu_item_chat_support -> {
|
||||
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
|
||||
// changed on email support [REDACTED_TASK_KEY]
|
||||
store.dispatch(
|
||||
GlobalAction.SendEmail(
|
||||
feedbackData = SupportInfo(),
|
||||
scanResponse = scanResponseProvider(),
|
||||
),
|
||||
)
|
||||
|
||||
val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponseProvider()).getOrNull()
|
||||
?: error("CardInfo must be not null")
|
||||
|
||||
store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo))
|
||||
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import com.tangem.core.analytics.models.Basic
|
|||
import com.tangem.core.ui.extensions.setStatusBarColor
|
||||
import com.tangem.datasource.utils.isNullOrEmpty
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.feature.onboarding.data.model.CreateWalletResponse
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseMediator
|
||||
|
|
@ -37,8 +38,6 @@ import com.tangem.sdk.ui.widget.leapfrogWidget.LeapfrogWidget
|
|||
import com.tangem.sdk.ui.widget.leapfrogWidget.PropertyCalculator
|
||||
import com.tangem.tap.common.analytics.events.Onboarding
|
||||
import com.tangem.tap.common.extensions.*
|
||||
import com.tangem.tap.common.feedback.SupportInfo
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.features.BaseFragment
|
||||
import com.tangem.tap.features.FragmentOnBackPressedHandler
|
||||
import com.tangem.tap.features.addBackPressHandler
|
||||
|
|
@ -46,6 +45,7 @@ import com.tangem.tap.features.onboarding.OnboardingMenuProvider
|
|||
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.store
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -510,14 +510,13 @@ class OnboardingWalletFragment :
|
|||
onBack = ::legacyOnBackHandler,
|
||||
onOpenChat = {
|
||||
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
|
||||
// changed on email support [REDACTED_TASK_KEY]
|
||||
store.dispatch(
|
||||
GlobalAction.SendEmail(
|
||||
feedbackData = SupportInfo(),
|
||||
scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
?: error("ScanResponse must be not null"),
|
||||
),
|
||||
)
|
||||
|
||||
val scanResponse = requireNotNull(store.state.globalState.onboardingState.onboardingManager?.scanResponse)
|
||||
|
||||
val getCardInfoUseCase = store.inject(DaggerGraphState::getCardInfoUseCase)
|
||||
val cardInfo = requireNotNull(getCardInfoUseCase.invoke(scanResponse).getOrNull())
|
||||
|
||||
store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo))
|
||||
},
|
||||
onOpenUriClick = { uri ->
|
||||
store.dispatchOpenUrl(uri.toString())
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.tap.common.extensions.dispatchDialogHide
|
||||
import com.tangem.tap.common.feedback.SupportInfo
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
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.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
|
|
@ -23,13 +24,14 @@ object WalletActivationErrorDialog {
|
|||
setNegativeButton(R.string.common_support) { _, _ ->
|
||||
// changed on email support [REDACTED_TASK_KEY]
|
||||
Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro))
|
||||
store.dispatch(
|
||||
GlobalAction.SendEmail(
|
||||
feedbackData = SupportInfo(),
|
||||
scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
?: error("ScanResponse must be not null"),
|
||||
),
|
||||
)
|
||||
|
||||
val scanResponse = store.state.globalState.onboardingState.onboardingManager?.scanResponse
|
||||
?: error("ScanResponse must be not null")
|
||||
|
||||
val cardInfo = store.inject(DaggerGraphState::getCardInfoUseCase).invoke(scanResponse).getOrNull()
|
||||
?: error("CardInfo must be not null")
|
||||
|
||||
store.state.globalState.feedbackManager?.sendEmail(type = FeedbackEmailType.DirectUserRequest(cardInfo))
|
||||
}
|
||||
setOnDismissListener { store.dispatchDialogHide() }
|
||||
setCancelable(false)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import com.tangem.domain.card.ScanCardProcessor
|
|||
import com.tangem.domain.card.ScanCardUseCase
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.card.repository.CardSdkConfigRepository
|
||||
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
|
||||
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||
import com.tangem.domain.feedback.GetFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.SaveBlockchainErrorUseCase
|
||||
|
|
@ -71,7 +70,6 @@ data class DaggerGraphState(
|
|||
val saveTwinsOnboardingShownUseCase: SaveTwinsOnboardingShownUseCase? = null,
|
||||
val generateWalletNameUseCase: GenerateWalletNameUseCase? = null,
|
||||
val cardRepository: CardRepository? = null,
|
||||
val feedbackManagerFeatureToggles: FeedbackManagerFeatureToggles? = null,
|
||||
val tangemSdkLogger: TangemSdkLogger? = null,
|
||||
val settingsRepository: SettingsRepository? = null,
|
||||
val blockchainSDKFactory: BlockchainSDKFactory? = null,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue