Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clean up #9728

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions link/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,7 @@
<string name="stripe_wallet_update_card">Update card</string>
<!-- A text notice shown when the user selects an expired card. -->
<string name="stripe_wallet_update_expired_card_error">This card has expired. Update your card info or choose a different payment method.</string>
<!-- Title for a button that when tapped removes a saved card. -->
<string name="stripe_wallet_remove_card">Remove card</string>
<string name="stripe_wallet_expand_accessibility">Change selection</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ sealed class LinkActivityResult : Parcelable {
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
enum class Reason {
BackPressed,
LoggedOut
LoggedOut,
PayAnotherWay
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class LinkAnalyticsHelper @Inject internal constructor(
LinkActivityResult.Canceled.Reason.LoggedOut -> {
linkEventsReporter.onPopupLogout()
}
LinkActivityResult.Canceled.Reason.PayAnotherWay -> Unit
}
}

Expand Down
26 changes: 18 additions & 8 deletions link/src/main/java/com/stripe/android/link/ui/LinkContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ internal fun LinkContent(
Screens(
navController = navController,
goBack = viewModel::goBack,
onUpdateSheetContent = onUpdateSheetContent,
navigateAndClearStack = { screen ->
viewModel.navigate(screen, clearStack = true)
},
Expand All @@ -113,6 +114,7 @@ internal fun LinkContent(
private fun Screens(
navController: NavHostController,
getLinkAccount: () -> LinkAccount?,
onUpdateSheetContent: (BottomSheetContent?) -> Unit,
goBack: () -> Unit,
navigateAndClearStack: (route: LinkScreen) -> Unit,
dismissWithResult: (LinkActivityResult) -> Unit
Expand All @@ -122,13 +124,7 @@ private fun Screens(
startDestination = LinkScreen.Loading.route
) {
composable(LinkScreen.Loading.route) {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
Loader()
}

composable(LinkScreen.SignUp.route) {
Expand Down Expand Up @@ -166,7 +162,10 @@ private fun Screens(
dismissWithResult = dismissWithResult
)
}
WalletScreen(viewModel)
WalletScreen(
viewModel = viewModel,
showBottomSheetContent = onUpdateSheetContent
)
}

composable(LinkScreen.CardEdit.route) {
Expand All @@ -178,3 +177,14 @@ private fun Screens(
}
}
}

@Composable
private fun Loader() {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
CircularProgressIndicator()
}
}
44 changes: 44 additions & 0 deletions link/src/main/java/com/stripe/android/link/ui/PrimaryButton.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.material.Icon
import androidx.compose.material.LocalContentAlpha
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Alignment
Expand All @@ -26,10 +27,15 @@ import androidx.compose.ui.semantics.testTag
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.stripe.android.core.strings.resolvableString
import com.stripe.android.link.theme.DefaultLinkTheme
import com.stripe.android.link.theme.PrimaryButtonHeight
import com.stripe.android.link.theme.linkColors
import com.stripe.android.link.theme.linkShapes
import com.stripe.android.model.PaymentIntent
import com.stripe.android.model.SetupIntent
import com.stripe.android.model.StripeIntent
import com.stripe.android.ui.core.Amount
import com.stripe.android.ui.core.R

@Composable
Expand Down Expand Up @@ -121,6 +127,44 @@ private fun PrimaryButtonIcon(
}
}

@Composable
internal fun SecondaryButton(
enabled: Boolean,
label: String,
onClick: () -> Unit
) {
TextButton(
onClick = onClick,
modifier = Modifier
.fillMaxWidth()
.height(PrimaryButtonHeight),
enabled = enabled,
shape = MaterialTheme.linkShapes.medium,
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.secondary,
disabledBackgroundColor = MaterialTheme.colors.secondary
)
) {
Text(
text = label,
color = MaterialTheme.linkColors.secondaryButtonLabel
.copy(alpha = if (enabled) ContentAlpha.high else ContentAlpha.disabled)
)
}
}

internal fun completePaymentButtonLabel(
stripeIntent: StripeIntent,
) = when (stripeIntent) {
is PaymentIntent -> {
Amount(
requireNotNull(stripeIntent.amount),
requireNotNull(stripeIntent.currency)
).buildPayButtonLabel()
}
is SetupIntent -> R.string.stripe_setup_button_label.resolvableString
}

/**
* Represent the possible states for the primary button on a Link screen.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.stripe.android.link.ui.menus

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.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.res.stringResource
import androidx.compose.ui.unit.dp
import com.stripe.android.link.theme.HorizontalPadding
import com.stripe.android.link.theme.MinimumTouchTargetSize
import com.stripe.android.link.theme.linkColors

/**
* An item to be displayed in a [LinkMenu].
*
* @property textResId The resource ID of the text of the item
* @property isDestructive Whether this item should be rendered with the error text color
*/
internal interface LinkMenuItem {
val textResId: Int
val isDestructive: Boolean
}

/**
* Displays a generic bottom sheet with the provided [items].
*
* @param items The list of items that implement [LinkMenuItem]
* @param onItemPress Called when an item in the list is pressed
*/
@Composable
internal fun <T : LinkMenuItem> LinkMenu(
modifier: Modifier = Modifier,
items: List<T>,
onItemPress: (T) -> Unit
) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(vertical = 10.dp)
) {
for (item in items) {
LinkBottomSheetRow(
item = item,
modifier = Modifier.clickable {
onItemPress(item)
}
)
}
}
}

@Composable
private fun <T : LinkMenuItem> LinkBottomSheetRow(
item: T,
modifier: Modifier = Modifier
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = modifier
.height(MinimumTouchTargetSize)
.fillMaxWidth()
) {
Text(
text = stringResource(item.textResId),
color = if (item.isDestructive) {
MaterialTheme.linkColors.errorText
} else {
Color.Unspecified
},
modifier = Modifier.padding(horizontal = HorizontalPadding)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ private fun MenuAndLoader(
)
} else {
IconButton(
modifier = Modifier
.testTag(WALLET_PAYMENT_DETAIL_ITEM_MENU_BUTTON),
onClick = onMenuButtonClick,
enabled = enabled
) {
Expand Down Expand Up @@ -259,3 +261,4 @@ private fun RowScope.BankAccountInfo(
}

internal const val WALLET_PAYMENT_DETAIL_ITEM_RADIO_BUTTON = "wallet_payment_detail_item_radio_button"
internal const val WALLET_PAYMENT_DETAIL_ITEM_MENU_BUTTON = "wallet_payment_detail_item_menu_button"
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.stripe.android.link.ui.wallet

import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.stripe.android.link.R
import com.stripe.android.link.ui.menus.LinkMenu
import com.stripe.android.link.ui.menus.LinkMenuItem
import com.stripe.android.model.ConsumerPaymentDetails
import com.stripe.android.R as StripeR

@Composable
internal fun WalletPaymentMethodMenu(
modifier: Modifier = Modifier,
paymentDetails: ConsumerPaymentDetails.PaymentDetails,
onEditClick: () -> Unit,
onSetDefaultClick: () -> Unit,
onRemoveClick: () -> Unit,
onCancelClick: () -> Unit
) {
val items = remember {
buildList {
if (paymentDetails is ConsumerPaymentDetails.Card) {
add(WalletPaymentMethodMenuItem.EditCard)
}

if (!paymentDetails.isDefault) {
add(WalletPaymentMethodMenuItem.SetAsDefault)
}

add(WalletPaymentMethodMenuItem.RemoveItem(textResId = paymentDetails.removeLabel))
add(WalletPaymentMethodMenuItem.Cancel)
}
}

LinkMenu(
modifier = modifier,
items = items,
onItemPress = { item ->
when (item) {
is WalletPaymentMethodMenuItem.EditCard -> onEditClick()
is WalletPaymentMethodMenuItem.SetAsDefault -> onSetDefaultClick()
is WalletPaymentMethodMenuItem.RemoveItem -> onRemoveClick()
is WalletPaymentMethodMenuItem.Cancel -> onCancelClick()
}
}
)
}

internal sealed class WalletPaymentMethodMenuItem(
override val textResId: Int,
override val isDestructive: Boolean = false
) : LinkMenuItem {

data class RemoveItem(
@StringRes override val textResId: Int
) : WalletPaymentMethodMenuItem(textResId, true)

data object EditCard : WalletPaymentMethodMenuItem(
textResId = R.string.stripe_wallet_update_card
)

data object SetAsDefault : WalletPaymentMethodMenuItem(
textResId = R.string.stripe_wallet_set_as_default
)

data object Cancel : WalletPaymentMethodMenuItem(
textResId = StripeR.string.stripe_cancel
)
}

internal val ConsumerPaymentDetails.PaymentDetails.removeLabel
get() = when (this) {
is ConsumerPaymentDetails.Card,
is ConsumerPaymentDetails.Passthrough -> R.string.stripe_wallet_remove_card
is ConsumerPaymentDetails.BankAccount -> R.string.stripe_wallet_remove_linked_account
}
Loading
Loading