Skip to content

Commit

Permalink
fixing conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
jleon15 committed Dec 14, 2022
2 parents 7e4a6ab + a9e7402 commit 90893df
Show file tree
Hide file tree
Showing 26 changed files with 447 additions and 228 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## [0.10.0](https://github.com/Basis-Theory/basistheory-android/compare/0.9.0...0.10.0) (2022-12-14)


### Features

* Allows custom masks, transforms, and validators on TextElement ([#19](https://github.com/Basis-Theory/basistheory-android/issues/19)) ([ceaf62c](https://github.com/Basis-Theory/basistheory-android/commit/ceaf62c48249df94be7f4b3ec850c965d46af0b2))


## [0.9.0](https://github.com/Basis-Theory/basistheory-android/compare/0.8.0...0.9.0) (2022-12-13)


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Add this dependency to your project's build file:
}
dependencies {
implementation 'com.github.basis-theory.basistheory-android:lib:0.9.0'
implementation 'com.github.basis-theory.basistheory-android:lib:0.10.0'
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.basistheory.android.example.databinding.FragmentCustomFormBinding
import com.basistheory.android.example.util.tokenExpirationTimestamp
import com.basistheory.android.example.viewmodel.TokenizeViewModel
import com.basistheory.android.model.KeyboardType
import com.basistheory.android.view.mask.ElementMask

class CustomFormFragment : Fragment() {
private val binding: FragmentCustomFormBinding by lazy {
Expand All @@ -18,9 +19,7 @@ class CustomFormFragment : Fragment() {
private val viewModel: TokenizeViewModel by viewModels()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
super.onCreateView(inflater, container, savedInstanceState)
binding.lifecycleOwner = this
Expand All @@ -31,33 +30,52 @@ class CustomFormFragment : Fragment() {

// illustrates that keyboardType can be set programmatically (or in xml)
binding.phoneNumber.keyboardType = KeyboardType.NUMBER
binding.phoneNumber.mask = listOf("+", "1", "(", digitRegex,digitRegex,digitRegex, ")", " ", digitRegex, digitRegex, digitRegex, "-", digitRegex, digitRegex , digitRegex, digitRegex )
binding.phoneNumber.mask = ElementMask(
listOf(
"+",
"1",
"(",
digitRegex,
digitRegex,
digitRegex,
")",
" ",
digitRegex,
digitRegex,
digitRegex,
"-",
digitRegex,
digitRegex,
digitRegex,
digitRegex
)
)

binding.orderNumber.mask = listOf(charRegex, charRegex, charRegex, "-", digitRegex, digitRegex, digitRegex)
binding.orderNumber.mask = ElementMask(
listOf(charRegex, charRegex, charRegex, "-", digitRegex, digitRegex, digitRegex)
)

binding.tokenizeButton.setOnClickListener { tokenize() }
binding.autofillButton.setOnClickListener { autofill() }

return binding.root
}

private fun autofill() {
binding.name.setText("John Doe")
binding.phoneNumber.setText("2345678900")
binding.orderNumber.setText("ABC123")
private fun autofill() {
binding.name.setText("John Doe")
binding.phoneNumber.setText("2345678900")
binding.orderNumber.setText("ABC123")
}

private fun tokenize() =
viewModel.tokenize(
object {
val type = "token"
val data = object {
val name = binding.name
val phoneNumber = binding.phoneNumber
val orderNumber = binding.orderNumber
}
val expires_at = tokenExpirationTimestamp()
}).observe(viewLifecycleOwner) {}
private fun tokenize() = viewModel.tokenize(object {
val type = "token"
val data = object {
val name = binding.name
val phoneNumber = binding.phoneNumber
val orderNumber = binding.orderNumber
}
val expires_at = tokenExpirationTimestamp()
}).observe(viewLifecycleOwner) {}
}


2 changes: 1 addition & 1 deletion lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ android {
defaultConfig {
minSdk 21
targetSdk 32
versionName = '0.9.0'
versionName = '0.10.0'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class CardBrandEnricher {
object CardMasks {
const val MASK_4_8_12GAPS_19LENGTH = "#### #### #### #######"
const val MASK_4_8_12GAPS_16LENGTH = "#### #### #### ####"
const val MASK_4_10GAPS_15LENGTH = "#### ###### #####"
const val MASK_4_10GAPS_19LENGTH = "#### ###### #########"
}

object CvcMasks {
Expand All @@ -18,8 +20,8 @@ class CardBrandEnricher {
var brand: String = "",
var identifierRanges: List<Pair<String, String?>>,
var validLengths: IntArray,
var cvcMask: String = "",
var cardMask: String = ""
var cvcMask: String,
var cardMask: String
)

class CardResult(
Expand Down Expand Up @@ -48,38 +50,53 @@ class CardBrandEnricher {
"23" to "26",
"270" to "271",
"2720" to null
), intArrayOf(16), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_16LENGTH
),
intArrayOf(16),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_16LENGTH
),

CardDetails(
CardBrands.AMERICAN_EXPRESS.label, listOf(
"34" to null,
"37" to null
), intArrayOf(15), CvcMasks.FOUR_DIGIT, "#### ###### #####"
),
intArrayOf(15),
CvcMasks.FOUR_DIGIT,
CardMasks.MASK_4_10GAPS_15LENGTH
),

CardDetails(
CardBrands.DINERS_CLUB.label, listOf(
"36" to null,
"38" to "39",
"300" to "305"
), intArrayOf(14, 16, 19), CvcMasks.THREE_DIGIT, "#### ###### #########"
),
intArrayOf(14, 16, 19),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_10GAPS_19LENGTH
),

CardDetails(
CardBrands.DISCOVER.label, listOf(
"65" to null,
"6011" to "39",
"644" to "649"
), intArrayOf(16, 19), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_19LENGTH
),
intArrayOf(16, 19),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_19LENGTH
),

CardDetails(
CardBrands.JCB.label, listOf(
"2131" to null,
"1800" to "39",
"3528" to "3589"
), intArrayOf(16, 17, 18, 19), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_19LENGTH
),
intArrayOf(16, 17, 18, 19),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_19LENGTH
),

CardDetails(
Expand All @@ -100,7 +117,10 @@ class CardBrandEnricher {
"627781" to "627799",
"6282" to "6289",
"8110" to "8171",
), intArrayOf(14, 15, 16, 17, 18, 19), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_19LENGTH
),
intArrayOf(14, 15, 16, 17, 18, 19),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_19LENGTH
),

CardDetails(
Expand All @@ -113,7 +133,10 @@ class CardBrandEnricher {
"504176" to "506698",
"506779" to "508999",
"56" to "59",
), intArrayOf(12, 13, 14, 15, 16, 17, 18, 19), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_19LENGTH
),
intArrayOf(12, 13, 14, 15, 16, 17, 18, 19),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_19LENGTH
),

CardDetails(
Expand Down Expand Up @@ -143,7 +166,10 @@ class CardBrandEnricher {
"651652" to "651679",
"655000" to "655019",
"655021" to "655058",
), intArrayOf(16), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_16LENGTH
),
intArrayOf(16),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_16LENGTH
),

CardDetails(
Expand All @@ -163,13 +189,19 @@ class CardBrandEnricher {
"637599" to null,
"637609" to null,
"637612" to null,
), intArrayOf(16), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_16LENGTH
),
intArrayOf(16),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_16LENGTH
),

CardDetails(
CardBrands.HIPERCARD.label, listOf(
"606282" to null,
), intArrayOf(16), CvcMasks.THREE_DIGIT, CardMasks.MASK_4_8_12GAPS_16LENGTH
),
intArrayOf(16),
CvcMasks.THREE_DIGIT,
CardMasks.MASK_4_8_12GAPS_16LENGTH
)
)

Expand Down Expand Up @@ -199,6 +231,10 @@ class CardBrandEnricher {
identifierMatch: String,
number: String
): CardResult =
if (currentBestMatch.identifierLength < identifierMatch.length) CardResult(cardDetails, number.length, identifierMatch.length)
if (currentBestMatch.identifierLength < identifierMatch.length) CardResult(
cardDetails,
number.length,
identifierMatch.length
)
else currentBestMatch
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.basistheory.android.view

import android.content.Context
import android.text.Editable
import android.util.AttributeSet
import com.basistheory.android.model.ElementValueReference
import com.basistheory.android.model.KeyboardType
import com.basistheory.android.view.validation.futureDateValidator
import com.basistheory.android.view.mask.ElementMask
import com.basistheory.android.view.validation.FutureDateValidator

class CardExpirationDateElement @JvmOverloads constructor(
context: Context,
Expand All @@ -19,20 +19,9 @@ class CardExpirationDateElement @JvmOverloads constructor(
init {
super.keyboardType = KeyboardType.NUMBER
super.mask = defaultMask
super.validate = { futureDateValidator(it) }
super.validator = FutureDateValidator()
}

private fun getMonthValue(): String? =
getText()
?.split("/")
?.elementAtOrNull(0)

private fun getYearValue(): String? =
getText()
?.split("/")
?.elementAtOrNull(1)
?.let { "20$it" }

/**
* If the user entered a leading digit > 1, auto insert a leading 0
*/
Expand All @@ -45,10 +34,22 @@ class CardExpirationDateElement @JvmOverloads constructor(
return if (firstDigit > 1) "0$value" else value
}

private fun getMonthValue(): String? =
getText()
?.split("/")
?.elementAtOrNull(0)

private fun getYearValue(): String? =
getText()
?.split("/")
?.elementAtOrNull(1)
?.let { "20$it" }

companion object {
private val digit = Regex("""\d""")

val defaultMask: List<Any> =
val defaultMask = ElementMask(
listOf(digit, digit, "/", digit, digit)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import com.basistheory.android.event.ChangeEvent
import com.basistheory.android.event.EventDetails
import com.basistheory.android.model.KeyboardType
import com.basistheory.android.service.CardBrandEnricher
import com.basistheory.android.view.transform.regexReplaceElementTransform
import com.basistheory.android.view.validation.luhnValidator
import com.basistheory.android.view.mask.ElementMask
import com.basistheory.android.view.transform.RegexReplaceElementTransform
import com.basistheory.android.view.validation.LuhnValidator

class CardNumberElement @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0) : TextElement(context, attrs, defStyleAttr) {
defStyleAttr: Int = 0
) : TextElement(context, attrs, defStyleAttr) {

var cardDetails: CardBrandEnricher.CardDetails? = null
private set
Expand All @@ -22,16 +24,16 @@ class CardNumberElement @JvmOverloads constructor(
init {
super.keyboardType = KeyboardType.NUMBER
super.mask = defaultMask
super.transform = regexReplaceElementTransform(Regex("""\s"""), "")
super.validate = ::luhnValidator
super.transform = RegexReplaceElementTransform(Regex("""\s"""), "")
super.validator = LuhnValidator()
}

override fun beforeTextChanged(value: String?): String? {
val cardResult = cardBrandEnricher.evaluateCard(getDigitsOnly(value))
cardDetails = cardResult.cardDetails

if (cardResult.cardDetails?.cardMask != null)
mask = cardResult.cardDetails!!.cardMask.toList()
mask = ElementMask(cardResult.cardDetails!!.cardMask)

return value
}
Expand Down Expand Up @@ -63,16 +65,17 @@ class CardNumberElement @JvmOverloads constructor(
}

private fun getDigitsOnly(text: String?): String? {
val maskedValue = maskValue?.evaluate(text, inputAction)
return transform(maskedValue)
val maskedValue = mask?.evaluate(text, inputAction)
return transform?.apply(maskedValue) ?: maskedValue
}

companion object {
private val digit = Regex("""\d""")

val defaultMask: List<Any> =
val defaultMask = ElementMask(
(1..19).map {
if (it % 5 == 0 && it > 0) " " else digit
}
)
}
}
Loading

0 comments on commit 90893df

Please sign in to comment.