Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
30d773b
Remove `viewStateData` from controller
samiuelson Nov 8, 2024
c82041e
Remove unused code
samiuelson Nov 12, 2024
3c7e865
Map `LoadingData`, `ReFetchingOrder`, `SharingReceipt`
samiuelson Nov 12, 2024
9ac5473
Merge branch `custom-payment-ui-3`
samiuelson Nov 12, 2024
eba0921
Map `CollectingInteracRefund` state
samiuelson Nov 12, 2024
df10576
Map `InteracRefundFailure` state
samiuelson Nov 12, 2024
344a206
Remove unused code
samiuelson Nov 12, 2024
f230590
Map `InteracRefundSuccessful` state
samiuelson Nov 12, 2024
e64953c
Map `LoadingData` state
samiuelson Nov 12, 2024
e448276
Map `ProcessingInteracRefund` state
samiuelson Nov 13, 2024
c07402d
Map `BuiltInReaderCollectPaymentState`, `ExternalReaderCollectPayment…
samiuelson Nov 13, 2024
efe8d43
Map `BuiltInReaderPaymentCapturing`, `ExternalReaderPaymentCapturing`…
samiuelson Nov 13, 2024
26a8039
Map `BuiltInReaderFailedPayment` state
samiuelson Nov 13, 2024
92e2c6b
Map `PrintingReceipt` state
samiuelson Nov 13, 2024
bbcb048
Map `ProcessingPayment` states
samiuelson Nov 13, 2024
0202072
Map `ExternalReaderPaymentSuccessfulReceiptSentAutomatically` state
samiuelson Nov 13, 2024
47e8b10
Map `ExternalReaderFailedPayment` state
samiuelson Nov 13, 2024
deb2e31
Map `BuiltInReaderPaymentSuccessfulReceiptSentAutomatically` state
samiuelson Nov 13, 2024
f749270
Map `ExternalReaderPaymentSuccessfulState` state
samiuelson Nov 13, 2024
1351e2e
Map `BuiltInReaderPaymentSuccessful` state
samiuelson Nov 13, 2024
f58ce86
Clean up code
samiuelson Nov 13, 2024
09ff678
Merge branch `custom-payment-ui-3`
samiuelson Nov 13, 2024
01f7698
Fix mapping of `BuiltInReaderFailedPayment` in case `onRetry` is not …
samiuelson Nov 14, 2024
9daf9a6
Fix card reader hint mapping
samiuelson Nov 14, 2024
a920a36
Add missing `secondaryLabel` to failedPaymentState
samiuelson Nov 14, 2024
487f78c
Satisfy detekt's complaints
samiuelson Nov 14, 2024
71e5b37
Merge branch 'custom-payment-ui-3' into custom-payment-ui-4
samiuelson Nov 14, 2024
778491e
Merge branch 'custom-payment-ui-3' into custom-payment-ui-4
samiuelson Nov 15, 2024
0d3565b
Narrow down available `InteracRefundFailure` sub-types
samiuelson Nov 19, 2024
a99ef64
Narrow down available `PaymentFailed` sub-types
samiuelson Nov 22, 2024
b224639
Update `CardReaderPaymentStateProvider` for new sub-types
samiuelson Nov 25, 2024
54425a3
Merge branch 'feature/custom-payment-ui' into custom-payment-ui-4
samiuelson Nov 25, 2024
8d05436
Clean up code formatting
samiuelson Nov 25, 2024
1434aa2
Clean up code - extract functions
samiuelson Nov 25, 2024
9f747a8
Clean up code - extract functions
samiuelson Nov 25, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
package com.woocommerce.android.ui.payments.cardreader.payment

import com.woocommerce.android.R
import com.woocommerce.android.model.UiString
import com.woocommerce.android.ui.payments.cardreader.onboarding.CardReaderType
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderInteracRefundState
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.CollectingPayment
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.LoadingData
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.PaymentCapturing
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.PaymentFailed
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.PaymentSuccessful
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.PrintingReceipt
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.ProcessingPayment
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.ReFetchingOrder
import com.woocommerce.android.ui.payments.cardreader.payment.controller.CardReaderPaymentOrRefundState.CardReaderPaymentState.SharingReceipt
import javax.inject.Inject

class CardReaderPaymentStateToViewStateMapper @Inject constructor(
private val cardReaderPaymentReaderTypeStateProvider: CardReaderPaymentReaderTypeStateProvider,
) {
@Suppress("LongMethod", "CyclomaticComplexMethod")
operator fun invoke(): (CardReaderPaymentOrRefundState) -> ViewState = { paymentState ->
when (paymentState) {
is CardReaderInteracRefundState.CollectingInteracRefund -> {
ViewState.CollectRefundState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
onSecondaryActionClicked = paymentState.onCancel,
hintLabel = paymentState.cardReaderHint
?: R.string.card_reader_interac_refund_refund_payment_hint,
)
}
is CardReaderInteracRefundState.InteracRefundFailure -> {
provideViewStateFor(paymentState)
}
is CardReaderInteracRefundState.InteracRefundSuccessful -> {
ViewState.RefundSuccessfulState(paymentState.amountWithCurrencyLabel)
}
is CardReaderInteracRefundState.LoadingData -> {
ViewState.RefundLoadingDataState(paymentState.onCancel)
}
is CardReaderInteracRefundState.ProcessingInteracRefund -> {
ViewState.ProcessingRefundState(paymentState.amountWithCurrencyLabel)
}
is CollectingPayment.BuiltInReaderCollectPaymentState -> {
ViewState.BuiltInReaderCollectPaymentState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
hintLabel = paymentState.cardReaderHint
?: R.string.card_reader_payment_collect_payment_built_in_hint
)
}
is CollectingPayment.ExternalReaderCollectPaymentState -> {
ViewState.ExternalReaderCollectPaymentState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
hintLabel = paymentState.cardReaderHint
?: R.string.card_reader_payment_collect_payment_hint,
onSecondaryActionClicked = paymentState.onCancel
)
}
is LoadingData -> ViewState.LoadingDataState(paymentState.onCancel)
is PaymentCapturing.BuiltInReaderPaymentCapturing -> {
ViewState.BuiltInReaderCapturingPaymentState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
)
}
is PaymentCapturing.ExternalReaderPaymentCapturing -> {
ViewState.ExternalReaderCapturingPaymentState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
)
}
is PaymentFailed.BuiltInReaderFailedPayment -> {
provideViewStateFor(paymentState)
}
is PaymentFailed.ExternalReaderFailedPayment -> {
provideViewStateFor(paymentState)
}
is PaymentSuccessful.BuiltInReaderPaymentSuccessful -> {
ViewState.BuiltInReaderPaymentSuccessfulState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
onPrimaryActionClicked = paymentState.onPrintReceiptClicked,
onSecondaryActionClicked = paymentState.onSendReceiptClicked,
onTertiaryActionClicked = paymentState.onSaveUserClicked,
)
}
is PaymentSuccessful.BuiltInReaderPaymentSuccessfulReceiptSentAutomatically -> {
provideViewStateFor(paymentState)
}
is PaymentSuccessful.ExternalReaderPaymentSuccessful -> {
ViewState.ExternalReaderPaymentSuccessfulState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
onPrimaryActionClicked = paymentState.onPrintReceiptClicked,
onSecondaryActionClicked = paymentState.onSendReceiptClicked,
onTertiaryActionClicked = paymentState.onSaveUserClicked,
)
}
is PaymentSuccessful.ExternalReaderPaymentSuccessfulReceiptSentAutomatically -> {
provideViewStateFor(paymentState)
}
is PrintingReceipt -> ViewState.PrintingReceiptState(paymentState.amountWithCurrencyLabel)
is ProcessingPayment.BuiltInReaderProcessingPayment -> {
ViewState.BuiltInReaderProcessingPaymentState(paymentState.amountWithCurrencyLabel)
}
is ProcessingPayment.ExternalReaderProcessingPayment -> {
ViewState.ExternalReaderProcessingPaymentState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
onSecondaryActionClicked = paymentState.onCancel
)
}
ReFetchingOrder -> ViewState.ReFetchingOrderState
SharingReceipt -> ViewState.SharingReceiptState
}
}

private fun provideViewStateFor(
paymentState: CardReaderInteracRefundState.InteracRefundFailure
): ViewState = when (paymentState) {
is CardReaderInteracRefundState.InteracRefundFailure.Cancelable -> {
provideViewStateFor(paymentState)
}

is CardReaderInteracRefundState.InteracRefundFailure.NonCancelable -> {
ViewState.FailedRefundState(
errorType = paymentState.errorType,
primaryLabel = R.string.try_again,
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
onPrimaryActionClicked = paymentState.onRetry,
)
}
}

private fun provideViewStateFor(
paymentState: CardReaderInteracRefundState.InteracRefundFailure.Cancelable
): ViewState =
if (paymentState.onRetry == null) {
if (paymentState.cta != null) {
ViewState.FailedRefundState(
errorType = paymentState.errorType,
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = paymentState.cta.label,
onPrimaryActionClicked = paymentState.cta.onCallToActionTapped,
secondaryLabel = R.string.cancel,
onSecondaryActionClicked = paymentState.onCancel,
)
} else {
ViewState.FailedRefundState(
errorType = paymentState.errorType,
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.card_reader_interac_refund_refund_failed_ok,
onPrimaryActionClicked = paymentState.onCancel,
)
}
} else {
ViewState.FailedRefundState(
errorType = paymentState.errorType,
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.try_again,
onPrimaryActionClicked = paymentState.onRetry,
secondaryLabel = R.string.cancel,
onSecondaryActionClicked = paymentState.onCancel,
)
}

private fun provideViewStateFor(
paymentState: PaymentFailed.ExternalReaderFailedPayment
): ViewState = when (paymentState) {
is PaymentFailed.ExternalReaderFailedPayment.Cancelable -> {
provideViewStateFor(paymentState)
}

is PaymentFailed.ExternalReaderFailedPayment.NonCancelable -> {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.EXTERNAL,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.try_again,
onPrimaryActionClicked = paymentState.onRetry
)
}
}

private fun provideViewStateFor(
paymentState: PaymentFailed.ExternalReaderFailedPayment.Cancelable
): ViewState =
if (paymentState.cta != null) {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.EXTERNAL,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = paymentState.cta.label,
onPrimaryActionClicked = paymentState.cta.onCallToActionTapped,
secondaryLabel = R.string.cancel,
onSecondaryActionClicked = paymentState.onCancel,
)
} else {
if (paymentState.onRetry != null) {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.EXTERNAL,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.try_again,
onPrimaryActionClicked = paymentState.onRetry,
secondaryLabel = R.string.cancel,
onSecondaryActionClicked = paymentState.onCancel,
)
} else {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.EXTERNAL,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.card_reader_payment_payment_failed_ok,
onPrimaryActionClicked = paymentState.onCancel!!,
)
}
}

private fun provideViewStateFor(
paymentState: PaymentFailed.BuiltInReaderFailedPayment
): ViewState = when (paymentState) {
is PaymentFailed.BuiltInReaderFailedPayment.Cancelable -> {
provideViewStateFor(paymentState)
}

is PaymentFailed.BuiltInReaderFailedPayment.NonCancelable -> {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.BUILT_IN,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.try_again,
onPrimaryActionClicked = paymentState.onRetry,
)
}
}

private fun provideViewStateFor(
paymentState: PaymentFailed.BuiltInReaderFailedPayment.Cancelable
): ViewState =
if (paymentState.cta != null) {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.BUILT_IN,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = paymentState.cta.label,
onPrimaryActionClicked = paymentState.cta.onCallToActionTapped,
secondaryLabel = R.string.cancel,
onSecondaryActionClicked = paymentState.onCancel,
)
} else {
if (paymentState.onRetry != null) {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.BUILT_IN,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.try_again,
onPrimaryActionClicked = paymentState.onRetry,
onSecondaryActionClicked = paymentState.onCancel,
secondaryLabel = R.string.cancel,
)
} else {
cardReaderPaymentReaderTypeStateProvider.provideFailedPaymentState(
cardReaderType = CardReaderType.BUILT_IN,
errorType = paymentState.errorType,
amountLabel = paymentState.amountWithCurrencyLabel,
primaryLabel = R.string.card_reader_payment_payment_failed_ok,
onPrimaryActionClicked = paymentState.onCancel,
)
}
}

private fun provideViewStateFor(
paymentState: PaymentSuccessful.BuiltInReaderPaymentSuccessfulReceiptSentAutomatically
): ViewState.BuiltInReaderPaymentSuccessfulReceiptSentAutomaticallyState {
val receiptSentHint = UiString.UiStringRes(
R.string.card_reader_payment_reader_receipt_sent,
listOf(UiString.UiStringText(paymentState.recipientEmail)),
true
)
return ViewState.BuiltInReaderPaymentSuccessfulReceiptSentAutomaticallyState(
amountWithCurrencyLabel = paymentState.amountWithCurrencyLabel,
receiptSentAutomaticallyHint = receiptSentHint,
onPrimaryActionClicked = paymentState.onPrintReceiptClicked,
onTertiaryActionClicked = paymentState.onSaveUserClicked,
)
}

private fun provideViewStateFor(
paymentState: PaymentSuccessful.ExternalReaderPaymentSuccessfulReceiptSentAutomatically
): ViewState {
val receiptSentHint = UiString.UiStringRes(
R.string.card_reader_payment_reader_receipt_sent,
listOf(UiString.UiStringText(paymentState.recipientEmail)),
true
)
return cardReaderPaymentReaderTypeStateProvider.providePaymentSuccessfulReceiptSentAutomaticallyState(
cardReaderType = CardReaderType.EXTERNAL,
amountLabel = paymentState.amountWithCurrencyLabel,
receiptSentHint = receiptSentHint,
onSaveUserClicked = paymentState.onSaveUserClicked,
onPrintReceiptClicked = paymentState.onPrintReceiptClicked,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.woocommerce.android.viewmodel.MultiLiveEvent
import com.woocommerce.android.viewmodel.ScopedViewModel
import com.woocommerce.android.viewmodel.navArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.map
import org.wordpress.android.fluxc.store.WooCommerceStore
import javax.inject.Inject

Expand All @@ -50,13 +51,13 @@ class CardReaderPaymentViewModel @Inject constructor(
wooStore: WooCommerceStore,
dispatchers: CoroutineDispatchers,
cardReaderTrackingInfoKeeper: CardReaderTrackingInfoKeeper,
cardReaderPaymentReaderTypeStateProvider: CardReaderPaymentReaderTypeStateProvider,
paymentStateProvider: CardReaderPaymentStateProvider,
cardReaderPaymentOrderHelper: CardReaderPaymentOrderHelper,
paymentReceiptHelper: PaymentReceiptHelper,
cardReaderOnboardingChecker: CardReaderOnboardingChecker,
cardReaderConfigProvider: CardReaderCountryConfigProvider,
paymentReceiptShare: PaymentReceiptShare,
paymentStateMapper: CardReaderPaymentStateToViewStateMapper,
) : ScopedViewModel(savedState) {
private val arguments: CardReaderPaymentDialogFragmentArgs by savedState.navArgs()

Expand All @@ -82,7 +83,6 @@ class CardReaderPaymentViewModel @Inject constructor(
wooStore = wooStore,
dispatchers = dispatchers,
cardReaderTrackingInfoKeeper = cardReaderTrackingInfoKeeper,
cardReaderPaymentReaderTypeStateProvider = cardReaderPaymentReaderTypeStateProvider,
paymentStateProvider = paymentStateProvider,
cardReaderPaymentOrderHelper = cardReaderPaymentOrderHelper,
paymentReceiptHelper = paymentReceiptHelper,
Expand All @@ -94,8 +94,8 @@ class CardReaderPaymentViewModel @Inject constructor(
isTTPPaymentInProgress = ::isTTPPaymentInProgress,
)

@Suppress("DEPRECATION")
val viewStateData: LiveData<ViewState> = paymentController.viewStateData
val viewStateData: LiveData<ViewState> =
paymentController.paymentState.map(paymentStateMapper()).asLiveData(coroutineContext)

override val event: LiveData<MultiLiveEvent.Event> =
paymentController.event.asLiveData(coroutineContext).map {
Expand Down
Loading
Loading