diff --git a/CHANGELOG.md b/CHANGELOG.md index a423eace3cd..8162d91c7fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## XX.XX.XX - 20XX-XX-XX +### AddressElement +* [FIXED][8596](https://github.com/stripe/stripe-android/pull/8596) Fixed issue where "Enter address manually" button only worked the first time it was clicked. + ### Payments * [FIXED][8590](https://github.com/stripe/stripe-android/pull/8590) Fix an issue where cancelling payment for Amazon Pay and Cash App Pay would show an error diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressElementNavigator.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressElementNavigator.kt index 938714a007e..b54bc7fecf8 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressElementNavigator.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AddressElementNavigator.kt @@ -41,4 +41,8 @@ internal class AddressElementNavigator @Inject constructor() { } } } + + companion object { + internal const val FORCE_EXPANDED_FORM_KEY = "force_expanded_form" + } } diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt index a3e810a4232..4243e2314b3 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/AutocompleteViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.stripe.android.paymentsheet.PaymentSheet +import com.stripe.android.paymentsheet.addresselement.AddressElementNavigator.Companion.FORCE_EXPANDED_FORM_KEY import com.stripe.android.paymentsheet.addresselement.analytics.AddressLauncherEventReporter import com.stripe.android.paymentsheet.injection.AutocompleteViewModelSubcomponent import com.stripe.android.ui.core.elements.autocomplete.PlacesClientProxy @@ -150,6 +151,7 @@ internal class AutocompleteViewModel @Inject constructor( } fun onEnterAddressManually() { + navigator.setResult(FORCE_EXPANDED_FORM_KEY, true) setResultAndGoBack( AddressDetails( address = PaymentSheet.Address( diff --git a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt index c02cc1a45fa..b43333649b9 100644 --- a/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt +++ b/paymentsheet/src/main/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModel.kt @@ -10,6 +10,7 @@ import com.stripe.android.paymentsheet.injection.InputAddressViewModelSubcompone import com.stripe.android.ui.core.elements.LayoutSpec import com.stripe.android.uicore.elements.IdentifierSpec import com.stripe.android.uicore.forms.FormFieldEntry +import com.stripe.android.uicore.utils.combineAsStateFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch @@ -25,6 +26,9 @@ internal class InputAddressViewModel @Inject constructor( private val _collectedAddress = MutableStateFlow(args.config?.address) val collectedAddress: StateFlow = _collectedAddress + private val _forceExpandedForm = MutableStateFlow(false) + private val forceExpandedForm: StateFlow = _forceExpandedForm + private val _formController = MutableStateFlow(null) val formController: StateFlow = _formController @@ -50,7 +54,21 @@ internal class InputAddressViewModel @Inject constructor( } viewModelScope.launch { - collectedAddress.collect { addressDetails -> + navigator.getResultFlow( + AddressElementNavigator.FORCE_EXPANDED_FORM_KEY + )?.collect { + _forceExpandedForm.emit(it) + } + } + + viewModelScope.launch { + combineAsStateFlow(collectedAddress, forceExpandedForm) { collectedAddress, forceExpandedForm -> + Pair( + collectedAddress, + forceExpandedForm + ) + }.collect { (addressDetails, forceExpandedFormNullable) -> + val forceExpandedForm = forceExpandedFormNullable ?: false val initialValues: Map = addressDetails ?.toIdentifierMap() ?: emptyMap() @@ -59,7 +77,11 @@ internal class InputAddressViewModel @Inject constructor( .stripeIntent(null) .merchantName("") .shippingValues(null) - .formSpec(buildFormSpec(addressDetails?.address?.line1 == null)) + .formSpec( + buildFormSpec( + condensedForm = !forceExpandedForm && addressDetails?.address?.line1 == null + ) + ) .initialValues(initialValues) .build().formController } diff --git a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt index 3aad5e87cf4..2b96cdf2692 100644 --- a/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt +++ b/paymentsheet/src/test/java/com/stripe/android/paymentsheet/addresselement/InputAddressViewModelTest.kt @@ -79,7 +79,7 @@ class InputAddressViewModelTest { fun `autocomplete address passed is collected to start`() = runTest(UnconfinedTestDispatcher()) { val expectedAddress = AddressDetails(name = "skyler", address = PaymentSheet.Address(country = "US")) val flow = MutableStateFlow(expectedAddress) - whenever(navigator.getResultFlow(any())).thenReturn(flow) + whenever(navigator.getResultFlow(AddressDetails.KEY)).thenReturn(flow) val viewModel = createViewModel() assertThat(viewModel.collectedAddress.value).isEqualTo(expectedAddress) @@ -89,7 +89,7 @@ class InputAddressViewModelTest { fun `takes only fields in new address`() = runTest(UnconfinedTestDispatcher()) { val usAddress = AddressDetails(name = "skyler", address = PaymentSheet.Address(country = "US")) val flow = MutableStateFlow(usAddress) - whenever(navigator.getResultFlow(any())).thenReturn(flow) + whenever(navigator.getResultFlow(AddressDetails.KEY)).thenReturn(flow) val viewModel = createViewModel() assertThat(viewModel.collectedAddress.value).isEqualTo(usAddress)