diff --git a/kotlin/app/build.gradle.kts b/kotlin/app/build.gradle.kts index a02fcf21..d473ce21 100644 --- a/kotlin/app/build.gradle.kts +++ b/kotlin/app/build.gradle.kts @@ -5,12 +5,12 @@ plugins { android { namespace = "com.google.android.gms.samples.pay" - compileSdk = 34 + compileSdk = 35 defaultConfig { applicationId = "com.google.android.gms.samples.pay" minSdk = 21 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" @@ -58,6 +58,7 @@ android { dependencies { val lifecycleVersion = "2.7.0" + implementation("androidx.navigation:navigation-compose:2.5.0") implementation("com.google.android.gms:play-services-wallet:19.4.0") implementation("com.google.pay.button:compose-pay-button:0.1.3") diff --git a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/activity/CheckoutActivity.kt b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/activity/CheckoutActivity.kt index a72a58cd..0d36a5b7 100644 --- a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/activity/CheckoutActivity.kt +++ b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/activity/CheckoutActivity.kt @@ -23,15 +23,18 @@ import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.lifecycle.lifecycleScope +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument import com.google.android.gms.common.api.CommonStatusCodes -import com.google.android.gms.wallet.contract.TaskResultContracts.GetPaymentDataResult import com.google.android.gms.samples.pay.R +import com.google.android.gms.samples.pay.ui.PaymentSuccessScreen import com.google.android.gms.samples.pay.ui.ProductScreen import com.google.android.gms.samples.pay.viewmodel.CheckoutViewModel import com.google.android.gms.samples.pay.viewmodel.PaymentUiState -import com.google.android.gms.samples.pay.viewmodel.awaitTask -import kotlinx.coroutines.launch +import com.google.android.gms.wallet.contract.TaskResultContracts.GetPaymentDataResult class CheckoutActivity : ComponentActivity() { @@ -54,15 +57,41 @@ class CheckoutActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { + + val navController = rememberNavController() val payState: PaymentUiState by model.paymentUiState.collectAsStateWithLifecycle() - ProductScreen( - title = "Men's Tech Shell Full-Zip", - description = "A versatile full-zip that you can wear all day long and even...", - price = "$50.20", - image = R.drawable.ts_10_11019a, - payUiState = payState, - onGooglePayButtonClick = this::requestPayment, - ) + + NavHost(navController = navController, startDestination = "product_screen" ){ + + composable("product_screen"){ + ProductScreen( + title = "Men's Tech Shell Full-Zip", + description = "A versatile full-zip that you can wear all day long and even...", + price = "$50.20", + image = R.drawable.ts_10_11019a, + payUiState = payState, + onGooglePayButtonClick = { + requestPayment() + }, + onPaymentComplete = { payerName -> + // Navigate to the success screen with the payer's name as an argument + navController.navigate("success_screen/$payerName") { + // Pop up to the start destination to prevent going back to the product screen + popUpTo("product_screen") { inclusive = true } + } + }, + ) + + + } + + composable("success_screen/{payerName}", + arguments = listOf(navArgument("payerName") { type = NavType.StringType }) + ) { backStackEntry -> + PaymentSuccessScreen(payerName = backStackEntry.arguments?.getString("payerName") ?: "") + } + + } } } @@ -70,4 +99,4 @@ class CheckoutActivity : ComponentActivity() { val task = model.getLoadPaymentDataTask(priceLabel = "50.2") task.addOnCompleteListener(paymentDataLauncher::launch) } -} \ No newline at end of file +} diff --git a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/CheckoutLayout.kt b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/CheckoutLayout.kt index 85c25d43..5e3a084b 100644 --- a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/CheckoutLayout.kt +++ b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/CheckoutLayout.kt @@ -25,16 +25,14 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -51,45 +49,18 @@ fun ProductScreen( image: Int, onGooglePayButtonClick: () -> Unit, payUiState: PaymentUiState = PaymentUiState.NotStarted, + onPaymentComplete: (String) -> Unit, ) { val padding = 20.dp val black = Color(0xff000000.toInt()) val grey = Color(0xffeeeeee.toInt()) - if (payUiState is PaymentUiState.PaymentCompleted) { - Column( - modifier = Modifier - .testTag("successScreen") - .background(grey) - .padding(padding) - .fillMaxWidth() - .fillMaxHeight(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Image( - contentDescription = null, - painter = painterResource(R.drawable.check_circle), - modifier = Modifier - .width(200.dp) - .height(200.dp) - ) - Spacer(modifier = Modifier.height(10.dp)) - Text( - text = "${payUiState.payerName} completed a payment.\nWe are preparing your order.", - fontSize = 17.sp, - color = Color.DarkGray, - textAlign = TextAlign.Center - ) - } - - } else { - Column( - modifier = Modifier - .background(grey) - .padding(padding) - .fillMaxHeight(), - verticalArrangement = Arrangement.spacedBy(space = padding / 2), + Column( + modifier = Modifier + .background(grey) + .padding(padding) + .fillMaxHeight(), + verticalArrangement = Arrangement.spacedBy(space = padding / 2), ) { Image( contentDescription = null, @@ -125,8 +96,15 @@ fun ProductScreen( ) } } + + LaunchedEffect(key1 = payUiState) { + if (payUiState is PaymentUiState.PaymentCompleted) { + onPaymentComplete(payUiState.payerName) + } } -} + + } + /** * Wrapper to simplify previews with a provided description. @@ -143,6 +121,7 @@ private fun ProductScreenPreviewWithDescription( image = R.drawable.ts_10_11019a, onGooglePayButtonClick = {}, // No-op for previews payUiState = payUiState, + onPaymentComplete = {} // No Navigation for preview ) } @@ -180,4 +159,4 @@ private fun ProductScreenPreviewPaymentCompleted() { payUiState = PaymentUiState.PaymentCompleted(payerName = "John"), description = "This is a product description." ) -} \ No newline at end of file +} diff --git a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/PaymentsSuccessScreen.kt b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/PaymentsSuccessScreen.kt new file mode 100644 index 00000000..a05117d3 --- /dev/null +++ b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/ui/PaymentsSuccessScreen.kt @@ -0,0 +1,55 @@ +package com.google.android.gms.samples.pay.ui + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.google.android.gms.samples.pay.R + +@Composable +fun PaymentSuccessScreen(payerName: String) { + val padding = 20.dp + val grey = Color(0xffeeeeee.toInt()) + + Column( + modifier = Modifier + .testTag("successScreen") + .background(grey) + .padding(padding) + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Image( + contentDescription = null, + painter = painterResource(R.drawable.check_circle), + modifier = Modifier + .width(200.dp) + .height(200.dp) + ) + Spacer(modifier = Modifier.height(10.dp)) + Text( + text = "$payerName completed a payment.\nWe are preparing your order.", + fontSize = 17.sp, + color = Color.DarkGray, + textAlign = TextAlign.Center + ) + } +} \ No newline at end of file diff --git a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/viewmodel/CheckoutViewModel.kt b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/viewmodel/CheckoutViewModel.kt index e4c964ea..00102af2 100644 --- a/kotlin/app/src/main/java/com/google/android/gms/samples/pay/viewmodel/CheckoutViewModel.kt +++ b/kotlin/app/src/main/java/com/google/android/gms/samples/pay/viewmodel/CheckoutViewModel.kt @@ -168,3 +168,4 @@ private object DirectExecutor : Executor { r.run() } } + diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts index f09cb3b9..c336c6b1 100644 --- a/kotlin/build.gradle.kts +++ b/kotlin/build.gradle.kts @@ -1,5 +1,5 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.2.2" apply false + id("com.android.application") version "8.13.2" apply false id("org.jetbrains.kotlin.android") version "1.8.10" apply false } \ No newline at end of file diff --git a/kotlin/gradle/wrapper/gradle-wrapper.properties b/kotlin/gradle/wrapper/gradle-wrapper.properties index d6a82bef..ee584917 100644 --- a/kotlin/gradle/wrapper/gradle-wrapper.properties +++ b/kotlin/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip