Skip to content

Commit

Permalink
Create empty manage PMs screen (#8523)
Browse files Browse the repository at this point in the history
* Create empty manage PMs screen

* comment update

* update string resources

* Revert "update string resources"

This reverts commit 050aa72.

* put string in correct spot

* reuse existing string

* fix broken tests

* separate new "Go to manage screen" button from NewPM layout

* Add header text tests
  • Loading branch information
amk-stripe committed May 23, 2024
1 parent 87b2464 commit b487d88
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 51 deletions.
7 changes: 7 additions & 0 deletions paymentsheet/api/paymentsheet.api
Original file line number Diff line number Diff line change
Expand Up @@ -1934,6 +1934,13 @@ public final class com/stripe/android/paymentsheet/ui/ComposableSingletons$Manda
public final fun getLambda-1$paymentsheet_release ()Lkotlin/jvm/functions/Function2;
}

public final class com/stripe/android/paymentsheet/ui/ComposableSingletons$PaymentMethodVerticalLayoutUIKt {
public static final field INSTANCE Lcom/stripe/android/paymentsheet/ui/ComposableSingletons$PaymentMethodVerticalLayoutUIKt;
public static field lambda-1 Lkotlin/jvm/functions/Function3;
public fun <init> ()V
public final fun getLambda-1$paymentsheet_release ()Lkotlin/jvm/functions/Function3;
}

public final class com/stripe/android/paymentsheet/ui/ComposableSingletons$PaymentSheetScreenKt {
public static final field INSTANCE Lcom/stripe/android/paymentsheet/ui/ComposableSingletons$PaymentSheetScreenKt;
public static field lambda-1 Lkotlin/jvm/functions/Function4;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.stripe.android.paymentsheet.navigation

import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
Expand All @@ -15,7 +16,7 @@ import com.stripe.android.paymentsheet.ui.AddPaymentMethod
import com.stripe.android.paymentsheet.ui.EditPaymentMethod
import com.stripe.android.paymentsheet.ui.FormElement
import com.stripe.android.paymentsheet.ui.ModifiableEditPaymentMethodViewInteractor
import com.stripe.android.paymentsheet.ui.NewPaymentMethodVerticalLayoutUI
import com.stripe.android.paymentsheet.ui.PaymentMethodVerticalLayoutUI
import com.stripe.android.paymentsheet.ui.SavedPaymentMethodTabLayoutUI
import com.stripe.android.paymentsheet.ui.SavedPaymentMethodsTopContentPadding
import com.stripe.android.paymentsheet.viewmodels.BaseSheetViewModel
Expand All @@ -32,6 +33,7 @@ internal val PaymentSheetScreen.topContentPadding: Dp
is PaymentSheetScreen.Form,
is PaymentSheetScreen.AddFirstPaymentMethod,
is PaymentSheetScreen.AddAnotherPaymentMethod,
is PaymentSheetScreen.ManageSavedPaymentMethods,
is PaymentSheetScreen.EditPaymentMethod -> {
0.dp
}
Expand Down Expand Up @@ -64,7 +66,7 @@ internal sealed interface PaymentSheetScreen {
}
}

object SelectSavedPaymentMethods : PaymentSheetScreen {
data object SelectSavedPaymentMethods : PaymentSheetScreen {

override val showsBuyButton: Boolean = true
override val showsContinueButton: Boolean = false
Expand Down Expand Up @@ -172,10 +174,11 @@ internal sealed interface PaymentSheetScreen {

val isProcessing by viewModel.processing.collectAsState()

NewPaymentMethodVerticalLayoutUI(
PaymentMethodVerticalLayoutUI(
paymentMethods = supportedPaymentMethods,
selectedIndex = -1,
isEnabled = !isProcessing,
onViewMorePaymentMethods = { viewModel.transitionTo(ManageSavedPaymentMethods) },
onItemSelectedListener = { viewModel.transitionTo(Form(it.code)) },
imageLoader = imageLoader,
modifier = Modifier.padding(horizontal = 20.dp)
Expand Down Expand Up @@ -222,4 +225,17 @@ internal sealed interface PaymentSheetScreen {
)
}
}

data object ManageSavedPaymentMethods : PaymentSheetScreen {
override val showsBuyButton: Boolean = false
override val showsContinueButton: Boolean = false
override val canNavigateBack: Boolean = true

override fun showsWalletsHeader(isCompleteFlow: Boolean): Boolean = false

@Composable
override fun Content(viewModel: BaseSheetViewModel, modifier: Modifier) {
Text("Manage your saved PMs here")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,55 +16,69 @@ internal class HeaderTextFactory(
types: List<PaymentMethodCode>,
): Int? {
return if (isCompleteFlow) {
when (screen) {
is PaymentSheetScreen.SelectSavedPaymentMethods -> {
if (isWalletEnabled) {
null
} else {
R.string.stripe_paymentsheet_select_payment_method
}
}
is PaymentSheetScreen.AddFirstPaymentMethod, PaymentSheetScreen.VerticalMode -> {
R.string.stripe_paymentsheet_add_payment_method_title.takeUnless {
isWalletEnabled
}
}
is PaymentSheetScreen.EditPaymentMethod -> {
StripeR.string.stripe_title_update_card
}
is PaymentSheetScreen.Loading,
is PaymentSheetScreen.AddAnotherPaymentMethod,
is PaymentSheetScreen.Form,
null -> {
null
}
}
createForCompleteFlow(screen, isWalletEnabled)
} else {
when (screen) {
is PaymentSheetScreen.Loading, is PaymentSheetScreen.Form -> {
null
}
is PaymentSheetScreen.SelectSavedPaymentMethods -> {
R.string.stripe_paymentsheet_select_payment_method
}
is PaymentSheetScreen.AddFirstPaymentMethod,
is PaymentSheetScreen.AddAnotherPaymentMethod,
is PaymentSheetScreen.VerticalMode -> {
val title = if (types.singleOrNull() == PaymentMethod.Type.Card.code) {
StripeR.string.stripe_title_add_a_card
} else {
R.string.stripe_paymentsheet_choose_payment_method
}
createForFlowController(screen, types, isWalletEnabled)
}
}

private fun createForCompleteFlow(
screen: PaymentSheetScreen?,
isWalletEnabled: Boolean
) = when (screen) {
is PaymentSheetScreen.SelectSavedPaymentMethods -> {
if (isWalletEnabled) {
null
} else {
R.string.stripe_paymentsheet_select_payment_method
}
}
is PaymentSheetScreen.AddFirstPaymentMethod, PaymentSheetScreen.VerticalMode -> {
R.string.stripe_paymentsheet_add_payment_method_title.takeUnless {
isWalletEnabled
}
}
is PaymentSheetScreen.EditPaymentMethod -> {
StripeR.string.stripe_title_update_card
}
is PaymentSheetScreen.ManageSavedPaymentMethods -> {
R.string.stripe_paymentsheet_select_payment_method
}
is PaymentSheetScreen.Loading,
is PaymentSheetScreen.AddAnotherPaymentMethod,
is PaymentSheetScreen.Form,
null -> {
null
}
}

title.takeUnless { isWalletEnabled }
}
is PaymentSheetScreen.EditPaymentMethod -> {
StripeR.string.stripe_title_update_card
}
null -> {
null
}
private fun createForFlowController(
screen: PaymentSheetScreen?,
types: List<PaymentMethodCode>,
isWalletEnabled: Boolean
) = when (screen) {
is PaymentSheetScreen.Loading, is PaymentSheetScreen.Form -> {
null
}
is PaymentSheetScreen.SelectSavedPaymentMethods, is PaymentSheetScreen.ManageSavedPaymentMethods -> {
R.string.stripe_paymentsheet_select_payment_method
}
is PaymentSheetScreen.AddFirstPaymentMethod,
is PaymentSheetScreen.AddAnotherPaymentMethod,
is PaymentSheetScreen.VerticalMode -> {
val title = if (types.singleOrNull() == PaymentMethod.Type.Card.code) {
StripeR.string.stripe_title_add_a_card
} else {
R.string.stripe_paymentsheet_choose_payment_method
}

title.takeUnless { isWalletEnabled }
}
is PaymentSheetScreen.EditPaymentMethod -> {
StripeR.string.stripe_title_update_card
}
null -> {
null
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.stripe.android.paymentsheet.ui

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.stripe.android.lpmfoundations.luxe.SupportedPaymentMethod
import com.stripe.android.uicore.image.StripeImageLoader

@Composable
internal fun PaymentMethodVerticalLayoutUI(
paymentMethods: List<SupportedPaymentMethod>,
selectedIndex: Int,
isEnabled: Boolean,
onViewMorePaymentMethods: () -> Unit,
onItemSelectedListener: (SupportedPaymentMethod) -> Unit,
imageLoader: StripeImageLoader,
modifier: Modifier = Modifier,
) {
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(12.dp)) {
TextButton(onClick = { onViewMorePaymentMethods() }) {
Text(text = "Go to manage screen")
}

NewPaymentMethodVerticalLayoutUI(
paymentMethods = paymentMethods,
selectedIndex = selectedIndex,
isEnabled = isEnabled,
onItemSelectedListener = onItemSelectedListener,
imageLoader = imageLoader
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ internal abstract class BaseSheetViewModel(
previouslyShownForm = null
previouslyInteractedForm = null
}
is PaymentSheetScreen.Form -> {
is PaymentSheetScreen.Form, is PaymentSheetScreen.ManageSavedPaymentMethods -> {
}
}
}
Expand Down Expand Up @@ -362,7 +362,10 @@ internal abstract class BaseSheetViewModel(

private fun reportPaymentSheetShown(currentScreen: PaymentSheetScreen) {
when (currentScreen) {
is PaymentSheetScreen.Loading, is PaymentSheetScreen.EditPaymentMethod, is PaymentSheetScreen.Form -> {
is PaymentSheetScreen.Loading,
is PaymentSheetScreen.EditPaymentMethod,
is PaymentSheetScreen.Form,
is PaymentSheetScreen.ManageSavedPaymentMethods -> {
// Nothing to do here
}
is PaymentSheetScreen.SelectSavedPaymentMethods -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,26 @@ class HeaderTextFactoryTest {

assertThat(resource).isEqualTo(R.string.stripe_paymentsheet_choose_payment_method)
}

@Test
fun `Shows correct header for manage saved PMs screen when first opened`() {
val resource = getManagedSavedPaymentMethodsHeaderText(isCompleteFlow = true)

assertThat(resource).isEqualTo(R.string.stripe_paymentsheet_select_payment_method)
}

@Test
fun `Shows correct header for manage saved PMs screen when first opened - FlowController`() {
val resource = getManagedSavedPaymentMethodsHeaderText(isCompleteFlow = false)

assertThat(resource).isEqualTo(R.string.stripe_paymentsheet_select_payment_method)
}

private fun getManagedSavedPaymentMethodsHeaderText(isCompleteFlow: Boolean): Int? {
return HeaderTextFactory(isCompleteFlow = isCompleteFlow).create(
screen = PaymentSheetScreen.ManageSavedPaymentMethods,
isWalletEnabled = false,
types = emptyList(),
)
}
}

0 comments on commit b487d88

Please sign in to comment.