Skip to content

Commit

Permalink
Android sync 0.8.0 #1
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasbark committed May 6, 2022
1 parent 6c80de8 commit 1b1d75f
Show file tree
Hide file tree
Showing 20 changed files with 765 additions and 86 deletions.
2 changes: 1 addition & 1 deletion packages/stripe/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- Feat: Add support for ACHv2
- Feat: Add support for setting a card's currency when creating a Token
- Feat: Added support for placeholderColor, textErrorColor , borderColor, borderRadius, and borderWidth for AuBECSDebitForm on iOS
- Several fixes by the Stripe sdk [v0.7.0](https://github.com/stripe/stripe-react-native/releases/tag/v0.4.0)
- Several fixes by the Stripe sdk [v0.7.0](https://github.com/stripe/stripe-react-native/releases/tag/v0.7.0)
- Updated freezed dependency to allow 2.x

## 2.4.0
Expand Down
8 changes: 8 additions & 0 deletions packages/stripe_android/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ android {
}

dependencies {
implementation 'com.github.bumptech.glide:glide:4.12.0'

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.3.1"
implementation 'com.stripe:stripe-android:20.1.+'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'

// play-services-wallet is already included in stripe-android
compileOnly "com.google.android.gms:play-services-wallet:19.1.0"

// Users need to declare this dependency on their own, otherwise all methods are a no-op
compileOnly 'com.stripe:stripe-android-issuing-push-provisioning:1.1.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import com.flutter.stripe.StripeAndroidPlugin
import io.flutter.plugin.common.PluginRegistry.ActivityResultListener
import java.lang.ref.WeakReference

abstract class BaseActivityEventListener : ActivityEventListener, ActivityResultListener {
open class BaseActivityEventListener : ActivityEventListener, ActivityResultListener {

lateinit var activity: WeakReference<Activity>

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
onActivityResult(activity.get(), requestCode, resultCode, data)
onActivityResult(activity.get()!!, requestCode, resultCode, data)
return false
}

override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
TODO("Override")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import android.content.Intent;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.android.FlutterFragmentActivity;
import io.flutter.plugin.common.PluginRegistry;
Expand Down Expand Up @@ -33,6 +35,10 @@ public String getName() {
return "StripeSdk";
}

public Map<String, Object> getConstants() {
return new HashMap();
}

@Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
for (ActivityEventListener eventListener : eventListeners) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
import androidx.annotation.Nullable;

import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -105,5 +108,41 @@ public ReadableArray getArray(@NotNull String key) {
return null;
}
}

private static HashMap<String, Object> toMap(JSONObject jsonobj) throws JSONException {
HashMap<String, Object> map = new HashMap<String, Object>();
Iterator<String> keys = jsonobj.keys();
while(keys.hasNext()) {
String key = keys.next();
Object value = jsonobj.get(key);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
} else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
map.put(key, value);
}
return map;
}

private static List<Object> toList(JSONArray array) throws JSONException {
List<Object> list = new ArrayList<Object>();
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
if (value instanceof JSONArray) {
value = toList((JSONArray) value);
}
else if (value instanceof JSONObject) {
value = toMap((JSONObject) value);
}
list.add(value);
}
return list;
}

@NotNull
public HashMap toHashMap() throws JSONException {
return toMap(this.map);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package com.facebook.react.uimanager

import android.content.Context
import android.content.ContextWrapper
import com.facebook.react.bridge.ReactApplicationContext
import com.reactnativestripesdk.StripeSdkModule
import io.flutter.plugin.common.MethodChannel

class ThemedReactContext(context: Context,
private val channel: MethodChannel,
private val sdkAccessor: () -> StripeSdkModule): ContextWrapper(context) {

val reactApplicationContext: ReactApplicationContext = context as ReactApplicationContext

fun getNativeModule(clazz: Class<UIManagerModule>): UIManagerModule? {
return UIManagerModule(channel)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.flutter.plugin.common.MethodChannel

class RCTEventEmitter(private val channel: MethodChannel) {

fun receiveEvent(viewTag: Any, eventName: String, serializeEventData: WritableMap) {
fun receiveEvent(viewTag: Any, eventName: String, serializeEventData: WritableMap?) {
channel.invokeMethod(eventName, serializeEventData)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ If you continue to have trouble, follow this discussion to get some support http
params = call.requiredArgument("params"),
promise = Promise(result)
)
"isCardInWallet" -> stripeSdk.isCardInWallet(
params = call.requiredArgument("params"),
promise = Promise(result)
)
else -> result.notImplemented()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import com.facebook.react.common.MapBuilder
import com.facebook.react.uimanager.SimpleViewManager
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.annotations.ReactProp
import com.stripe.android.model.PaymentMethodCreateParams

class CardFieldViewManager : SimpleViewManager<CardFieldView>() {
override fun getName() = "CardField"

internal var reactContextRef: ThemedReactContext? = null
private var reactContextRef: ThemedReactContext? = null

override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
return MapBuilder.of(
Expand Down Expand Up @@ -47,9 +46,9 @@ class CardFieldViewManager : SimpleViewManager<CardFieldView>() {
view.setCardStyle(cardStyle)
}

@ReactProp(name = "placeholder")
fun setPlaceHolders(view: CardFieldView, placeholder: ReadableMap) {
view.setPlaceHolders(placeholder)
@ReactProp(name = "placeholders")
fun setPlaceHolders(view: CardFieldView, placeholders: ReadableMap) {
view.setPlaceHolders(placeholders)
}

override fun createViewInstance(reactContext: ThemedReactContext): CardFieldView {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ package com.reactnativestripesdk

import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.Typeface
import android.os.Build
import android.view.View
import android.view.View.OnFocusChangeListener
import android.widget.FrameLayout
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.flutter.stripe.R
import com.google.android.material.shape.CornerFamily
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import com.stripe.android.databinding.CardMultilineWidgetBinding
import com.stripe.android.databinding.StripeCardFormViewBinding
import com.stripe.android.model.Address
Expand Down Expand Up @@ -39,35 +42,31 @@ class CardFormView(context: ThemedReactContext) : FrameLayout(context) {
}

fun setPostalCodeEnabled(value: Boolean) {
val cardFormView = StripeCardFormViewBinding.bind(cardForm)
val visibility = if (value) View.VISIBLE else View.GONE

cardFormView.cardMultilineWidget.postalCodeRequired = false
cardFormView.postalCodeContainer.visibility = visibility
cardFormViewBinding.cardMultilineWidget.postalCodeRequired = false
cardFormViewBinding.postalCodeContainer.visibility = visibility
}

// TODO: uncomment when ios-sdk allows for this
// fun setPlaceHolders(value: ReadableMap) {
// val cardFormView = StripeCardFormViewBinding.bind(cardForm)
//
// val numberPlaceholder = getValOr(value, "number", null)
// val expirationPlaceholder = getValOr(value, "expiration", null)
// val cvcPlaceholder = getValOr(value, "cvc", null)
// val postalCodePlaceholder = getValOr(value, "postalCode", null)
//
// numberPlaceholder?.let {
//// multilineWidgetBinding.tlCardNumber.hint = it
// }
// expirationPlaceholder?.let {
// multilineWidgetBinding.tlExpiry.hint = it
// }
// cvcPlaceholder?.let {
// multilineWidgetBinding.tlCvc.hint = it
// }
// postalCodePlaceholder?.let {
// cardFormView.postalCodeContainer.hint = it
// }
// }
fun setPlaceHolders(value: ReadableMap) {
val numberPlaceholder = getValOr(value, "number", null)
val expirationPlaceholder = getValOr(value, "expiration", null)
val cvcPlaceholder = getValOr(value, "cvc", null)
val postalCodePlaceholder = getValOr(value, "postalCode", null)

numberPlaceholder?.let {
multilineWidgetBinding.tlCardNumber.hint = it
}
expirationPlaceholder?.let {
multilineWidgetBinding.tlExpiry.hint = it
}
cvcPlaceholder?.let {
multilineWidgetBinding.tlCvc.hint = it
}
postalCodePlaceholder?.let {
cardFormViewBinding.postalCodeContainer.hint = it
}
}

fun setAutofocus(value: Boolean) {
if (value) {
Expand Down Expand Up @@ -102,11 +101,81 @@ class CardFormView(context: ThemedReactContext) : FrameLayout(context) {
}

fun setCardStyle(value: ReadableMap) {
val binding = StripeCardFormViewBinding.bind(cardForm)
val backgroundColor = getValOr(value, "backgroundColor", null)
val textColor = getValOr(value, "textColor", null)
val borderWidth = getIntOrNull(value, "borderWidth")
val borderColor = getValOr(value, "borderColor", null)
val borderRadius = getIntOrNull(value, "borderRadius") ?: 0
val fontSize = getIntOrNull(value, "fontSize")
val fontFamily = getValOr(value, "fontFamily")
val placeholderColor = getValOr(value, "placeholderColor", null)
val textErrorColor = getValOr(value, "textErrorColor", null)
val cursorColor = getValOr(value, "cursorColor", null)

val editTextBindings = setOf(
cardFormViewBinding.cardMultilineWidget.cardNumberEditText,
cardFormViewBinding.cardMultilineWidget.cvcEditText,
cardFormViewBinding.cardMultilineWidget.expiryDateEditText,
cardFormViewBinding.postalCode
)

textColor?.let {
for (binding in editTextBindings) {
binding.setTextColor(Color.parseColor(it))
}
cardFormViewBinding.countryLayout.countryAutocomplete.setTextColor(Color.parseColor(it))
}
textErrorColor?.let {
for (binding in editTextBindings) {
binding.setErrorColor(Color.parseColor(it))
cardFormViewBinding.postalCode.setErrorColor(Color.parseColor(it))
}
}
placeholderColor?.let {
multilineWidgetBinding.tlExpiry.defaultHintTextColor = ColorStateList.valueOf(Color.parseColor(it))
multilineWidgetBinding.tlCardNumber.defaultHintTextColor = ColorStateList.valueOf(Color.parseColor(it))
multilineWidgetBinding.tlCvc.defaultHintTextColor = ColorStateList.valueOf(Color.parseColor(it))
cardFormViewBinding.postalCodeContainer.defaultHintTextColor = ColorStateList.valueOf(Color.parseColor(it))
}
fontSize?.let {
for (binding in editTextBindings) {
binding.textSize = it.toFloat()
}
}
fontFamily?.let {
for (binding in editTextBindings) {
binding.typeface = Typeface.create(it, Typeface.NORMAL)
}
}
cursorColor?.let {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val color = Color.parseColor(it)
for (binding in editTextBindings) {
binding.textCursorDrawable?.setTint(color)
binding.textSelectHandle?.setTint(color)
binding.textSelectHandleLeft?.setTint(color)
binding.textSelectHandleRight?.setTint(color)
binding.highlightColor = color
}
}
}

binding.cardMultilineWidgetContainer.background = MaterialShapeDrawable().also { shape ->
cardFormViewBinding.cardMultilineWidgetContainer.setPadding(40, 0, 40, 0)
cardFormViewBinding.cardMultilineWidgetContainer.background = MaterialShapeDrawable(
ShapeAppearanceModel()
.toBuilder()
.setAllCorners(CornerFamily.ROUNDED, (borderRadius * 2).toFloat())
.build()
).also { shape ->
shape.strokeWidth = 0.0f
shape.strokeColor = ColorStateList.valueOf(Color.parseColor("#000000"))
shape.fillColor = ColorStateList.valueOf(Color.parseColor("#FFFFFF"))
borderWidth?.let {
shape.strokeWidth = (it * 2).toFloat()
}
borderColor?.let {
shape.strokeColor = ColorStateList.valueOf(Color.parseColor(it))
}
backgroundColor?.let {
shape.fillColor = ColorStateList.valueOf(Color.parseColor(it))
}
Expand Down Expand Up @@ -143,8 +212,7 @@ class CardFormView(context: ThemedReactContext) : FrameLayout(context) {
.setCountry(it.address?.country)
.build()

val binding = StripeCardFormViewBinding.bind(cardForm)
binding.cardMultilineWidget.paymentMethodCard?.let { params -> cardParams = params }
cardFormViewBinding.cardMultilineWidget.paymentMethodCard?.let { params -> cardParams = params }
}
} else {
cardParams = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ class CardFormViewManager : SimpleViewManager<CardFormView>() {
view.setPostalCodeEnabled(postalCodeEnabled)
}

// @ReactProp(name = "placeholder")
// fun setPlaceHolders(view: CardFormView, placeholder: ReadableMap) {
// view.setPlaceHolders(placeholder)
// }
@ReactProp(name = "placeholders")
fun setPlaceHolders(view: CardFormView, placeholders: ReadableMap) {
view.setPlaceHolders(placeholders);
}

@ReactProp(name = "autofocus")
fun setAutofocus(view: CardFormView, autofocus: Boolean = false) {
Expand Down
Loading

0 comments on commit 1b1d75f

Please sign in to comment.