From 42c50724a2d66a59f2b5daabd5535ccde2e5f85f Mon Sep 17 00:00:00 2001 From: Javier Varona Date: Mon, 2 Oct 2017 22:25:58 -0400 Subject: [PATCH 1/2] - Adding Fields Validators to validate user entries in synchronous or asynchronous way (Work in progress...) --- .../activities/ImportSeedActivity.java | 28 ++++++- .../CryptoNetInfoRequest.java | 2 +- .../CryptoNetInfoRequestListener.java | 2 +- .../CryptoNetInfoRequests.java | 14 ++-- .../CryptoNetInfoRequestsListener.java | 2 +- ...ValidateImportBitsharesAccountRequest.java | 4 +- .../viewmodels/AccountSeedViewModel.java | 25 ++++++ .../validators/ImportSeedValidator.java | 78 +++++++++++++++++++ .../ImportSeedValidatorListener.java | 11 +++ .../validators/ValidationField.java | 54 +++++++++++++ 10 files changed, 207 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java create mode 100644 app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidatorListener.java create mode 100644 app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ValidationField.java diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java index ac5673a..6fc947a 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java @@ -5,6 +5,7 @@ import android.arch.lifecycle.ViewModelProviders; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import android.text.Editable; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; @@ -14,16 +15,20 @@ import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; +import butterknife.OnTextChanged; import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.models.AccountSeed; import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel; import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel; import cy.agorise.crystalwallet.viewmodels.TransactionListViewModel; +import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator; +import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidatorListener; import cy.agorise.crystalwallet.views.TransactionListView; -public class ImportSeedActivity extends AppCompatActivity { +public class ImportSeedActivity extends AppCompatActivity implements ImportSeedValidatorListener { AccountSeedViewModel accountSeedViewModel; + ImportSeedValidator importSeedValidator; @BindView(R.id.tvPin) TextView tvPin; @@ -48,11 +53,20 @@ public class ImportSeedActivity extends AppCompatActivity { ButterKnife.bind(this); accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class); - //this.seed = new AccountSeed(); + importSeedValidator = accountSeedViewModel.getValidator(); + + importSeedValidator.setListener(this); + } + + @OnTextChanged(value = R.id.etAccountName, + callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) + void afterAccountNameChanged(Editable editable) { + this.validator.validateAccountName(editable.getT); } @OnClick(R.id.btnImport) public void importSeed(){ + if (this.validator) AccountSeed seed = new AccountSeed(); //TODO verify if PIN and PIN confirmation are not null and are the same @@ -63,4 +77,14 @@ public class ImportSeedActivity extends AppCompatActivity { accountSeedViewModel.addSeed(seed); } + + @Override + public void onValidationSucceeded() { + //Clear all errors + } + + @Override + public void onValidationFailed(String error) { + //Show errors + } } diff --git a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequest.java b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequest.java index 3fb44ba..24c11e9 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequest.java +++ b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequest.java @@ -6,7 +6,7 @@ import cy.agorise.crystalwallet.enums.CryptoCoin; * Created by Henry Varona on 1/10/2017. */ -abstract class CryptoNetInfoRequest { +public abstract class CryptoNetInfoRequest { protected CryptoCoin coin; protected CryptoNetInfoRequestListener listener; diff --git a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestListener.java b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestListener.java index 8b3d63a..e53c05d 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestListener.java +++ b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestListener.java @@ -4,7 +4,7 @@ package cy.agorise.crystalwallet.cryptonetinforequests; * Created by Henry Varona on 1/10/2017. */ -interface CryptoNetInfoRequestListener { +public interface CryptoNetInfoRequestListener { public void onCarryOut(); } diff --git a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequests.java b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequests.java index 74d9126..01b27f8 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequests.java +++ b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequests.java @@ -10,20 +10,20 @@ import java.util.List; public class CryptoNetInfoRequests { private List requests; private List listeners; - private CryptoNetInfoRequests instance; + private static CryptoNetInfoRequests instance; private void CryptoNetInfoRequests(){ //Private constructor for singleton pattern } - public CryptoNetInfoRequests getInstance(){ - if (this.instance == null){ - this.instance = new CryptoNetInfoRequests(); - this.requests = new ArrayList(); - this.listeners = new ArrayList(); + public static CryptoNetInfoRequests getInstance(){ + if (CryptoNetInfoRequests.instance == null){ + CryptoNetInfoRequests.instance = new CryptoNetInfoRequests(); + CryptoNetInfoRequests.instance.requests = new ArrayList(); + CryptoNetInfoRequests.instance.listeners = new ArrayList(); } - return this.instance; + return CryptoNetInfoRequests.instance; } public void addRequest(CryptoNetInfoRequest request){ diff --git a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestsListener.java b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestsListener.java index 1c16bf3..05efb5f 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestsListener.java +++ b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/CryptoNetInfoRequestsListener.java @@ -4,6 +4,6 @@ package cy.agorise.crystalwallet.cryptonetinforequests; * Created by Henry Varona on 1/10/2017. */ -interface CryptoNetInfoRequestsListener { +public interface CryptoNetInfoRequestsListener { public void onNewRequest(CryptoNetInfoRequest request); } diff --git a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/ValidateImportBitsharesAccountRequest.java b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/ValidateImportBitsharesAccountRequest.java index bdae7cf..e8d6eac 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/ValidateImportBitsharesAccountRequest.java +++ b/app/src/main/java/cy/agorise/crystalwallet/cryptonetinforequests/ValidateImportBitsharesAccountRequest.java @@ -6,7 +6,7 @@ import cy.agorise.crystalwallet.enums.CryptoCoin; * Created by Henry Varona on 1/10/2017. */ -class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest { +public class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest { private String accountName; private String mnemonic; @@ -22,10 +22,12 @@ class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest { public void setAccountExists(boolean value){ this.accountExists = value; + this.validate(); } public void setMnemonicIsCorrect(boolean value){ this.mnemonicIsCorrect = value; + this.validate(); } public boolean getAccountExists(){ diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java index c36f4d4..01d69de 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java @@ -7,8 +7,11 @@ import android.arch.lifecycle.MutableLiveData; import java.util.List; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener; import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.models.AccountSeed; +import cy.agorise.crystalwallet.cryptonetinforequests.ValidateImportBitsharesAccountRequest; +import cy.agorise.crystalwallet.viewmodels.validators.ImportSeedValidator; /** * Created by Henry Varona on 27/9/2017. @@ -18,6 +21,7 @@ public class AccountSeedViewModel extends AndroidViewModel { private LiveData accountSeed; private CrystalDatabase db; + private MutableLiveData importSeedValidator; public AccountSeedViewModel(Application application) { super(application); @@ -28,6 +32,13 @@ public class AccountSeedViewModel extends AndroidViewModel { this.accountSeed = this.db.accountSeedDao().findById(seedId); } + public ImportSeedValidator getValidator(){ + if (this.importSeedValidator == null){ + this.importSeedValidator = new ImportSeedValidator(); + + } + } + public void addSeed(AccountSeed seed){ this.db.accountSeedDao().insertAccountSeed(seed); } @@ -35,4 +46,18 @@ public class AccountSeedViewModel extends AndroidViewModel { public LiveData getAccountSeed(){ return this.accountSeed; } + + public void validateAccountSeed(){ + if (this.accountSeed != null){ + AccountSeed seed = this.accountSeed.getValue(); + + ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(seed.getName(),seed.getMasterSeed()); + request.setListener(new CryptoNetInfoRequestListener() { + @Override + public void onCarryOut() { + + } + }); + } + } } diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java new file mode 100644 index 0000000..392852d --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java @@ -0,0 +1,78 @@ +package cy.agorise.crystalwallet.viewmodels.validators; + +import android.accounts.Account; + +import java.util.ArrayList; +import java.util.List; + +import cy.agorise.crystalwallet.R; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests; +import cy.agorise.crystalwallet.cryptonetinforequests.ValidateImportBitsharesAccountRequest; +import cy.agorise.crystalwallet.models.AccountSeed; + +/** + * Created by Henry Varona on 2/10/2017. + */ + +public class ImportSeedValidator { + + private ImportSeedValidatorListener listener; + + private List validationFields; + private AccountSeed accountSeed; + + private boolean isValid = false; + + public ImportSeedValidator(AccountSeed seed){ + this.accountSeed = seed; + this.validationFields = new ArrayList(); + //this.validationFields.add(new ValidationField("pin")); + //this.validationFields.add(new ValidationField("pinConfirmation")); + this.validationFields.add(new ValidationField("accountname")); + } + + public void setListener(ImportSeedValidatorListener listener){ + this.listener = listener; + } + + public void validate(){ + //validatePin(); + //validatePinConfirmation(); + validateAccountName(); + } + + public ValidationField getValidationField(String name){ + for (int i=0;i Date: Mon, 2 Oct 2017 22:31:22 -0400 Subject: [PATCH 2/2] - Deleting databases generated schema --- .../2.json | 247 ------------------ 1 file changed, 247 deletions(-) delete mode 100644 app/schemas/cy.agorise.crystalwallet.dao.CrystalDatabase/2.json diff --git a/app/schemas/cy.agorise.crystalwallet.dao.CrystalDatabase/2.json b/app/schemas/cy.agorise.crystalwallet.dao.CrystalDatabase/2.json deleted file mode 100644 index 2145cfe..0000000 --- a/app/schemas/cy.agorise.crystalwallet.dao.CrystalDatabase/2.json +++ /dev/null @@ -1,247 +0,0 @@ -{ - "formatVersion": 1, - "database": { - "version": 2, - "identityHash": "e8e3aa452878e49fb9c7cfa99f356e4e", - "entities": [ - { - "tableName": "account_seed", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `master_seed` TEXT)", - "fields": [ - { - "fieldPath": "mId", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "mName", - "columnName": "name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "mMasterSeed", - "columnName": "master_seed", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - }, - { - "tableName": "crypto_net_account", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `seed_id` INTEGER NOT NULL, `account_number` INTEGER NOT NULL, `account_index` INTEGER NOT NULL, FOREIGN KEY(`seed_id`) REFERENCES `account_seed`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )", - "fields": [ - { - "fieldPath": "mId", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "mSeedId", - "columnName": "seed_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "mAccountNumber", - "columnName": "account_number", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "mAccountIndex", - "columnName": "account_index", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [ - { - "name": "index_crypto_net_account_id", - "unique": false, - "columnNames": [ - "id" - ], - "createSql": "CREATE INDEX `index_crypto_net_account_id` ON `${TABLE_NAME}` (`id`)" - }, - { - "name": "index_crypto_net_account_seed_id", - "unique": false, - "columnNames": [ - "seed_id" - ], - "createSql": "CREATE INDEX `index_crypto_net_account_seed_id` ON `${TABLE_NAME}` (`seed_id`)" - } - ], - "foreignKeys": [ - { - "table": "account_seed", - "onDelete": "NO ACTION", - "onUpdate": "NO ACTION", - "columns": [ - "seed_id" - ], - "referencedColumns": [ - "id" - ] - } - ] - }, - { - "tableName": "crypto_coin_transaction", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`account` INTEGER, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `date` INTEGER, `is_input` INTEGER NOT NULL, `account_id` INTEGER NOT NULL, `amount` INTEGER NOT NULL, `id_currency` INTEGER NOT NULL, `is_confirmed` INTEGER NOT NULL, `from` TEXT, `to` TEXT, FOREIGN KEY(`account_id`) REFERENCES `crypto_net_account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`id_currency`) REFERENCES `crypto_currency`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", - "fields": [ - { - "fieldPath": "account", - "columnName": "account", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "id", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "date", - "columnName": "date", - "affinity": "INTEGER", - "notNull": false - }, - { - "fieldPath": "isInput", - "columnName": "is_input", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "accountId", - "columnName": "account_id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "amount", - "columnName": "amount", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "idCurrency", - "columnName": "id_currency", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "isConfirmed", - "columnName": "is_confirmed", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "from", - "columnName": "from", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "to", - "columnName": "to", - "affinity": "TEXT", - "notNull": false - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [ - { - "table": "crypto_net_account", - "onDelete": "CASCADE", - "onUpdate": "NO ACTION", - "columns": [ - "account_id" - ], - "referencedColumns": [ - "id" - ] - }, - { - "table": "crypto_currency", - "onDelete": "CASCADE", - "onUpdate": "NO ACTION", - "columns": [ - "id_currency" - ], - "referencedColumns": [ - "id" - ] - } - ] - }, - { - "tableName": "crypto_currency", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `crypto_net` TEXT, `precision` INTEGER NOT NULL)", - "fields": [ - { - "fieldPath": "mId", - "columnName": "id", - "affinity": "INTEGER", - "notNull": true - }, - { - "fieldPath": "mName", - "columnName": "name", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "mCryptoNet", - "columnName": "crypto_net", - "affinity": "TEXT", - "notNull": false - }, - { - "fieldPath": "mPrecision", - "columnName": "precision", - "affinity": "INTEGER", - "notNull": true - } - ], - "primaryKey": { - "columnNames": [ - "id" - ], - "autoGenerate": true - }, - "indices": [], - "foreignKeys": [] - } - ], - "setupQueries": [ - "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"e8e3aa452878e49fb9c7cfa99f356e4e\")" - ] - } -} \ No newline at end of file