Updated on 2026-08-14
This commit is contained in:
parent
228c0c8af4
commit
82fa3edf45
18 changed files with 97 additions and 61 deletions
|
|
@ -1,20 +1,15 @@
|
|||
package com.tangem.common
|
||||
|
||||
import com.tangem.utils.SupportedLanguages
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
object TangemBlogUrlBuilder {
|
||||
|
||||
fun build(post: Post): String {
|
||||
val code = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
.takeIf { code ->
|
||||
code == SupportedLanguages.RUSSIAN || code == SupportedLanguages.ENGLISH
|
||||
}
|
||||
?: SupportedLanguages.ENGLISH
|
||||
|
||||
return "https://tangem.com/$code/blog/post/${post.path}/"
|
||||
suspend fun build(post: Post): String {
|
||||
return TangemSiteUrlBuilder.url(
|
||||
path = "/blog/post/${post.path}/",
|
||||
campaign = "articles",
|
||||
)
|
||||
}
|
||||
|
||||
sealed interface Post {
|
||||
|
|
@ -28,5 +23,13 @@ object TangemBlogUrlBuilder {
|
|||
data object SeedNotifySecond : Post {
|
||||
override val path: String = "tangem-resolves-log-issue"
|
||||
}
|
||||
|
||||
data object SeedPhraseRiskySolution : Post {
|
||||
override val path: String = "seed-phrase-a-risky-solution"
|
||||
}
|
||||
|
||||
data object WhatWalletToChoose : Post {
|
||||
override val path: String = "mobile-wallet"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.common
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import java.util.Locale
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
object TangemSiteUrlBuilder {
|
||||
|
||||
suspend fun getUtmTags(campaign: String?): String {
|
||||
val langCode = Locale.getDefault().language
|
||||
val utmCampaignPart = campaign?.let { "&utm_campaign=$it-$langCode" }.orEmpty()
|
||||
val utmContent = deviceLang()?.let { "&utm_content=devicelang-$it" }.orEmpty()
|
||||
val appInstanceIdPart = getAppInstanceId()?.let { "&app_instance_id=$it" }.orEmpty()
|
||||
return "utm_source=tangem-app&utm_medium=app$utmCampaignPart$utmContent$appInstanceIdPart"
|
||||
}
|
||||
|
||||
suspend fun url(path: String, campaign: String): String {
|
||||
val normalizedPath = path.trim('/')
|
||||
return "https://tangem.com/$normalizedPath?${getUtmTags(campaign)}"
|
||||
}
|
||||
|
||||
private fun deviceLang(): String? {
|
||||
return runCatching {
|
||||
Resources.getSystem().configuration.locales.get(0).toLanguageTag()
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
private suspend fun getAppInstanceId(): String? {
|
||||
return suspendCoroutine { cont ->
|
||||
Firebase.analytics.appInstanceId
|
||||
.addOnSuccessListener { id ->
|
||||
cont.resume(id)
|
||||
}
|
||||
.addOnFailureListener {
|
||||
cont.resume(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ object SupportedLanguages {
|
|||
const val ITALIAN = "it"
|
||||
const val JAPANESE = "ja"
|
||||
const val UKRAINIAN = "uk"
|
||||
const val CHINESE = "uk"
|
||||
const val CHINESE = "zh"
|
||||
const val SPANISH = "es"
|
||||
|
||||
val supportedLangugeCodes = listOf(
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.utils
|
|||
|
||||
import java.util.Locale
|
||||
|
||||
@Deprecated("Use TangemBlogUrlBuilder from common module")
|
||||
object TangemBlogUrlBuilder {
|
||||
|
||||
private const val RU_LOCALE = "ru"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ dependencies {
|
|||
implementation(projects.domain.hotWallet)
|
||||
// endregion
|
||||
|
||||
implementation(projects.common)
|
||||
|
||||
// region Tangem libraries
|
||||
implementation(tangemDeps.blockchain) // android-library
|
||||
implementation(tangemDeps.card.core)
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import com.tangem.common.TangemSiteUrlBuilder
|
||||
import java.util.Locale
|
||||
|
||||
class GenerateBuyTangemCardLinkUseCase {
|
||||
|
||||
suspend operator fun invoke(): String = suspendCoroutine { cont ->
|
||||
Firebase.analytics.appInstanceId
|
||||
.addOnSuccessListener { id ->
|
||||
cont.resume("$NEW_BUY_WALLET_URL&app_instance_id=$id")
|
||||
}
|
||||
.addOnFailureListener {
|
||||
cont.resume(NEW_BUY_WALLET_URL)
|
||||
}
|
||||
suspend operator fun invoke(source: Source): String {
|
||||
return invoke(source.utmCampaign)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val NEW_BUY_WALLET_URL = "https://buy.tangem.com/?utm_source=tangem-app&utm_medium=app"
|
||||
suspend operator fun invoke(utmCampaign: String?): String {
|
||||
val langCode = Locale.getDefault().language
|
||||
val utmTags = TangemSiteUrlBuilder.getUtmTags(utmCampaign)
|
||||
return "https://buy.tangem.com/$langCode?$utmTags"
|
||||
}
|
||||
|
||||
enum class Source(val utmCampaign: String) {
|
||||
Creation("prospect"),
|
||||
Settings("users"),
|
||||
Backup("backup"),
|
||||
Upgrade("upgrade"),
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +162,8 @@ internal class CreateWalletStartModel @Inject constructor(
|
|||
private fun onBuyClick() {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.CreateWalletIntro))
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Creation).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -232,8 +232,10 @@ internal class DetailsModel @Inject constructor(
|
|||
modelScope.launch {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Settings))
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Settings).let { urlOpener.openUrl(it) }
|
||||
} else {
|
||||
// This is incorrect implementation of buy link generation, but it is left here
|
||||
urlOpener.openUrl(buildBuyLink())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ internal class HomeModel @Inject constructor(
|
|||
analyticsEventHandler.send(IntroductionProcess.ButtonBuyCards())
|
||||
analyticsEventHandler.send(Shop.ScreenOpened())
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase.invoke(null).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ internal class CreateHardwareWalletModel @Inject constructor(
|
|||
private fun onBuyTangemWalletClick() {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.CreateWallet))
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Upgrade).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,8 @@ internal class UpgradeWalletModel @Inject constructor(
|
|||
private fun onBuyTangemWalletClick() {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Upgrade))
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Upgrade).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,8 @@ internal class WalletBackupModel @Inject constructor(
|
|||
private fun onBuyClick() {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Backup))
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,8 @@ internal class WalletHardwareBackupModel @Inject constructor(
|
|||
private fun onBuyClick() {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.HardwareWallet))
|
||||
modelScope.launch {
|
||||
generateBuyTangemCardLinkUseCase.invoke().let { urlOpener.openUrl(it) }
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Backup).let { urlOpener.openUrl(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ dependencies {
|
|||
/** Common */
|
||||
implementation(projects.common.ui)
|
||||
implementation(projects.common.routing)
|
||||
implementation(projects.common)
|
||||
|
||||
/** Domain */
|
||||
implementation(projects.domain.models)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.mode
|
|||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.TangemBlogUrlBuilder
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
|
|
@ -161,7 +162,11 @@ internal class MultiWalletSeedPhraseModel @Inject constructor(
|
|||
openGeneratedSeedPhrase()
|
||||
},
|
||||
onLearnMoreClicked = {
|
||||
urlOpener.openUrl(seedPhraseLearnMoreUrl())
|
||||
modelScope.launch {
|
||||
urlOpener.openUrl(
|
||||
TangemBlogUrlBuilder.build(TangemBlogUrlBuilder.Post.SeedPhraseRiskySolution),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model
|
||||
|
||||
import android.net.Uri
|
||||
import com.tangem.utils.SupportedLanguages
|
||||
import java.util.Locale
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
internal fun seedPhraseLearnMoreUrl(): String {
|
||||
val language = Locale.getDefault().language
|
||||
|
||||
val languageBy = "by"
|
||||
if (SupportedLanguages.RUSSIAN.equals(language, true) ||
|
||||
languageBy.equals(language, true)
|
||||
) {
|
||||
SupportedLanguages.RUSSIAN
|
||||
} else {
|
||||
SupportedLanguages.ENGLISH
|
||||
}
|
||||
|
||||
val webUri = Uri.Builder()
|
||||
.scheme("https")
|
||||
.authority("tangem.com")
|
||||
.appendPath(language)
|
||||
.appendPath("blog/post/seed-phrase-a-risky-solution")
|
||||
.build()
|
||||
|
||||
return webUri.toString()
|
||||
}
|
||||
|
|
@ -1194,6 +1194,7 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
@Deprecated("Use TangemBlockUrlBuilder instead")
|
||||
private fun buildReadMoreUrl(): String {
|
||||
return buildString {
|
||||
append(FEE_READ_MORE_URL_FIRST_PART)
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ internal class WcSendTransactionModel @Inject constructor(
|
|||
stackNavigation.pop()
|
||||
}
|
||||
|
||||
@Deprecated("Use TangemBlockUrlBuilder instead")
|
||||
private fun onApproveLearnMoreClick() {
|
||||
val code = SupportedLanguages.getCurrentSupportedLanguageCode()
|
||||
.takeIf { it == SupportedLanguages.RUSSIAN }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue