Updated on 2026-08-14
This commit is contained in:
commit
86d788ed42
27 changed files with 298 additions and 104 deletions
|
|
@ -80,8 +80,8 @@ dependencies {
|
|||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
implementation 'com.tangem:blockchain:develop-64'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-132'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-132'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:core:develop-134'
|
||||
implementation 'com.tangem.tangem-sdk-kotlin:android:develop-134'
|
||||
|
||||
// WebView
|
||||
implementation "androidx.browser:browser:1.3.0"
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 180252680e80b88f8fec9add783207d41d30e4e3
|
||||
Subproject commit 44ccf4e7766e51e869eabe8bc68026b5b7edd237
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.tap.common.extensions.filterNotNull
|
||||
|
|
@ -13,6 +14,11 @@ abstract class AnalyticsHandler {
|
|||
params: Map<String, String> = emptyMap()
|
||||
)
|
||||
|
||||
abstract fun triggerEvent(
|
||||
event: String,
|
||||
params: Map<String, String>
|
||||
)
|
||||
|
||||
abstract fun logCardSdkError(
|
||||
error: TangemSdkError,
|
||||
actionToLog: Analytics.ActionToLog,
|
||||
|
|
@ -71,6 +77,13 @@ abstract class AnalyticsHandler {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun logShopifyOrder(order: Storefront.Order) {
|
||||
triggerEvent(getOrderEvent(), getOrderParams(order))
|
||||
}
|
||||
|
||||
protected abstract fun getOrderEvent(): String
|
||||
|
||||
protected abstract fun getOrderParams(order: Storefront.Order): Map<String, String>
|
||||
}
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import android.app.Application
|
||||
import com.appsflyer.AFInAppEventParameterName
|
||||
import com.appsflyer.AFInAppEventType
|
||||
import com.appsflyer.AppsFlyerLib
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
||||
|
|
@ -30,4 +33,30 @@ class AppsFlyerAnalyticsHandler(val context: Application): AnalyticsHandler() {
|
|||
//TODO
|
||||
}
|
||||
|
||||
override fun getOrderEvent(): String = AFInAppEventType.PURCHASE
|
||||
|
||||
override fun getOrderParams(order: Storefront.Order): Map<String, String> {
|
||||
|
||||
val sku = order.lineItems.edges.firstOrNull()?.node?.variant?.sku ?: "unknown"
|
||||
|
||||
val discountCode =
|
||||
(order.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
|
||||
|
||||
val discountParams = if (discountCode != null ){
|
||||
mapOf(AFInAppEventParameterName.COUPON_CODE to discountCode)
|
||||
} else {
|
||||
mapOf()
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
AFInAppEventParameterName.CONTENT_ID to sku,
|
||||
AFInAppEventParameterName.REVENUE to order.totalPriceV2.amount,
|
||||
AFInAppEventParameterName.CURRENCY to order.currencyCode.name
|
||||
) + discountParams
|
||||
}
|
||||
|
||||
override fun triggerEvent(event: String, params: Map<String, String>) {
|
||||
AppsFlyerLib.getInstance().logEvent(context, event, params)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,9 +2,11 @@ package com.tangem.tap.common.analytics
|
|||
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
||||
|
|
@ -57,4 +59,30 @@ object FirebaseAnalyticsHandler : AnalyticsHandler() {
|
|||
params.forEach { (key, value) -> FirebaseCrashlytics.getInstance().setCustomKey(key, value) }
|
||||
FirebaseCrashlytics.getInstance().recordException(error)
|
||||
}
|
||||
|
||||
override fun getOrderEvent(): String = FirebaseAnalytics.Event.PURCHASE
|
||||
|
||||
override fun getOrderParams(order: Storefront.Order): Map<String, String> {
|
||||
|
||||
val sku = order.lineItems.edges.firstOrNull()?.node?.variant?.sku ?: "unknown"
|
||||
|
||||
val discountCode =
|
||||
(order.discountApplications.edges.firstOrNull()?.node as? Storefront.DiscountCodeApplication)?.code
|
||||
|
||||
val discountParams = if (discountCode != null ){
|
||||
mapOf(FirebaseAnalytics.Param.DISCOUNT to discountCode)
|
||||
} else {
|
||||
mapOf()
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
FirebaseAnalytics.Param.ITEM_ID to sku,
|
||||
FirebaseAnalytics.Param.VALUE to order.totalPriceV2.amount,
|
||||
FirebaseAnalytics.Param.CURRENCY to order.currencyCode.name
|
||||
) + discountParams
|
||||
}
|
||||
|
||||
override fun triggerEvent(event: String, params: Map<String, String>) {
|
||||
Firebase.analytics.logEvent(event, params.toBundle())
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import android.app.Application
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
||||
|
|
@ -15,6 +16,10 @@ class GlobalAnalyticsHandler(val analyticsHandlers: List<AnalyticsHandler>) :
|
|||
analyticsHandlers.forEach { it.triggerEvent(event, card, blockchain) }
|
||||
}
|
||||
|
||||
override fun triggerEvent(event: String, params: Map<String, String>) {
|
||||
analyticsHandlers.forEach { it.triggerEvent(event, params) }
|
||||
}
|
||||
|
||||
override fun logCardSdkError(
|
||||
error: TangemSdkError,
|
||||
actionToLog: Analytics.ActionToLog,
|
||||
|
|
@ -28,6 +33,14 @@ class GlobalAnalyticsHandler(val analyticsHandlers: List<AnalyticsHandler>) :
|
|||
analyticsHandlers.forEach { it.logError(error, params) }
|
||||
}
|
||||
|
||||
override fun getOrderEvent(): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun getOrderParams(order: Storefront.Order): Map<String, String> {
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun createDefaultAnalyticHandlers(context: Application): GlobalAnalyticsHandler {
|
||||
return GlobalAnalyticsHandler(
|
||||
|
|
|
|||
|
|
@ -4,9 +4,11 @@ import android.app.Application
|
|||
import android.content.Intent
|
||||
import com.google.android.gms.wallet.PaymentData
|
||||
import com.shopify.buy3.Storefront
|
||||
import com.tangem.tap.common.analytics.AnalyticsHandler
|
||||
import com.tangem.tap.common.shop.data.ProductType
|
||||
import com.tangem.tap.common.shop.data.TangemProduct
|
||||
import com.tangem.tap.common.shop.data.TotalSum
|
||||
import com.tangem.tap.common.shop.shopify.ShopifyService
|
||||
import com.tangem.tap.common.shop.shopify.ShopifyShop
|
||||
import com.tangem.tap.common.shop.shopify.data.CheckoutItem
|
||||
import kotlinx.coroutines.async
|
||||
|
|
@ -197,6 +199,18 @@ class TangemShopService(application: Application, shopifyShop: ShopifyShop) {
|
|||
return checkouts[productType]!!.webUrl
|
||||
}
|
||||
|
||||
suspend fun waitForCheckout(
|
||||
productType: ProductType,
|
||||
analyticsHandler: AnalyticsHandler?
|
||||
) {
|
||||
val result = shopifyService.checkout(true, checkouts[productType]!!.id)
|
||||
result.onSuccess {
|
||||
if (it.order != null) {
|
||||
analyticsHandler?.logShopifyOrder(order = it.order)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TANGEM_WALLET_2_CARDS_SKU = "TG115x2"
|
||||
const val TANGEM_WALLET_3_CARDS_SKU = "TG115x3"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.tap.common.shop
|
||||
package com.tangem.tap.common.shop.shopify
|
||||
|
||||
import android.app.Application
|
||||
import com.shopify.buy3.GraphCallResult
|
||||
|
|
@ -7,7 +7,6 @@ import com.shopify.buy3.RetryHandler
|
|||
import com.shopify.buy3.Storefront.*
|
||||
import com.shopify.graphql.support.ID
|
||||
import com.shopify.graphql.support.Input
|
||||
import com.tangem.tap.common.shop.shopify.ShopifyShop
|
||||
import com.tangem.tap.common.shop.shopify.data.CheckoutItem
|
||||
import com.tangem.tap.common.shop.shopify.data.checkoutFieldsFragment
|
||||
import com.tangem.tap.common.shop.shopify.data.collectionFieldsFragment
|
||||
|
|
@ -85,7 +84,7 @@ class ShopifyService(private val application: Application, val shop: ShopifyShop
|
|||
when (result) {
|
||||
is GraphCallResult.Success -> {
|
||||
val checkout = result.response.data?.node as? Checkout
|
||||
checkout == null
|
||||
checkout?.order == null
|
||||
}
|
||||
is GraphCallResult.Failure -> false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ object TapWorkarounds {
|
|||
"AB04" to Blockchain.Dogecoin,
|
||||
"AB05" to Blockchain.BSC,
|
||||
"AB06" to Blockchain.XRP,
|
||||
"AB07" to Blockchain.Bitcoin,
|
||||
"AB08" to Blockchain.Ethereum,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,20 @@ private class CreateWalletTangemWallet : ProductCommandProcessor<CreateProductWa
|
|||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
primaryCard = result.data
|
||||
deriveKeys(createWalletResponse, session, callback)
|
||||
when {
|
||||
card.settings.isHDWalletAllowed -> {
|
||||
deriveKeys(createWalletResponse, session, callback)
|
||||
}
|
||||
else -> {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
CreateProductWalletTaskResponse(
|
||||
card = session.environment.card!!, primaryCard = primaryCard
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
callback(CompletionResult.Failure(result.error))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.domain.tasks.product
|
||||
|
||||
import com.tangem.*
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.Token
|
||||
import com.tangem.common.CompletionResult
|
||||
|
|
@ -241,7 +240,7 @@ private class ScanWalletProcessor(
|
|||
callback: (result: CompletionResult<ScanResponse>) -> Unit
|
||||
) {
|
||||
val derivations = collectDerivations(card)
|
||||
if (derivations.isEmpty()) {
|
||||
if (derivations.isEmpty() || !card.settings.isHDWalletAllowed) {
|
||||
callback(
|
||||
CompletionResult.Success(
|
||||
ScanResponse(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.tangem.tap.features.home.compose
|
||||
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.text.TextLayoutResult
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.unit.ExperimentalUnitApi
|
||||
|
||||
@OptIn(ExperimentalUnitApi::class)
|
||||
@Composable
|
||||
fun AutoSizeText(
|
||||
text: String,
|
||||
textStyle: TextStyle,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val scaledTextStyle = remember { mutableStateOf(textStyle) }
|
||||
val readyToDraw = remember { mutableStateOf(false) }
|
||||
|
||||
val onTextLayout: (TextLayoutResult) -> Unit = { result ->
|
||||
if (result.didOverflowWidth) {
|
||||
val fontSize = result.size.width / result.multiParagraph.width
|
||||
scaledTextStyle.value =
|
||||
// scaledTextStyle.value.copy(fontSize = TextUnit(fontSize, TextUnitType.Sp))
|
||||
scaledTextStyle.value.copy(fontSize = scaledTextStyle.value.fontSize * 0.9)
|
||||
} else {
|
||||
readyToDraw.value = true
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
text = text,
|
||||
modifier = modifier.drawWithContent {
|
||||
if (readyToDraw.value) {
|
||||
drawContent()
|
||||
}
|
||||
},
|
||||
softWrap = false,
|
||||
onTextLayout = onTextLayout,
|
||||
style = scaledTextStyle.value,
|
||||
)
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ import androidx.compose.animation.scaleIn
|
|||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -21,6 +20,7 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -88,32 +88,27 @@ fun FirstStoriesContent(
|
|||
StartingScreenState.MEET_TANGEM -> R.string.story_meet_title
|
||||
}
|
||||
|
||||
if (screenState.value != StartingScreenState.MEET_TANGEM) {
|
||||
Text(
|
||||
text = text?.let { stringResource(text) } ?: "",
|
||||
fontSize = 60.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
modifier = Modifier
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
.alpha(if (screenState.value == StartingScreenState.SHOW_CARD) 0f else 1f),
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Center,
|
||||
val style = TextStyle(
|
||||
fontSize = 60.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
)
|
||||
if (screenState.value != StartingScreenState.MEET_TANGEM) {
|
||||
AutoSizeText(text = text?.let { stringResource(text) } ?: "", textStyle = style,
|
||||
modifier = Modifier
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
.alpha(if (screenState.value == StartingScreenState.SHOW_CARD) 0f else 1f),)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = screenState.value == StartingScreenState.MEET_TANGEM,
|
||||
enter = slideInVertically() { it / 2 }
|
||||
) {
|
||||
Text(
|
||||
text = text?.let { stringResource(text) } ?: "",
|
||||
fontSize = 60.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
AutoSizeText(text = text?.let { stringResource(text) } ?: "", textStyle = style,
|
||||
modifier = Modifier
|
||||
.padding(start = 40.dp, end = 40.dp),
|
||||
color = Color.White,
|
||||
textAlign = TextAlign.Center
|
||||
.padding(start = 40.dp, end = 40.dp)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.wallet.R
|
||||
import androidx.compose.foundation.layout.fillMaxWidth as fillMaxWidth1
|
||||
|
||||
@Composable
|
||||
fun HomeButtons(
|
||||
|
|
@ -25,13 +25,13 @@ fun HomeButtons(
|
|||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
modifier = modifier.fillMaxWidth1()
|
||||
modifier = modifier.fillMaxWidth()
|
||||
) {
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
Button(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(42.dp),
|
||||
.height(42.dp)
|
||||
,
|
||||
onClick = onScanButtonClick,
|
||||
colors = ButtonDefaults.textButtonColors(
|
||||
backgroundColor = if (isDarkBackground) darkColorBackground else Color.White,
|
||||
|
|
@ -41,7 +41,8 @@ fun HomeButtons(
|
|||
Text(
|
||||
text = stringResource(id = R.string.home_button_scan),
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 16.sp
|
||||
fontSize = 16.sp,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.size(8.dp))
|
||||
|
|
@ -58,9 +59,9 @@ fun HomeButtons(
|
|||
Text(
|
||||
text = stringResource(id = R.string.home_button_order),
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 16.sp
|
||||
fontSize = 16.sp,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
}
|
||||
}
|
||||
|
|
@ -54,28 +54,46 @@ fun StoriesScreen(
|
|||
Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color(0xFF090E13))
|
||||
.pointerInput(Unit) {
|
||||
val maxWidth = this.size.width
|
||||
detectTapGestures(
|
||||
onPress = {
|
||||
val pressStartTime = System.currentTimeMillis()
|
||||
isPressed.value = true
|
||||
this.tryAwaitRelease()
|
||||
val pressEndTime = System.currentTimeMillis()
|
||||
val totalPressTime = pressEndTime - pressStartTime
|
||||
if (totalPressTime < 200) {
|
||||
val isTapOnRightTwoTiers = (it.x > (maxWidth / 2))
|
||||
if (isTapOnRightTwoTiers) {
|
||||
goToNextScreen()
|
||||
} else {
|
||||
goToPreviousScreen()
|
||||
}
|
||||
}
|
||||
isPressed.value = false
|
||||
},
|
||||
)
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
Modifier.fillMaxSize()
|
||||
) {
|
||||
Box(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.fillMaxHeight()
|
||||
.pointerInput(isPressed) {
|
||||
detectTapGestures(
|
||||
onPress = {
|
||||
val pressStartTime = System.currentTimeMillis()
|
||||
isPressed.value = true
|
||||
this.tryAwaitRelease()
|
||||
val pressEndTime = System.currentTimeMillis()
|
||||
val totalPressTime = pressEndTime - pressStartTime
|
||||
if (totalPressTime < 200) goToPreviousScreen()
|
||||
isPressed.value = false
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
Box(
|
||||
Modifier.weight(1f)
|
||||
.fillMaxHeight()
|
||||
.pointerInput(isPressed) {
|
||||
detectTapGestures(
|
||||
onPress = {
|
||||
val pressStartTime = System.currentTimeMillis()
|
||||
isPressed.value = true
|
||||
this.tryAwaitRelease()
|
||||
val pressEndTime = System.currentTimeMillis()
|
||||
val totalPressTime = pressEndTime - pressStartTime
|
||||
if (totalPressTime < 200) goToNextScreen()
|
||||
isPressed.value = false
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (!isDarkBackground) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_overlay),
|
||||
|
|
@ -87,9 +105,8 @@ fun StoriesScreen(
|
|||
}
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxSize()
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Spacer(modifier = Modifier.size(24.dp))
|
||||
StoriesProgressBar(
|
||||
|
|
@ -111,12 +128,6 @@ fun StoriesScreen(
|
|||
.align(Alignment.Start),
|
||||
colorFilter = if (isDarkBackground) null else ColorFilter.tint(Color.Black)
|
||||
)
|
||||
}
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
when (currentStep.value) {
|
||||
1 -> FirstStoriesContent(pause, stepDuration) { hideContent.value = it }
|
||||
2 -> StoriesRevolutionaryWallet()
|
||||
|
|
@ -130,7 +141,8 @@ fun StoriesScreen(
|
|||
isDarkBackground = isDarkBackground,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(37.dp),
|
||||
.padding(37.dp)
|
||||
.fillMaxWidth(),
|
||||
onScanButtonClick = onScanButtonClick,
|
||||
onShopButtonClick = onShopButtonClick
|
||||
)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ fun StoriesGeneralContent(
|
|||
Image(
|
||||
painter = painterResource(id = imageSource),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillWidth,
|
||||
contentScale = if(isDarkBackground) ContentScale.Inside else ContentScale.FillWidth,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,8 +332,8 @@ class TwinsCardsFragment : BaseOnboardingFragment<TwinCardsState>() {
|
|||
store.dispatch(TwinCardsAction.ShowAddressInfoDialog)
|
||||
}
|
||||
} else {
|
||||
btnAlternativeAction.setText(R.string.onboarding_button_receive_crypto)
|
||||
btnAlternativeAction.setOnClickListener {
|
||||
btnMainAction.setText(R.string.onboarding_button_receive_crypto)
|
||||
btnMainAction.setOnClickListener {
|
||||
store.dispatch(TwinCardsAction.ShowAddressInfoDialog)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,10 +124,15 @@ private fun handleWalletAction(action: Action) {
|
|||
} else {
|
||||
null
|
||||
}
|
||||
BackupAction.IntroduceBackup(url)
|
||||
if (walletState.backupState.backupStep == BackupStep.InitBackup ||
|
||||
walletState.backupState.backupStep == BackupStep.Finished) {
|
||||
BackupAction.IntroduceBackup(url)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
store.dispatch(newAction)
|
||||
newAction?.let { store.dispatch(it) }
|
||||
}
|
||||
OnboardingWalletAction.OnBackPressed -> {
|
||||
when (walletState.backupState.backupStep) {
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet),
|
|||
viewPagerBackupInfo.hide()
|
||||
tabLayoutBackupInfo.hide()
|
||||
|
||||
imvSecondBackupCard.show()
|
||||
imvFirstBackupCard.show()
|
||||
imvSecondBackupCard.show()
|
||||
}
|
||||
|
||||
|
|
@ -236,12 +236,15 @@ class OnboardingWalletFragment : Fragment(R.layout.fragment_onboarding_wallet),
|
|||
tvHeader.text = getText(R.string.onboarding_title_one_backup_card)
|
||||
tvBody.text = getText(R.string.onboarding_subtitle_one_backup_card)
|
||||
|
||||
cardsWidget.toFan(false)
|
||||
cardsWidget.getFirstBackupCardView().animate().alpha(1f).setDuration(400)
|
||||
cardsWidget.getSecondBackupCardView().alpha = 0.2f
|
||||
}
|
||||
2 -> {
|
||||
tvHeader.text = getText(R.string.onboarding_title_two_backup_cards)
|
||||
tvBody.text = getText(R.string.onboarding_subtitle_two_backup_cards)
|
||||
|
||||
cardsWidget.toFan(false)
|
||||
cardsWidget.getFirstBackupCardView().alpha = 1f
|
||||
cardsWidget.getSecondBackupCardView().animate().alpha(1f).setDuration(400)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) :
|
|||
}
|
||||
|
||||
private fun handleFeeState(fg: SendFragment, state: FeeState) = with(fg.binding.clNetworkFee) {
|
||||
chipGroup.fitChipsByGroupWidth()
|
||||
// chipGroup.fitChipsByGroupWidth()
|
||||
fg.view?.findViewById<ViewGroup>(R.id.clNetworkFee)?.show(state.mainLayoutIsVisible)
|
||||
flExpandCollapse.imvExpandCollapse.rotation = if (state.controlsLayoutIsVisible) 0f else 180f
|
||||
llFeeControlsContainer.show(state.controlsLayoutIsVisible)
|
||||
|
|
|
|||
|
|
@ -34,5 +34,7 @@ sealed class ShopAction : Action {
|
|||
|
||||
data class SelectProduct(val productType: ProductType) : ShopAction()
|
||||
|
||||
object FinishSuccessfulOrder : ShopAction()
|
||||
|
||||
object ResetState : ShopAction()
|
||||
}
|
||||
|
|
@ -110,7 +110,18 @@ private fun handle(action: Action) {
|
|||
}
|
||||
ShopAction.StartWebCheckout -> {
|
||||
store.dispatchOpenUrl(shopService.getCheckoutUrl(shopState.selectedProduct))
|
||||
store.dispatch(ShopAction.FinishSuccessfulOrder)
|
||||
}
|
||||
|
||||
is ShopAction.FinishSuccessfulOrder -> {
|
||||
scope.launch {
|
||||
shopService.waitForCheckout(
|
||||
productType = shopState.selectedProduct,
|
||||
analyticsHandler = store.state.globalState.analyticsHandlers
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -63,6 +63,7 @@ private fun internalReduce(action: Action, state: ShopState): ShopState {
|
|||
ShopAction.BuyWithGooglePay.UserCancelled -> {
|
||||
state
|
||||
}
|
||||
ShopAction.FinishSuccessfulOrder -> state
|
||||
ShopAction.ResetState -> ShopState()
|
||||
}
|
||||
}
|
||||
|
|
@ -137,7 +137,7 @@ class ShopFragment : BaseStoreFragment(R.layout.fragment_shop), StoreSubscriber<
|
|||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
super.onAnimationEnd(animation)
|
||||
imvThird?.show(show)
|
||||
imvThird.show(show)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="36dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="44dp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:layout_weight="1"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tv_header"
|
||||
|
|
@ -109,7 +110,6 @@
|
|||
android:id="@+id/tv_header"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="44dp"
|
||||
android:layout_marginBottom="14dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:text="@string/shop_one_wallet"
|
||||
|
|
@ -343,7 +343,7 @@
|
|||
android:layout_height="48sp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginBottom="70dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:text="@string/shop_buy_now"
|
||||
android:textAlignment="center"
|
||||
android:textSize="16sp" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/clNetworkFee"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
@ -35,39 +36,47 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/flExpandCollapse">
|
||||
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chipGroup"
|
||||
<HorizontalScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:translationY="-8dp"
|
||||
app:selectionRequired="true"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
android:clipChildren="false">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipLow"
|
||||
style="@style/TapChip"
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:id="@+id/chipGroup"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_low" />
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:translationY="-8dp"
|
||||
app:selectionRequired="true"
|
||||
app:singleLine="true"
|
||||
app:singleSelection="true">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipNormal"
|
||||
style="@style/TapChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_normal" />
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipLow"
|
||||
style="@style/TapChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_low" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipPriority"
|
||||
style="@style/TapChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_priority" />
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipNormal"
|
||||
style="@style/TapChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_normal"
|
||||
tools:text="Нормальный" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/chipPriority"
|
||||
style="@style/TapChip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/send_fee_picker_priority"
|
||||
tools:text="Приоритетный" />
|
||||
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
</HorizontalScrollView>
|
||||
|
||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||
android:id="@+id/swIncludeFee"
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintGuide_percent="0.37" />
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_confirm_long"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue