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

Update FPX bank list with offline status #1748

Merged
merged 1 commit into from
Oct 24, 2019
Merged
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
4 changes: 4 additions & 0 deletions stripe/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,8 @@
<string name="sepa_debit_mandate" tools:ignore="MissingTranslation">By providing your IBAN and confirming this payment, you are authorizing EXAMPLE COMPANY NAME and Stripe, our payment service provider, to send instructions to your bank to debit your account and your bank to debit your account in accordance with those instructions. You are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited.</string>
<string name="iban_hint" tools:ignore="MissingTranslation">IBAN</string>
<string name="create_sepa_debit_button" tools:ignore="MissingTranslation">Create SEPA Debit Payment Method</string>

<!-- TODO(mshafrir-stripe): translate string - ANDROID-432 -->
<!-- Label that will show that an FPX bank is offline. For example, "AmBank - Offline" -->
<string name="fpx_bank_offline" tools:ignore="MissingTranslation">%s - Offline</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import org.json.JSONObject
internal class FpxBankStatuses private constructor(
private val statuses: Map<String, Boolean>? = null
) {
/**
* Defaults to `true` if statuses aren't available.
*/
@JvmSynthetic
internal fun isOnline(bankId: String): Boolean {
return statuses?.get(bankId) ?: false
return statuses?.get(bankId) ?: true
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.stripe.android.view

import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Resources
import android.os.AsyncTask
import android.os.Parcel
import android.os.Parcelable
import android.view.LayoutInflater
Expand All @@ -12,8 +14,15 @@ import androidx.appcompat.widget.AppCompatImageView
import androidx.core.widget.ImageViewCompat
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.stripe.android.ApiRequest
import com.stripe.android.PaymentConfiguration
import com.stripe.android.R
import com.stripe.android.StripeApiRepository
import com.stripe.android.StripeRepository
import com.stripe.android.model.FpxBankStatuses
import com.stripe.android.model.PaymentMethodCreateParams
import java.lang.ref.WeakReference
import kotlinx.android.synthetic.main.add_payment_method_fpx_layout.view.*

internal class AddPaymentMethodFpxView private constructor(
Expand Down Expand Up @@ -44,6 +53,8 @@ internal class AddPaymentMethodFpxView private constructor(
layoutManager = LinearLayoutManager(context)
itemAnimator = DefaultItemAnimator()
}

FpxBankStatusesTask(context.applicationContext, this).execute()
}

override fun onSaveInstanceState(): Parcelable? {
Expand All @@ -59,16 +70,23 @@ internal class AddPaymentMethodFpxView private constructor(
}
}

private fun onFpxBankStatusesUpdated(fpxBankStatuses: FpxBankStatuses?) {
fpxBankStatuses?.let {
fpxAdapter.updateStatuses(it)
}
}

private class Adapter constructor(
private val themeConfig: ThemeConfig
) : androidx.recyclerview.widget.RecyclerView.Adapter<Adapter.ViewHolder>() {
) : RecyclerView.Adapter<Adapter.ViewHolder>() {
var selectedPosition = -1
private var fpxBankStatuses: FpxBankStatuses = FpxBankStatuses.EMPTY

internal val selectedBank: FpxBank?
get() = if (selectedPosition == -1) {
null
} else {
FpxBank.values()[selectedPosition]
getItem(selectedPosition)
}

init {
Expand All @@ -83,7 +101,9 @@ internal class AddPaymentMethodFpxView private constructor(

override fun onBindViewHolder(viewHolder: ViewHolder, i: Int) {
viewHolder.setSelected(i == selectedPosition)
viewHolder.update(FpxBank.values()[i])

val fpxBank = getItem(i)
viewHolder.update(fpxBank, fpxBankStatuses.isOnline(fpxBank.id))
viewHolder.itemView.setOnClickListener {
val currentPosition = viewHolder.adapterPosition
if (currentPosition != selectedPosition) {
Expand All @@ -103,22 +123,45 @@ internal class AddPaymentMethodFpxView private constructor(
return FpxBank.values().size
}

fun updateSelected(position: Int) {
private fun getItem(position: Int): FpxBank {
return FpxBank.values()[position]
}

internal fun updateSelected(position: Int) {
selectedPosition = position
notifyItemChanged(position)
}

internal fun updateStatuses(fpxBankStatuses: FpxBankStatuses) {
this.fpxBankStatuses = fpxBankStatuses

FpxBank.values().indices
.filterNot { position ->
fpxBankStatuses.isOnline(getItem(position).id)
}
.forEach { position ->
notifyItemChanged(position)
}
}

private class ViewHolder constructor(
itemView: View,
private val themeConfig: ThemeConfig
) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) {

) : RecyclerView.ViewHolder(itemView) {
private val resources: Resources = itemView.resources
private val name: TextView = itemView.findViewById(R.id.name)
private val icon: AppCompatImageView = itemView.findViewById(R.id.icon)
private val checkMark: AppCompatImageView = itemView.findViewById(R.id.check_icon)

internal fun update(fpxBank: FpxBank) {
name.text = fpxBank.displayName
internal fun update(fpxBank: FpxBank, isOnline: Boolean) {
name.text = if (isOnline) {
fpxBank.displayName
} else {
resources.getString(
R.string.fpx_bank_offline,
fpxBank.displayName
)
}
icon.setImageResource(fpxBank.brandIconResId)
}

Expand All @@ -133,6 +176,30 @@ internal class AddPaymentMethodFpxView private constructor(
}
}

private class FpxBankStatusesTask internal constructor(
context: Context,
view: AddPaymentMethodFpxView
) : AsyncTask<Void, Void, FpxBankStatuses?>() {
private val stripeRepository: StripeRepository = StripeApiRepository(context)
private val paymentConfiguration = PaymentConfiguration.getInstance(context)
private val viewRef: WeakReference<AddPaymentMethodFpxView> = WeakReference(view)

override fun doInBackground(vararg p0: Void?): FpxBankStatuses? {
return try {
stripeRepository.getFpxBankStatus(
ApiRequest.Options.create(paymentConfiguration.publishableKey)
)
} catch (e: Exception) {
null
}
}

override fun onPostExecute(fpxBankStatuses: FpxBankStatuses?) {
super.onPostExecute(fpxBankStatuses)
viewRef.get()?.onFpxBankStatusesUpdated(fpxBankStatuses)
}
}

private class SavedState : BaseSavedState {
internal val selectedPosition: Int

Expand Down