Skip to content

Commit 6011a6d

Browse files
committed
Move loading state to GooglePayView
Previously, the GooglePayView was replaced with ProcessingPaymentView. This causes the Activity Result API to fail and not deliver the result in case the view got recreated on configuration change. By keeping the GooglePayView in view it will be able to successfully restore it's state and deliver the activity result. Making the loading state part of the GooglePayView is essential to fix this problem. COAND-941
1 parent 06ca180 commit 6011a6d

File tree

7 files changed

+47
-12
lines changed

7 files changed

+47
-12
lines changed

googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegate.kt

+5-2
Original file line numberDiff line numberDiff line change
@@ -135,19 +135,22 @@ internal class DefaultGooglePayDelegate(
135135

136136
private fun updateOutputData(
137137
isButtonVisible: Boolean = this.outputData.isButtonVisible,
138+
isLoading: Boolean = this.outputData.isLoading,
138139
paymentData: PaymentData? = this.outputData.paymentData,
139140
) {
140-
val newOutputData = createOutputData(isButtonVisible, paymentData)
141+
val newOutputData = createOutputData(isButtonVisible, isLoading, paymentData)
141142
_outputDataFlow.tryEmit(newOutputData)
142143
updateComponentState(newOutputData)
143144
}
144145

145146
private fun createOutputData(
146147
isButtonVisible: Boolean = componentParams.isSubmitButtonVisible,
148+
isLoading: Boolean = !isButtonVisible,
147149
paymentData: PaymentData? = null,
148150
): GooglePayOutputData {
149151
return GooglePayOutputData(
150152
isButtonVisible = isButtonVisible,
153+
isLoading = isLoading,
151154
paymentData = paymentData,
152155
)
153156
}
@@ -204,7 +207,7 @@ internal class DefaultGooglePayDelegate(
204207
override fun onSubmit() {
205208
adyenLog(AdyenLogLevel.DEBUG) { "onSubmit" }
206209

207-
_viewFlow.tryEmit(PaymentInProgressViewType)
210+
updateOutputData(isButtonVisible = false, isLoading = true)
208211

209212
val paymentDataRequest = GooglePayUtils.createPaymentDataRequest(componentParams)
210213
val paymentDataTask = paymentsClient.loadPaymentData(paymentDataRequest)

googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/GooglePayView.kt

+16
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@ import android.util.AttributeSet
1313
import android.view.LayoutInflater
1414
import android.view.View
1515
import android.widget.FrameLayout
16+
import androidx.core.view.isVisible
1617
import com.adyen.checkout.components.core.internal.ui.ComponentDelegate
1718
import com.adyen.checkout.googlepay.databinding.ViewGooglePayBinding
19+
import com.adyen.checkout.googlepay.internal.ui.model.GooglePayOutputData
1820
import com.adyen.checkout.ui.core.internal.ui.ComponentView
1921
import kotlinx.coroutines.CoroutineScope
22+
import kotlinx.coroutines.flow.launchIn
23+
import kotlinx.coroutines.flow.onEach
2024

2125
internal class GooglePayView
2226
@JvmOverloads
@@ -41,12 +45,24 @@ internal constructor(
4145
require(delegate is GooglePayDelegate) { "Unsupported delegate type" }
4246
this.delegate = delegate
4347
initializeFragment(delegate)
48+
49+
observeDelegate(delegate, coroutineScope)
4450
}
4551

4652
private fun initializeFragment(delegate: GooglePayDelegate) {
4753
binding.fragmentContainer.getFragment<GooglePayFragment?>()?.initialize(delegate)
4854
}
4955

56+
private fun observeDelegate(delegate: GooglePayDelegate, coroutineScope: CoroutineScope) {
57+
delegate.outputDataFlow
58+
.onEach { outputDataChanged(it) }
59+
.launchIn(coroutineScope)
60+
}
61+
62+
private fun outputDataChanged(outputData: GooglePayOutputData) {
63+
binding.processingPaymentView.isVisible = outputData.isLoading
64+
}
65+
5066
override fun highlightValidationErrors() = Unit
5167

5268
override fun getView(): View = this

googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/GooglePayViewProvider.kt

-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import com.adyen.checkout.ui.core.internal.ui.ComponentView
1616
import com.adyen.checkout.ui.core.internal.ui.ComponentViewType
1717
import com.adyen.checkout.ui.core.internal.ui.ViewProvider
1818
import com.adyen.checkout.ui.core.internal.ui.view.PayButton
19-
import com.adyen.checkout.ui.core.internal.ui.view.ProcessingPaymentView
2019

2120
internal class GooglePayViewProvider : ViewProvider {
2221

@@ -25,7 +24,6 @@ internal class GooglePayViewProvider : ViewProvider {
2524
context: Context,
2625
): ComponentView = when (viewType) {
2726
GooglePayComponentViewType -> GooglePayView(context)
28-
PaymentInProgressViewType -> ProcessingPaymentView(context)
2927
else -> throw IllegalArgumentException("Unsupported view type")
3028
}
3129

@@ -34,7 +32,6 @@ internal class GooglePayViewProvider : ViewProvider {
3432
layoutInflater: LayoutInflater
3533
): ComponentView = when (viewType) {
3634
GooglePayComponentViewType -> GooglePayView(layoutInflater)
37-
PaymentInProgressViewType -> ProcessingPaymentView(layoutInflater.context)
3835
else -> throw IllegalArgumentException("Unsupported view type")
3936
}
4037
}
@@ -50,8 +47,3 @@ internal object GooglePayComponentViewType : ButtonComponentViewType {
5047

5148
override val buttonTextResId: Int = ButtonComponentViewType.DEFAULT_BUTTON_TEXT_RES_ID
5249
}
53-
54-
internal object PaymentInProgressViewType : ComponentViewType {
55-
56-
override val viewProvider: ViewProvider get() = GooglePayViewProvider()
57-
}

googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/model/GooglePayOutputData.kt

+1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ import com.google.android.gms.wallet.PaymentData
1212

1313
internal data class GooglePayOutputData(
1414
val isButtonVisible: Boolean,
15+
val isLoading: Boolean,
1516
val paymentData: PaymentData?,
1617
)

googlepay/src/main/res/layout/view_google_pay.xml

+8
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,12 @@
2020
android:layout_width="match_parent"
2121
android:layout_height="wrap_content" />
2222

23+
<!-- ProcessingPaymentView has a RestrictTo annotation, but is actually available -->
24+
<!--suppress AndroidUnresolvableTag -->
25+
<com.adyen.checkout.ui.core.internal.ui.view.ProcessingPaymentView
26+
android:id="@+id/processingPaymentView"
27+
android:layout_width="match_parent"
28+
android:layout_height="wrap_content"
29+
android:visibility="gone" />
30+
2331
</merge>

googlepay/src/test/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegateTest.kt

+14-1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ internal class DefaultGooglePayDelegateTest(
158158
assertEquals(task, payEventFlow.latestValue)
159159
}
160160

161+
@Test
162+
fun `when onSubmit is called, then button is hidden and loading state is shown`() = runTest {
163+
val outputDataFlow = delegate.outputDataFlow.test(testScheduler)
164+
delegate.initialize(CoroutineScope(UnconfinedTestDispatcher()))
165+
166+
delegate.onSubmit()
167+
168+
val latestOutputData = outputDataFlow.latestValue
169+
assertFalse(latestOutputData.isButtonVisible)
170+
assertTrue(latestOutputData.isLoading)
171+
}
172+
161173
@ParameterizedTest
162174
@MethodSource("amountSource")
163175
fun `when input data is valid then amount is propagated in component state if set`(
@@ -353,8 +365,9 @@ internal class DefaultGooglePayDelegateTest(
353365

354366
private fun createOutputData(
355367
isButtonVisible: Boolean = false,
368+
isLoading: Boolean = !isButtonVisible,
356369
paymentData: PaymentData? = null,
357-
) = GooglePayOutputData(isButtonVisible, paymentData)
370+
) = GooglePayOutputData(isButtonVisible, isLoading, paymentData)
358371

359372
companion object {
360373
private val TEST_ORDER = OrderRequest("PSP", "ORDER_DATA")

ui-core/src/main/java/com/adyen/checkout/ui/core/internal/ui/view/ProcessingPaymentView.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import com.adyen.checkout.ui.core.internal.util.setLocalizedTextFromStyle
2323
import kotlinx.coroutines.CoroutineScope
2424

2525
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
26-
class ProcessingPaymentView @JvmOverloads constructor(
26+
class ProcessingPaymentView
27+
@JvmOverloads
28+
constructor(
2729
context: Context,
2830
attrs: AttributeSet? = null,
2931
defStyleAttr: Int = 0,

0 commit comments

Comments
 (0)