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

Address Lookup - Display country name instead of country code #1892

Closed
wants to merge 2 commits into from
Closed
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
7 changes: 5 additions & 2 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@

## Fixed
- For the Address Lookup functionality:
- Address data is now correctly saved to `PaymentComponentData`.
- Address fields that were edited manually no longer lose their state when starting Lookup mode.
- Address data is now correctly saved to `PaymentComponentData`.
- Address fields that were edited manually no longer lose their state when starting Lookup mode.

## Changed
- In Card Component selected lookup address field, country name is displayed now instead of country code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also check this with docs team?

Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,9 @@ class CardView @JvmOverloads constructor(
}

private fun updateAddressLookupInputText(addressOutputData: AddressOutputData) {
binding.autoCompleteTextViewAddressLookup.setText(addressOutputData.toString())
binding.autoCompleteTextViewAddressLookup.setText(
addressOutputData.getDisplayAddress(cardDelegate.componentParams.shopperLocale)
)
}

private fun updateAddressHint(addressFormUIState: AddressFormUIState, isOptional: Boolean) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ package com.adyen.checkout.ui.core.internal.ui.model
import androidx.annotation.RestrictTo
import com.adyen.checkout.components.core.internal.ui.model.FieldState
import com.adyen.checkout.components.core.internal.ui.model.OutputData
import com.adyen.checkout.components.core.internal.util.CountryUtils
import java.util.Locale

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
data class AddressOutputData(
Expand All @@ -34,15 +36,15 @@ data class AddressOutputData(
city.validation.isValid() &&
country.validation.isValid()

override fun toString(): String {
fun getDisplayAddress(locale: Locale): String {
return listOf(
street.value,
houseNumberOrName.value,
apartmentSuite.value,
postalCode.value,
city.value,
stateOrProvince.value,
country.value,
CountryUtils.getCountryName(country.value, locale),
).filter { it.isNotBlank() }.joinToString(" ")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.adyen.checkout.components.core.LookupAddress
import com.adyen.checkout.components.core.internal.util.CountryUtils
import com.adyen.checkout.ui.core.databinding.AddressLookupOptionItemViewBinding
import java.util.Locale

internal class AddressLookupOptionsAdapter(
private val onItemClicked: (LookupAddress) -> Unit
private val shopperLocale: Locale,
private val onItemClicked: (LookupAddress) -> Unit,
) :
ListAdapter<LookupOption, AddressLookupOptionsAdapter.AddressLookupOptionViewHolder>(
AddressLookupOptionDiffCallback,
) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AddressLookupOptionViewHolder {
val binding = AddressLookupOptionItemViewBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return AddressLookupOptionViewHolder(binding, onItemClicked)
return AddressLookupOptionViewHolder(binding, onItemClicked, shopperLocale)
}

override fun onBindViewHolder(holder: AddressLookupOptionViewHolder, position: Int) {
Expand All @@ -36,15 +39,16 @@ internal class AddressLookupOptionsAdapter(

internal class AddressLookupOptionViewHolder(
private val binding: AddressLookupOptionItemViewBinding,
private val onItemClicked: (LookupAddress) -> Unit
private val onItemClicked: (LookupAddress) -> Unit,
private val shopperLocale: Locale,
) : RecyclerView.ViewHolder(binding.root) {
fun bindItem(lookupOption: LookupOption) {
binding.root.setOnClickListener {
onItemClicked(lookupOption.lookupAddress)
}
binding.progressBar.isVisible = lookupOption.isLoading
binding.textViewAddressHeader.text = lookupOption.title
binding.textViewAddressDescription.text = lookupOption.subtitle
binding.textViewAddressHeader.text = lookupOption.getDisplayTitle(shopperLocale)
binding.textViewAddressDescription.text = lookupOption.getDisplaySubtitle(shopperLocale)
}
}

Expand All @@ -62,27 +66,25 @@ data class LookupOption(
val lookupAddress: LookupAddress,
val isLoading: Boolean = false
) {
override fun toString(): String {
private fun getDisplayName(locale: Locale): String {
return listOf(
lookupAddress.address.street,
lookupAddress.address.houseNumberOrName,
lookupAddress.address.apartmentSuite,
lookupAddress.address.postalCode,
lookupAddress.address.city,
lookupAddress.address.stateOrProvince,
lookupAddress.address.country,
CountryUtils.getCountryName(lookupAddress.address.country, locale),
).filter { !it.isNullOrBlank() }.joinToString(" ")
}

val title
get() = lookupAddress.address.street.ifBlank {
toString()
}
fun getDisplayTitle(locale: Locale) = lookupAddress.address.street.ifBlank {
getDisplayName(locale)
}

val subtitle
get() = if (lookupAddress.address.street.isBlank()) {
""
} else {
toString()
}
fun getDisplaySubtitle(locale: Locale) = if (lookupAddress.address.street.isBlank()) {
""
} else {
getDisplayName(locale)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.adyen.checkout.ui.core.internal.util.showKeyboard
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import java.util.Locale

@Suppress("TooManyFunctions")
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
Expand All @@ -50,6 +51,8 @@ class AddressLookupView @JvmOverloads constructor(

private lateinit var localizedContext: Context

private lateinit var shopperLocale: Locale

private lateinit var addressLookupDelegate: AddressLookupDelegate

private var addressLookupOptionsAdapter: AddressLookupOptionsAdapter? = null
Expand All @@ -64,6 +67,8 @@ class AddressLookupView @JvmOverloads constructor(
require(delegate is AddressLookupDelegate) { "Unsupported delegate type" }
addressLookupDelegate = delegate

shopperLocale = delegate.componentParams.shopperLocale

this.localizedContext = localizedContext
initLocalizedStrings(localizedContext)

Expand Down Expand Up @@ -164,7 +169,7 @@ class AddressLookupView @JvmOverloads constructor(
}

private fun initAddressOptions() {
addressLookupOptionsAdapter = AddressLookupOptionsAdapter(::onAddressSelected)
addressLookupOptionsAdapter = AddressLookupOptionsAdapter(shopperLocale, ::onAddressSelected)
addressLookupOptionsAdapter?.let { adapter ->
binding.recyclerViewAddressLookupOptions.adapter = adapter
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package com.adyen.checkout.ui.core.internal.util

import androidx.annotation.RestrictTo
import com.adyen.checkout.components.core.Address
import com.adyen.checkout.components.core.internal.util.CountryUtils
import com.adyen.checkout.ui.core.internal.data.model.AddressItem
import com.adyen.checkout.ui.core.internal.ui.AddressFormUIState
import com.adyen.checkout.ui.core.internal.ui.model.AddressListItem
Expand Down Expand Up @@ -70,13 +71,16 @@ object AddressFormUtils {

val defaultCountryCode = getInitialCountryCode(
shopperLocale = shopperLocale,
addressParams = addressParams
addressParams = addressParams,
)
markAddressListItemSelected(
mapToCountryListItem(filteredCountryList, shopperLocale),
defaultCountryCode,
)
markAddressListItemSelected(mapToListItem(filteredCountryList), defaultCountryCode)
}

is AddressParams.Lookup -> {
mapToListItem(countryList)
mapToCountryListItem(countryList, shopperLocale)
}

else -> emptyList()
Expand Down Expand Up @@ -106,7 +110,7 @@ object AddressFormUtils {
* @return State options.
*/
fun initializeStateOptions(stateList: List<AddressItem>): List<AddressListItem> {
return markAddressListItemSelected(mapToListItem(stateList))
return markAddressListItemSelected(mapToStateListItem(stateList))
}

/**
Expand Down Expand Up @@ -136,7 +140,7 @@ object AddressFormUtils {
stateOrProvince = addressOutputData.stateOrProvince.value.ifEmpty { Address.ADDRESS_NULL_PLACEHOLDER },
houseNumberOrName = makeHouseNumberOrName(
addressOutputData.houseNumberOrName.value,
addressOutputData.apartmentSuite.value
addressOutputData.apartmentSuite.value,
).ifEmpty { Address.ADDRESS_NULL_PLACEHOLDER },
city = addressOutputData.city.value.ifEmpty { Address.ADDRESS_NULL_PLACEHOLDER },
country = addressOutputData.country.value,
Expand Down Expand Up @@ -173,16 +177,34 @@ object AddressFormUtils {
/**
* Map a list of [AddressItem] to a list of [AddressListItem].
*
* @param list Input list.
* @param list Input country list.
*
* @return Mapped list of [AddressListItem].
*/
private fun mapToCountryListItem(list: List<AddressItem>, shopperLocale: Locale): List<AddressListItem> {
return list.map {
AddressListItem(
name = it.id?.let { isoCode -> CountryUtils.getCountryName(isoCode, shopperLocale) }
?: it.name.orEmpty(),
code = it.id.orEmpty(),
selected = false,
)
}
}

/**
* Map a list of [AddressItem] to a list of [AddressListItem].
*
* @param list Input states list.
*
* @return Mapped list of [AddressListItem].
*/
private fun mapToListItem(list: List<AddressItem>): List<AddressListItem> {
private fun mapToStateListItem(list: List<AddressItem>): List<AddressListItem> {
return list.map {
AddressListItem(
name = it.name.orEmpty(),
code = it.id.orEmpty(),
selected = false
selected = false,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,25 @@ import com.adyen.checkout.components.core.internal.ui.model.FieldState
import com.adyen.checkout.components.core.internal.ui.model.Validation
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import java.util.Locale

class AddressOutputDataTest {
@Test
fun addressOutputDataToString() {
val addressOutputData = AddressOutputData(
postalCode = FieldState("postalCode", Validation.Valid),
houseNumberOrName = FieldState("houseNumberOrName", Validation.Valid),
apartmentSuite = FieldState("apartmentSuite", Validation.Valid),
street = FieldState("street", Validation.Valid),
city = FieldState("city", Validation.Valid),
stateOrProvince = FieldState("stateOrProvince", Validation.Valid),
country = FieldState("country", Validation.Valid),
postalCode = FieldState("1234AB", Validation.Valid),
houseNumberOrName = FieldState("1", Validation.Valid),
apartmentSuite = FieldState("A", Validation.Valid),
street = FieldState("Straat", Validation.Valid),
city = FieldState("Amsterdam", Validation.Valid),
stateOrProvince = FieldState("Noord-Holland", Validation.Valid),
country = FieldState("NL", Validation.Valid),
isOptional = false,
countryOptions = emptyList(),
stateOptions = emptyList(),
)

val expected = "street houseNumberOrName apartmentSuite postalCode city stateOrProvince country"
assertEquals(expected, addressOutputData.toString())
val expected = "Straat 1 A 1234AB Amsterdam Noord-Holland Netherlands"
assertEquals(expected, addressOutputData.getDisplayAddress(Locale.ENGLISH))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -211,17 +211,17 @@ internal class AddressFormUtilsTest {
)
val expected = listOf(
AddressListItem(
name = "Canada",
name = "Kanada",
code = "CA",
selected = false,
),
AddressListItem(
name = "United States",
name = "Vereinigte Staaten",
code = "US",
selected = false,
),
AddressListItem(
name = "United Kingdom",
name = "Vereinigtes Königreich",
code = "GB",
selected = false,
),
Expand Down