Updated on 2026-08-14
This commit is contained in:
commit
d243f6f01b
33 changed files with 236 additions and 56 deletions
|
|
@ -10,6 +10,7 @@ import com.tangem.Log
|
|||
import com.tangem.LogFormat
|
||||
import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder
|
||||
import com.tangem.domain.DomainLayer
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.network.common.MoshiConverter
|
||||
import com.tangem.tap.common.AndroidAssetReader
|
||||
import com.tangem.tap.common.AssetReader
|
||||
|
|
@ -39,7 +40,7 @@ val store = Store(
|
|||
middleware = AppState.getMiddleware(),
|
||||
state = AppState(),
|
||||
)
|
||||
val logConfig = LogConfig()
|
||||
|
||||
lateinit var foregroundActivityObserver: ForegroundActivityObserver
|
||||
lateinit var preferencesStorage: PreferencesStorage
|
||||
lateinit var walletConnectRepository: WalletConnectRepository
|
||||
|
|
@ -48,6 +49,7 @@ lateinit var assetReader: AssetReader
|
|||
lateinit var userTokensRepository: UserTokensRepository
|
||||
|
||||
class TapApplication : Application(), ImageLoaderFactory {
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
|
|
@ -68,7 +70,7 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
initConfigManager(configLoader, ::initWithConfigDependency)
|
||||
initWarningMessagesManager()
|
||||
|
||||
BlockchainSdkRetrofitBuilder.enableNetworkLogging = BuildConfig.DEBUG
|
||||
BlockchainSdkRetrofitBuilder.enableNetworkLogging = LogConfig.network.blockchainSdkNetwork
|
||||
|
||||
userTokensRepository = UserTokensRepository.init(
|
||||
context = this,
|
||||
|
|
@ -77,7 +79,10 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
}
|
||||
|
||||
override fun newImageLoader(): ImageLoader {
|
||||
return createCoilImageLoader(context = this)
|
||||
return createCoilImageLoader(
|
||||
context = this,
|
||||
logEnabled = LogConfig.imageLoader
|
||||
)
|
||||
}
|
||||
|
||||
private fun initConfigManager(loader: FeaturesLocalLoader, onComplete: (Config) -> Unit) {
|
||||
|
|
@ -135,6 +140,7 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
infoHolder = additionalFeedbackInfo,
|
||||
logCollector = tangemLogCollector,
|
||||
preferencesStorage = preferencesStorage,
|
||||
logEnabled = LogConfig.zendesk,
|
||||
)
|
||||
feedbackManager.initChat(
|
||||
context = context,
|
||||
|
|
@ -146,10 +152,4 @@ class TapApplication : Application(), ImageLoaderFactory {
|
|||
private fun initWarningMessagesManager() {
|
||||
store.dispatch(GlobalAction.SetWarningManager(WarningMessagesManager()))
|
||||
}
|
||||
}
|
||||
|
||||
data class LogConfig(
|
||||
val coil: Boolean = BuildConfig.DEBUG,
|
||||
val storeAction: Boolean = BuildConfig.DEBUG,
|
||||
val zendesk: Boolean = BuildConfig.DEBUG,
|
||||
)
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@ fun Blockchain.getRoundIconRes(): Int {
|
|||
Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_round
|
||||
Blockchain.Gnosis -> R.drawable.ic_gnosis_round
|
||||
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_round
|
||||
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism
|
||||
Blockchain.Dash -> R.drawable.ic_dash
|
||||
else -> R.drawable.ic_tangem_logo
|
||||
}
|
||||
}
|
||||
|
|
@ -57,6 +59,8 @@ fun Blockchain.getGreyedOutIconRes(): Int {
|
|||
Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_no_color
|
||||
Blockchain.Gnosis -> R.drawable.ic_gnosis_no_color
|
||||
Blockchain.Polkadot, Blockchain.PolkadotTestnet -> R.drawable.ic_polkadot_no_color
|
||||
Blockchain.Optimism, Blockchain.OptimismTestnet -> R.drawable.ic_optimism_no_color
|
||||
Blockchain.Dash -> R.drawable.ic_dash_no_color
|
||||
else -> R.drawable.ic_tangem_logo
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
package com.tangem.tap.common.extensions
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.*
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
|
|
@ -21,7 +26,6 @@ import androidx.fragment.app.Fragment
|
|||
import com.google.android.material.card.MaterialCardView
|
||||
import com.tangem.common.extensions.VoidCallback
|
||||
|
||||
|
||||
fun Fragment.getDrawable(@DrawableRes drawableResId: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(requireContext(), drawableResId)
|
||||
}
|
||||
|
|
@ -53,6 +57,10 @@ fun View.getString(@StringRes id: Int, vararg formatArgs: String): String {
|
|||
return context.getString(id, *formatArgs)
|
||||
}
|
||||
|
||||
fun View.getQuantityString(@StringRes id: Int, quantity: Int): String {
|
||||
return context.resources.getQuantityString(id, quantity, quantity)
|
||||
}
|
||||
|
||||
fun View.getResourceName(): String {
|
||||
return try {
|
||||
resources.getResourceEntryName(id)
|
||||
|
|
@ -89,15 +97,13 @@ fun View.invisible(invisible: Boolean = true, invokeBeforeStateChanged: (() -> U
|
|||
} else {
|
||||
this.show(invokeBeforeStateChanged)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun Context.dpToPixels(dp: Int): Int =
|
||||
TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), this.resources.displayMetrics
|
||||
TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), this.resources.displayMetrics,
|
||||
).toInt()
|
||||
|
||||
|
||||
fun Context.pixelsToDp(pixels: Int): Int {
|
||||
return (pixels.toFloat() /
|
||||
(resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT))
|
||||
|
|
@ -107,7 +113,6 @@ fun Context.pixelsToDp(pixels: Int): Int {
|
|||
fun Context.dpToPixels(dp: Float): Float =
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, this.resources.displayMetrics)
|
||||
|
||||
|
||||
fun Context.pixelsToDp(pixels: Float): Float =
|
||||
(pixels / (resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT))
|
||||
|
||||
|
|
@ -118,14 +123,14 @@ fun MaterialCardView.setMargins(
|
|||
marginLeftDp: Int = 16,
|
||||
marginTopDp: Int = 8,
|
||||
marginRightDp: Int = 16,
|
||||
marginBottomDp: Int = 8
|
||||
marginBottomDp: Int = 8,
|
||||
) {
|
||||
val params = this.layoutParams
|
||||
(params as ViewGroup.MarginLayoutParams).setMargins(
|
||||
context.dpToPixels(marginLeftDp),
|
||||
context.dpToPixels(marginTopDp),
|
||||
context.dpToPixels(marginRightDp),
|
||||
context.dpToPixels(marginBottomDp)
|
||||
context.dpToPixels(marginBottomDp),
|
||||
)
|
||||
this.layoutParams = params
|
||||
}
|
||||
|
|
@ -144,7 +149,8 @@ fun Activity.setSystemBarTextColor(setTextDark: Boolean) {
|
|||
}
|
||||
|
||||
fun View.hideKeyboard() {
|
||||
val inputMethodManager = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
||||
val inputMethodManager =
|
||||
context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE) as? InputMethodManager
|
||||
inputMethodManager?.hideSoftInputFromWindow(this.windowToken, 0)
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +188,7 @@ fun Context.safeStartActivity(
|
|||
intent: Intent,
|
||||
options: Bundle? = null,
|
||||
fallback: ((ActivityNotFoundException) -> Unit)? = null,
|
||||
finally: VoidCallback? = null
|
||||
finally: VoidCallback? = null,
|
||||
) {
|
||||
try {
|
||||
this.startActivity(intent, options)
|
||||
|
|
@ -200,7 +206,7 @@ fun View.getString(resId: Int, vararg formatArgs: Any?): String {
|
|||
fun View.animateVisibility(
|
||||
show: Boolean,
|
||||
durationMillis: Long = SHORT_ANIMATION_DURATION,
|
||||
hiddenVisibility: Int = View.GONE
|
||||
hiddenVisibility: Int = View.GONE,
|
||||
) {
|
||||
if (show) {
|
||||
this.animate()
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.tap.common.extensions.sendEmail
|
|||
import com.tangem.tap.common.log.TangemLogCollector
|
||||
import com.tangem.tap.common.zendesk.ZendeskConfig
|
||||
import com.tangem.tap.foregroundActivityObserver
|
||||
import com.tangem.tap.logConfig
|
||||
import com.tangem.tap.persistence.PreferencesStorage
|
||||
import com.tangem.tap.withForegroundActivity
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -31,6 +30,7 @@ class FeedbackManager(
|
|||
val infoHolder: AdditionalFeedbackInfo,
|
||||
private val logCollector: TangemLogCollector,
|
||||
private val preferencesStorage: PreferencesStorage,
|
||||
private val logEnabled: Boolean = false,
|
||||
) {
|
||||
fun initChat(
|
||||
context: Context,
|
||||
|
|
@ -43,7 +43,7 @@ class FeedbackManager(
|
|||
)
|
||||
|
||||
// Zendesk logs
|
||||
Logger.setLoggable(logConfig.zendesk)
|
||||
Logger.setLoggable(logEnabled)
|
||||
}
|
||||
|
||||
fun sendEmail(feedbackData: FeedbackData, onFail: ((Exception) -> Unit)? = null) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.util.Log
|
||||
import coil.ImageLoader
|
||||
import coil.util.Logger
|
||||
import com.tangem.tap.logConfig
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import timber.log.Timber
|
||||
|
|
@ -12,11 +11,12 @@ import timber.log.Timber
|
|||
private const val COIL_LOG_TAG = "COIL"
|
||||
|
||||
fun createCoilImageLoader(
|
||||
context: Context
|
||||
context: Context,
|
||||
logEnabled: Boolean = false,
|
||||
): ImageLoader {
|
||||
return ImageLoader.Builder(context)
|
||||
.apply {
|
||||
if (!logConfig.coil) return@apply
|
||||
if (!logEnabled) return@apply
|
||||
|
||||
logger(CoilTimberLogger())
|
||||
okHttpClient {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.common.redux
|
||||
|
||||
import com.tangem.tap.logConfig
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import org.rekotlin.Middleware
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
@ -10,7 +10,9 @@ import timber.log.Timber
|
|||
val logMiddleware: Middleware<AppState> = { dispatch, appState ->
|
||||
{ nextDispatch ->
|
||||
{ action ->
|
||||
if (logConfig.storeAction) Timber.d("Dispatch action: $action")
|
||||
if (LogConfig.storeAction) {
|
||||
Timber.d("Dispatch action: $action")
|
||||
}
|
||||
nextDispatch(action)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.tangem.common.core.TangemSdkError
|
|||
import com.tangem.common.extensions.guard
|
||||
import com.tangem.common.extensions.ifNotNull
|
||||
import com.tangem.common.services.Result
|
||||
import com.tangem.domain.common.LogConfig
|
||||
import com.tangem.domain.common.extensions.withMainContext
|
||||
import com.tangem.tap.common.extensions.dispatchDebugErrorNotification
|
||||
import com.tangem.tap.common.extensions.dispatchDialogShow
|
||||
|
|
@ -96,7 +97,8 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di
|
|||
?.setWalletsInfo(action.walletManagers)
|
||||
}
|
||||
is GlobalAction.ExchangeManager.Init -> {
|
||||
val config = appState()?.globalState?.configManager?.config
|
||||
val appStateSafe = appState() ?: return
|
||||
val config = appStateSafe.globalState.configManager?.config
|
||||
ifNotNull(
|
||||
config?.mercuryoWidgetId,
|
||||
config?.mercuryoSecret,
|
||||
|
|
@ -108,8 +110,13 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di
|
|||
apiVersion = MercuryoApi.API_VERSION,
|
||||
mercuryoWidgetId = mercuryoWidgetId,
|
||||
secret = mercuryoSecret,
|
||||
logEnabled = LogConfig.network.mercuryoService,
|
||||
)
|
||||
val sellService = MoonPayService(
|
||||
apiKey = moonPayKey,
|
||||
secretKey = moonPaySecretKey,
|
||||
logEnabled = LogConfig.network.moonPayService,
|
||||
)
|
||||
val sellService = MoonPayService(moonPayKey, moonPaySecretKey)
|
||||
val cardProvider = { store.state.globalState.scanResponse?.card }
|
||||
|
||||
val exchangeManager = CurrencyExchangeManager(
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ fun CurrenciesWarning() {
|
|||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.background(Color(0xFFF2F2F2), shape = RoundedCornerShape(10.dp))
|
||||
.background(
|
||||
color = Color(0xFFF2F2F2),
|
||||
shape = RoundedCornerShape(10.dp),
|
||||
),
|
||||
)
|
||||
{
|
||||
val warning = stringResource(id = R.string.alert_manage_tokens_addresses_message)
|
||||
|
|
@ -33,18 +36,18 @@ fun CurrenciesWarning() {
|
|||
AnnotatedString.Range(
|
||||
SpanStyle(fontWeight = FontWeight.Bold),
|
||||
start = 0,
|
||||
end = end
|
||||
)
|
||||
end = end,
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = AnnotatedString(text = warning, spanStyles = spanStyles),
|
||||
textAlign = TextAlign.Center,
|
||||
textAlign = TextAlign.Start,
|
||||
color = Color(0xFF848488),
|
||||
modifier = Modifier.padding(
|
||||
top = 8.dp,
|
||||
bottom = 8.dp,
|
||||
start = 16.dp,
|
||||
end = 16.dp
|
||||
end = 16.dp,
|
||||
),
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Row
|
|||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
|
|
@ -50,7 +51,7 @@ fun CurrencyItemHeader(
|
|||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(62.dp)
|
||||
.heightIn(min = 62.dp)
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
|
|
@ -172,8 +173,7 @@ private fun BlockchainNetworkItem(
|
|||
addedBlockchains: List<Blockchain>,
|
||||
) {
|
||||
val added = addedBlockchains.contains(blockchain)
|
||||
val icon =
|
||||
if (added) blockchain?.getRoundIconRes() else blockchain?.getGreyedOutIconRes()
|
||||
val icon = if (added) blockchain?.getRoundIconRes() else blockchain?.getGreyedOutIconRes()
|
||||
if (icon != null) {
|
||||
Box(
|
||||
Modifier
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.tangem.domain.common.TapWorkarounds.derivationStyle
|
|||
import com.tangem.domain.common.TapWorkarounds.isTestCard
|
||||
import com.tangem.tap.common.extensions.animateVisibility
|
||||
import com.tangem.tap.common.extensions.formatAmountAsSpannedString
|
||||
import com.tangem.tap.common.extensions.getQuantityString
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
|
|
@ -27,7 +28,9 @@ import com.tangem.wallet.R
|
|||
import com.tangem.wallet.databinding.FragmentWalletBinding
|
||||
|
||||
class MultiWalletView : WalletView() {
|
||||
|
||||
private lateinit var walletsAdapter: WalletAdapter
|
||||
|
||||
override fun changeWalletView(fragment: WalletFragment, binding: FragmentWalletBinding) {
|
||||
setFragment(fragment, binding)
|
||||
onViewCreated()
|
||||
|
|
@ -51,8 +54,7 @@ class MultiWalletView : WalletView() {
|
|||
if (card?.backupStatus is Card.BackupStatus.Active) {
|
||||
val cardCount = (card.backupStatus as Card.BackupStatus.Active).cardCount + 1
|
||||
tvTwinCardNumber.show()
|
||||
tvTwinCardNumber.text =
|
||||
fragment?.getString(R.string.wallet_twins_chip_format, 1, cardCount)
|
||||
tvTwinCardNumber.text = tvTwinCardNumber.getQuantityString(R.plurals.card_label_card_count, cardCount)
|
||||
} else {
|
||||
tvTwinCardNumber.hide()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,8 +89,7 @@ class SingleWalletView : WalletView() {
|
|||
TwinCardNumber.First -> 1
|
||||
TwinCardNumber.Second -> 2
|
||||
}
|
||||
tvTwinCardNumber.text =
|
||||
fragment?.getString(R.string.wallet_twins_chip_format, number, 2)
|
||||
tvTwinCardNumber.text = fragment?.getString(R.string.wallet_twins_chip_format, number, 2)
|
||||
}
|
||||
if (twinCardsState?.cardNumber == null) {
|
||||
tvTwinCardNumber.hide()
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ class MercuryoService(
|
|||
private val apiVersion: String,
|
||||
private val mercuryoWidgetId: String,
|
||||
private val secret: String,
|
||||
private val logEnabled: Boolean,
|
||||
) : ExchangeService, ExchangeUrlBuilder {
|
||||
|
||||
private val api: MercuryoApi = createRetrofitInstance(MercuryoApi.BASE_URL)
|
||||
.create(MercuryoApi::class.java)
|
||||
private val api: MercuryoApi = createRetrofitInstance(
|
||||
baseUrl = MercuryoApi.BASE_URL,
|
||||
logEnabled = logEnabled,
|
||||
).create(MercuryoApi::class.java)
|
||||
|
||||
private val blockchainsAvailableToBuy = mutableListOf<Blockchain>()
|
||||
private val tokensAvailableToBy = mutableMapOf<String, MutableList<Blockchain>>()
|
||||
|
|
|
|||
|
|
@ -20,11 +20,14 @@ import javax.crypto.spec.SecretKeySpec
|
|||
class MoonPayService(
|
||||
private val apiKey: String,
|
||||
private val secretKey: String,
|
||||
private val logEnabled: Boolean,
|
||||
) : ExchangeService, ExchangeUrlBuilder {
|
||||
|
||||
private val api: MoonPayApi by lazy {
|
||||
createRetrofitInstance(MoonPayApi.MOOONPAY_BASE_URL)
|
||||
.create(MoonPayApi::class.java)
|
||||
createRetrofitInstance(
|
||||
baseUrl = MoonPayApi.MOOONPAY_BASE_URL,
|
||||
logEnabled = logEnabled,
|
||||
).create(MoonPayApi::class.java)
|
||||
}
|
||||
|
||||
private var status: MoonPayStatus? = null
|
||||
|
|
|
|||
|
|
@ -23,7 +23,10 @@ class PayIdService {
|
|||
return performRequest { payIdApi.setPayId(cardId, publicKey, payId, address, network) }
|
||||
}
|
||||
|
||||
private fun provideRetrofit(): Retrofit = createRetrofitInstance("https://tangem.com/")
|
||||
private fun provideRetrofit(): Retrofit = createRetrofitInstance(
|
||||
baseUrl = "https://tangem.com/",
|
||||
logEnabled = false,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,13 @@ import com.tangem.network.common.createRetrofitInstance
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class PayIdVerifyService(
|
||||
private val baseUrl: String
|
||||
private val baseUrl: String,
|
||||
) {
|
||||
|
||||
private val api = createRetrofitInstance(baseUrl).create(PayIdVerifyApi::class.java)
|
||||
private val api = createRetrofitInstance(
|
||||
baseUrl = baseUrl,
|
||||
logEnabled = false,
|
||||
).create(PayIdVerifyApi::class.java)
|
||||
|
||||
suspend fun verifyAddress(user: String, network: String): Result<VerifyPayIdResponse> {
|
||||
return performRequest { api.verifyAddress(user, createNetworkHeader(network)) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue