Skip to content

Commit

Permalink
feat(POM-442): Extend screens customization options (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
vitalii-vanziak-cko authored Jan 9, 2025
1 parent 0842b8d commit f6b3177
Show file tree
Hide file tree
Showing 28 changed files with 559 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import com.processout.sdk.core.ProcessOutActivityResult
import com.processout.sdk.core.onFailure
import com.processout.sdk.core.onSuccess
import com.processout.sdk.ui.card.tokenization.POCardTokenizationConfiguration
import com.processout.sdk.ui.card.tokenization.POCardTokenizationConfiguration.SubmitButton
import com.processout.sdk.ui.card.tokenization.POCardTokenizationLauncher
import com.processout.sdk.ui.shared.view.dialog.POAlertDialog
import com.processout.sdk.ui.threeds.PO3DSRedirectCustomTabLauncher
Expand Down Expand Up @@ -98,7 +99,8 @@ class CardPaymentFragment : BaseFragment<FragmentCardPaymentBinding>(
viewModel.onTokenizing()
launcher.launch(
POCardTokenizationConfiguration(
savingAllowed = true
savingAllowed = true,
submitButton = SubmitButton()
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import com.processout.sdk.core.onSuccess
import com.processout.sdk.ui.checkout.PODynamicCheckoutConfiguration
import com.processout.sdk.ui.checkout.PODynamicCheckoutConfiguration.AlternativePaymentConfiguration
import com.processout.sdk.ui.checkout.PODynamicCheckoutConfiguration.AlternativePaymentConfiguration.PaymentConfirmationConfiguration
import com.processout.sdk.ui.checkout.PODynamicCheckoutConfiguration.AlternativePaymentConfiguration.PaymentConfirmationConfiguration.ConfirmButton
import com.processout.sdk.ui.checkout.PODynamicCheckoutConfiguration.SubmitButton
import com.processout.sdk.ui.checkout.PODynamicCheckoutLauncher
import com.processout.sdk.ui.shared.view.dialog.POAlertDialog
import com.processout.sdk.ui.threeds.PO3DSRedirectCustomTabLauncher
Expand Down Expand Up @@ -99,7 +99,7 @@ class DynamicCheckoutFragment : BaseFragment<FragmentDynamicCheckoutBinding>(
alternativePayment = AlternativePaymentConfiguration(
returnUrl = Constants.RETURN_URL,
paymentConfirmation = PaymentConfirmationConfiguration(
confirmButton = ConfirmButton()
confirmButton = SubmitButton()
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.processout.sdk.api.model.response.POCard
import com.processout.sdk.api.model.response.POGooglePayCardTokenizationData
import com.processout.sdk.core.*
import com.processout.sdk.ui.card.update.POCardUpdateConfiguration
import com.processout.sdk.ui.card.update.POCardUpdateConfiguration.*
import com.processout.sdk.ui.card.update.POCardUpdateLauncher
import com.processout.sdk.ui.googlepay.POGooglePayCardTokenizationLauncher
import com.processout.sdk.ui.shared.configuration.POCancellationConfiguration
Expand Down Expand Up @@ -90,15 +91,15 @@ class FeaturesFragment : BaseFragment<FragmentFeaturesBinding>(
cardUpdateLauncher.launch(
POCardUpdateConfiguration(
cardId = card?.id ?: String(),
options = POCardUpdateConfiguration.Options(
cardInformation = POCardUpdateConfiguration.CardInformation(
options = Options(
cardInformation = CardInformation(
maskedNumber = maskedNumber,
iin = card?.iin,
scheme = card?.scheme,
preferredScheme = card?.coScheme
),
submitButton = SubmitButton(),
cancellation = POCancellationConfiguration(
secondaryAction = true,
backPressed = true,
dragDown = true,
touchOutside = false
Expand Down
5 changes: 5 additions & 0 deletions sdk/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,9 @@
<string name="po_cancel_payment_confirmation_confirm">إلغاء الدفع</string>
<string name="po_cancel_payment_confirmation_dismiss">ليس الآن</string>

<!-- Cancel Confirmation -->
<string name="po_cancel_confirmation_title">إلغاء؟</string>
<string name="po_cancel_confirmation_confirm">إلغاء</string>
<string name="po_cancel_confirmation_dismiss">ليس الآن</string>

</resources>
5 changes: 5 additions & 0 deletions sdk/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,9 @@
<string name="po_cancel_payment_confirmation_confirm">Annuler le paiement</string>
<string name="po_cancel_payment_confirmation_dismiss">Pas maintenant</string>

<!-- Cancel Confirmation -->
<string name="po_cancel_confirmation_title">Annuler ?</string>
<string name="po_cancel_confirmation_confirm">Annuler</string>
<string name="po_cancel_confirmation_dismiss">Pas maintenant</string>

</resources>
5 changes: 5 additions & 0 deletions sdk/src/main/res/values-pl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@
<string name="po_cancel_payment_confirmation_confirm">Anuluj płatność</string>
<string name="po_cancel_payment_confirmation_dismiss">Nie teraz</string>

<!-- Cancel Confirmation -->
<string name="po_cancel_confirmation_title">Anulować?</string>
<string name="po_cancel_confirmation_confirm">Anuluj</string>
<string name="po_cancel_confirmation_dismiss">Nie teraz</string>

</resources>
5 changes: 5 additions & 0 deletions sdk/src/main/res/values-pt/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,9 @@
<string name="po_cancel_payment_confirmation_confirm">Cancelar pagamento</string>
<string name="po_cancel_payment_confirmation_dismiss">Agora não</string>

<!-- Cancel Confirmation -->
<string name="po_cancel_confirmation_title">Cancelar?</string>
<string name="po_cancel_confirmation_confirm">Cancelar</string>
<string name="po_cancel_confirmation_dismiss">Agora não</string>

</resources>
5 changes: 5 additions & 0 deletions sdk/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,9 @@
<string name="po_cancel_payment_confirmation_confirm">Cancel payment</string>
<string name="po_cancel_payment_confirmation_dismiss">Not now</string>

<!-- Cancel Confirmation -->
<string name="po_cancel_confirmation_title">Cancel?</string>
<string name="po_cancel_confirmation_confirm">Cancel</string>
<string name="po_cancel_confirmation_dismiss">Not now</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ private fun Actions(
modifier = modifier.fillMaxWidth(),
style = if (primary) primaryActionStyle else secondaryActionStyle,
enabled = enabled,
loading = loading
loading = loading,
iconResId = iconResId
)
if (requestConfirmation) {
confirmation?.run {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.processout.sdk.ui.core.component

import androidx.annotation.DrawableRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.*
Expand All @@ -10,8 +12,10 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
Expand All @@ -21,10 +25,12 @@ import com.processout.sdk.ui.core.component.POButton.border
import com.processout.sdk.ui.core.component.POButton.colors
import com.processout.sdk.ui.core.component.POButton.contentPadding
import com.processout.sdk.ui.core.component.POButton.elevation
import com.processout.sdk.ui.core.extension.conditional
import com.processout.sdk.ui.core.style.POButtonDefaults
import com.processout.sdk.ui.core.style.POButtonStateStyle
import com.processout.sdk.ui.core.style.POButtonStyle
import com.processout.sdk.ui.core.theme.ProcessOutTheme
import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing

/** @suppress */
@ProcessOutInternalApi
Expand All @@ -37,17 +43,19 @@ fun POButton(
enabled: Boolean = true,
loading: Boolean = false,
leadingContent: @Composable RowScope.() -> Unit = {},
@DrawableRes iconResId: Int? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
) {
val pressed by interactionSource.collectIsPressedAsState()
val colors = colors(style = style, enabled = enabled, loading = loading, pressed = pressed)
CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) {
Button(
onClick = onClick,
modifier = modifier.requiredHeightIn(
min = ProcessOutTheme.dimensions.interactiveComponentMinSize
),
enabled = enabled && !loading,
colors = colors(style = style, enabled = enabled, loading = loading, pressed = pressed),
colors = colors,
shape = if (enabled) style.normal.shape else style.disabled.shape,
border = border(style = style, enabled = enabled, pressed = pressed),
elevation = elevation(style = style, enabled = enabled, loading = loading),
Expand All @@ -65,6 +73,19 @@ fun POButton(
}
} else {
leadingContent()
iconResId?.let {
val iconColor = if (enabled) colors.contentColor else colors.disabledContentColor
Image(
painter = painterResource(it),
contentDescription = null,
modifier = Modifier
.conditional(text.isNotBlank()) {
padding(end = spacing.small)
}
.requiredSize(20.dp),
colorFilter = ColorFilter.tint(color = iconColor)
)
}
POText(
text = text,
style = if (enabled) style.normal.text.textStyle else style.disabled.text.textStyle,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.processout.sdk.ui.core.state

import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
import com.processout.sdk.ui.core.annotation.ProcessOutInternalApi

Expand All @@ -12,6 +13,7 @@ data class POActionState(
val primary: Boolean,
val enabled: Boolean = true,
val loading: Boolean = false,
@DrawableRes val iconResId: Int? = null,
val confirmation: Confirmation? = null
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import com.processout.sdk.ui.card.tokenization.CardTokenizationActivityContract.
import com.processout.sdk.ui.card.tokenization.CardTokenizationCompletion.Failure
import com.processout.sdk.ui.card.tokenization.CardTokenizationCompletion.Success
import com.processout.sdk.ui.card.tokenization.CardTokenizationEvent.Dismiss
import com.processout.sdk.ui.card.tokenization.POCardTokenizationConfiguration.SubmitButton
import com.processout.sdk.ui.core.theme.ProcessOutTheme
import com.processout.sdk.ui.shared.component.displayCutoutHeight
import com.processout.sdk.ui.shared.component.screenModeAsState
Expand All @@ -41,7 +42,7 @@ internal class CardTokenizationBottomSheet : BaseBottomSheetDialogFragment<POCar
private val viewModel: CardTokenizationViewModel by viewModels {
CardTokenizationViewModel.Factory(
app = requireActivity().application,
configuration = configuration ?: POCardTokenizationConfiguration(),
configuration = configuration ?: POCardTokenizationConfiguration(submitButton = SubmitButton()),
eventDispatcher = PODefaultEventDispatchers.defaultCardTokenization
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.processout.sdk.api.dispatcher.card.tokenization.PODefaultCardTokeniza
import com.processout.sdk.ui.card.tokenization.CardTokenizationInteractorState.*
import com.processout.sdk.ui.card.tokenization.CardTokenizationViewModelState.*
import com.processout.sdk.ui.core.state.POActionState
import com.processout.sdk.ui.core.state.POActionState.Confirmation
import com.processout.sdk.ui.core.state.POImmutableList
import com.processout.sdk.ui.shared.extension.map
import com.processout.sdk.ui.shared.filter.CardExpirationInputFilter
Expand Down Expand Up @@ -91,17 +92,31 @@ internal class CardTokenizationViewModel private constructor(
focusedFieldId = state.focusedFieldId,
primaryAction = POActionState(
id = state.primaryActionId,
text = primaryActionText ?: app.getString(R.string.po_card_tokenization_button_submit),
text = submitButton.text ?: app.getString(R.string.po_card_tokenization_button_submit),
primary = true,
enabled = state.submitAllowed,
loading = state.submitting
loading = state.submitting,
iconResId = submitButton.iconResId
),
secondaryAction = if (cancellation.secondaryAction) POActionState(
id = state.secondaryActionId,
text = secondaryActionText ?: app.getString(R.string.po_card_tokenization_button_cancel),
primary = false,
enabled = !state.submitting
) else null,
secondaryAction = cancelButton?.let {
POActionState(
id = state.secondaryActionId,
text = it.text ?: app.getString(R.string.po_card_tokenization_button_cancel),
primary = false,
enabled = !state.submitting,
iconResId = it.iconResId,
confirmation = it.confirmation?.run {
Confirmation(
title = title ?: app.getString(R.string.po_cancel_confirmation_title),
message = message,
confirmActionText = confirmActionText
?: app.getString(R.string.po_cancel_confirmation_confirm),
dismissActionText = dismissActionText
?: app.getString(R.string.po_cancel_confirmation_dismiss)
)
}
)
},
draggable = cancellation.dragDown
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.processout.sdk.ui.card.tokenization

import android.os.Parcelable
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import com.processout.sdk.api.model.request.POContact
import com.processout.sdk.ui.card.tokenization.POCardTokenizationConfiguration.BillingAddressConfiguration.CollectionMode
import com.processout.sdk.ui.core.style.*
import com.processout.sdk.ui.shared.configuration.POActionConfirmationConfiguration
import com.processout.sdk.ui.shared.configuration.POCancellationConfiguration
import kotlinx.parcelize.Parcelize

Expand All @@ -16,8 +18,8 @@ import kotlinx.parcelize.Parcelize
* @param[isCardholderNameFieldVisible] Specifies whether the cardholder name field should be displayed. Default value is _true_.
* @param[billingAddress] Allows to customize the collection of billing address.
* @param[savingAllowed] Displays checkbox that allows to save the card details for future payments.
* @param[primaryActionText] Custom primary action text (e.g. "Submit").
* @param[secondaryActionText] Custom secondary action text (e.g. "Cancel").
* @param[submitButton] Submit button configuration.
* @param[cancelButton] Cancel button configuration. Use _null_ to hide.
* @param[cancellation] Specifies cancellation behaviour.
* @param[metadata] Metadata related to the card.
* @param[style] Allows to customize the look and feel.
Expand All @@ -29,13 +31,53 @@ data class POCardTokenizationConfiguration(
val isCardholderNameFieldVisible: Boolean = true,
val billingAddress: BillingAddressConfiguration = BillingAddressConfiguration(),
val savingAllowed: Boolean = false,
val primaryActionText: String? = null,
val secondaryActionText: String? = null,
val submitButton: SubmitButton = SubmitButton(),
val cancelButton: CancelButton? = CancelButton(),
val cancellation: POCancellationConfiguration = POCancellationConfiguration(),
val metadata: Map<String, String>? = null,
val style: Style? = null
) : Parcelable {

/**
* Defines card tokenization configuration.
*
* @param[title] Custom title.
* @param[cvcRequired] Specifies whether the card CVC should be collected. Default value is _true_.
* @param[isCardholderNameFieldVisible] Specifies whether the cardholder name field should be displayed. Default value is _true_.
* @param[billingAddress] Allows to customize the collection of billing address.
* @param[savingAllowed] Displays checkbox that allows to save the card details for future payments.
* @param[primaryActionText] Custom primary action text (e.g. "Submit").
* @param[secondaryActionText] Custom secondary action text (e.g. "Cancel").
* @param[cancellation] Specifies cancellation behaviour.
* @param[metadata] Metadata related to the card.
* @param[style] Allows to customize the look and feel.
*/
@Deprecated(message = "Use alternative constructor.")
constructor(
title: String? = null,
cvcRequired: Boolean = true,
isCardholderNameFieldVisible: Boolean = true,
billingAddress: BillingAddressConfiguration = BillingAddressConfiguration(),
savingAllowed: Boolean = false,
primaryActionText: String? = null,
secondaryActionText: String? = null,
cancellation: POCancellationConfiguration = POCancellationConfiguration(),
metadata: Map<String, String>? = null,
style: Style? = null
) : this(
title = title,
cvcRequired = cvcRequired,
isCardholderNameFieldVisible = isCardholderNameFieldVisible,
billingAddress = billingAddress,
savingAllowed = savingAllowed,
submitButton = SubmitButton(text = primaryActionText),
cancelButton = if (cancellation.secondaryAction)
CancelButton(text = secondaryActionText) else null,
cancellation = cancellation,
metadata = metadata,
style = style
)

/**
* Defines billing address configuration.
*
Expand Down Expand Up @@ -69,6 +111,35 @@ data class POCardTokenizationConfiguration(
}
}

/**
* Submit button configuration.
*
* @param[text] Button text. Pass _null_ to use default text.
* @param[iconResId] Button icon drawable resource ID. Pass _null_ to hide.
*/
@Parcelize
data class SubmitButton(
val text: String? = null,
@DrawableRes
val iconResId: Int? = null
) : Parcelable

/**
* Cancel button configuration.
*
* @param[text] Button text. Pass _null_ to use default text.
* @param[iconResId] Button icon drawable resource ID. Pass _null_ to hide.
* @param[confirmation] Specifies action confirmation configuration (e.g. dialog).
* Use _null_ to disable, this is a default behaviour.
*/
@Parcelize
data class CancelButton(
val text: String? = null,
@DrawableRes
val iconResId: Int? = null,
val confirmation: POActionConfirmationConfiguration? = null
) : Parcelable

/**
* Allows to customize the look and feel.
*
Expand Down
Loading

0 comments on commit f6b3177

Please sign in to comment.