Add account name validation to CreateAccountFragment using Kotlin extension functions and RxJava debounce operator.
This commit is contained in:
parent
9236e374bc
commit
e530dc531e
3 changed files with 56 additions and 2 deletions
|
@ -9,6 +9,8 @@ import androidx.navigation.fragment.findNavController
|
|||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import cy.agorise.bitsybitshareswallet.utils.containsDigits
|
||||
import cy.agorise.bitsybitshareswallet.utils.containsVowels
|
||||
import cy.agorise.bitsybitshareswallet.utils.toast
|
||||
import cy.agorise.graphenej.Address
|
||||
import cy.agorise.graphenej.BrainKey
|
||||
|
@ -28,6 +30,7 @@ class CreateAccountFragment : ConnectedFragment() {
|
|||
private const val TAG = "CreateAccountFragment"
|
||||
|
||||
private const val BRAINKEY_FILE = "brainkeydict.txt"
|
||||
private const val MIN_ACCOUNT_NAME_LENGTH = 8
|
||||
}
|
||||
|
||||
private lateinit var mBrainKey: BrainKey
|
||||
|
@ -36,7 +39,7 @@ class CreateAccountFragment : ConnectedFragment() {
|
|||
/** Variables used to store the validation status of the form fields */
|
||||
private var isPINValid = false
|
||||
private var isPINConfirmationValid = false
|
||||
private var isAccountValid = true // TODO make false
|
||||
private var isAccountValidAndAvailable = false
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
setHasOptionsMenu(true)
|
||||
|
@ -47,6 +50,15 @@ class CreateAccountFragment : ConnectedFragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Use RxJava Debounce to check the validity and availability of the user's proposed account name
|
||||
mDisposables.add(
|
||||
tietAccountName.textChanges()
|
||||
.skipInitialValue()
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { validateAccountName(it.toString()) }
|
||||
)
|
||||
|
||||
// Use RxJava Debounce to update the PIN error only after the user stops writing for > 500 ms
|
||||
mDisposables.add(
|
||||
tietPin.textChanges()
|
||||
|
@ -73,6 +85,31 @@ class CreateAccountFragment : ConnectedFragment() {
|
|||
generateKeys()
|
||||
}
|
||||
|
||||
private fun validateAccountName(accountName: String) {
|
||||
isAccountValidAndAvailable = false
|
||||
|
||||
if ( !isAccountNameValid(accountName) ) {
|
||||
tilAccountName.error = getString(R.string.error__invalid_account_name)
|
||||
tilAccountName.helperText = ""
|
||||
} else {
|
||||
tilAccountName.isErrorEnabled = false
|
||||
tilAccountName.helperText = getString(R.string.text__verifying_account_availability)
|
||||
}
|
||||
|
||||
enableDisableCreateButton()
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to determine if the account name entered by the user is valid
|
||||
* @param accountName The proposed account name
|
||||
* @return True if the name is valid, false otherwise
|
||||
*/
|
||||
private fun isAccountNameValid(accountName: String): Boolean {
|
||||
return accountName.length >= MIN_ACCOUNT_NAME_LENGTH &&
|
||||
(accountName.containsDigits() || !accountName.containsVowels()) &&
|
||||
!accountName.contains("_")
|
||||
}
|
||||
|
||||
private fun validatePIN() {
|
||||
val pin = tietPin.text.toString()
|
||||
|
||||
|
@ -102,7 +139,7 @@ class CreateAccountFragment : ConnectedFragment() {
|
|||
}
|
||||
|
||||
private fun enableDisableCreateButton() {
|
||||
btnCreate.isEnabled = (isPINValid && isPINConfirmationValid && isAccountValid)
|
||||
btnCreate.isEnabled = (isPINValid && isPINConfirmationValid && isAccountValidAndAvailable)
|
||||
}
|
||||
|
||||
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.res.ColorStateList
|
|||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import java.util.regex.Pattern
|
||||
|
||||
/**
|
||||
* Creates an enabled state, by enabling the button and using the given [colorResource] to color it.
|
||||
|
@ -27,4 +28,18 @@ fun FloatingActionButton.disable(colorResource: Int) {
|
|||
*/
|
||||
fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_LONG) {
|
||||
Toast.makeText(this, message, duration).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the current string contains at least one digit
|
||||
*/
|
||||
fun String.containsDigits(): Boolean {
|
||||
return Pattern.matches("\\d", this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the current string contains at least one vowel
|
||||
*/
|
||||
fun String.containsVowels(): Boolean {
|
||||
return Pattern.matches("[aeiou]", this)
|
||||
}
|
|
@ -28,6 +28,8 @@
|
|||
<!-- Create Account -->
|
||||
<string name="text__bitshares_account_name">BitShares account name</string>
|
||||
<string name="error__read_dict_file">Error reading dictionary file</string>
|
||||
<string name="error__invalid_account_name">The account name has to either have more than 8 characters, contain a number or have no vowels. The underscore character is also not allowed. </string>
|
||||
<string name="text__verifying_account_availability">Verifying account availability…</string>
|
||||
|
||||
<!-- Home -->
|
||||
<string name="title_transactions">Transactions</string>
|
||||
|
|
Loading…
Reference in a new issue