- Send Fragment is now working

- Fixed validations fields to work only with the last value inserted by the user
This commit is contained in:
Javier Varona 2018-01-21 17:20:09 -04:00
parent 93976cadd2
commit 2f496b0f2a
21 changed files with 263 additions and 82 deletions

View file

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "6a2b148b120a70c3faee581a13c96cf5",
"identityHash": "a44ccb96c8213951403ed2a283fb3367",
"entities": [
{
"tableName": "account_seed",
@ -44,7 +44,7 @@
},
{
"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_index` INTEGER NOT NULL, `crypto_net` TEXT, FOREIGN KEY(`seed_id`) REFERENCES `account_seed`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `seed_id` INTEGER NOT NULL, `account_index` INTEGER NOT NULL, `crypto_net` TEXT, `name` TEXT, FOREIGN KEY(`seed_id`) REFERENCES `account_seed`(`id`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "mId",
@ -69,6 +69,12 @@
"columnName": "crypto_net",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "mName",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
@ -616,7 +622,7 @@
],
"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, \"6a2b148b120a70c3faee581a13c96cf5\")"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"a44ccb96c8213951403ed2a283fb3367\")"
]
}
}

View file

@ -1,5 +1,7 @@
package cy.agorise.crystalwallet.activities;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.AnimationDrawable;
@ -24,6 +26,8 @@ import android.view.animation.LinearInterpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import java.util.List;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.ButterKnife;
@ -35,6 +39,8 @@ import cy.agorise.crystalwallet.fragments.ContactsFragment;
import cy.agorise.crystalwallet.fragments.ReceiveTransactionFragment;
import cy.agorise.crystalwallet.fragments.SendTransactionFragment;
import cy.agorise.crystalwallet.fragments.TransactionsFragment;
import cy.agorise.crystalwallet.models.CryptoNetBalance;
import cy.agorise.crystalwallet.viewmodels.CryptoNetBalanceListViewModel;
/**
* Created by Henry Varona on 7/10/2017.
@ -216,8 +222,17 @@ public class BoardActivity extends AppCompatActivity {
}
ft.addToBackStack(null);
long sendCryptoNetAccountId = -1;
if (this.cryptoNetAccountId != -1){
sendCryptoNetAccountId = this.cryptoNetAccountId;
} else {
CryptoNetBalanceListViewModel cryptoNetBalanceListViewModel = ViewModelProviders.of(this).get(CryptoNetBalanceListViewModel.class);
sendCryptoNetAccountId = cryptoNetBalanceListViewModel.getFirstBitsharesAccountId();
}
// Create and show the dialog.
SendTransactionFragment newFragment = SendTransactionFragment.newInstance(this.cryptoNetAccountId);
SendTransactionFragment newFragment = SendTransactionFragment.newInstance(sendCryptoNetAccountId);
newFragment.show(ft, "SendDialog");
}

View file

@ -26,6 +26,9 @@ public interface CryptoCoinBalanceDao {
@Query("SELECT id as account_id, crypto_net FROM crypto_net_account")
LiveData<List<CryptoNetBalance>> getAllBalances();
@Query("SELECT id FROM crypto_net_account WHERE crypto_net = 'BITSHARES' ORDER BY id ASC LIMIT 1")
long getFirstBitsharesAccountId();
@Query("SELECT * FROM crypto_coin_balance WHERE account_id = :accountId")
LiveData<List<CryptoCoinBalance>> getBalancesFromAccount(long accountId);

View file

@ -23,6 +23,9 @@ public interface CryptoNetAccountDao {
@Query("SELECT * FROM crypto_net_account")
LiveData<List<CryptoNetAccount>> getAll();
@Query("SELECT cna.* FROM crypto_net_account cna")
List<CryptoNetAccount> getAllCryptoNetAccount();
@Query("SELECT * FROM crypto_net_account WHERE id = :accountId")
LiveData<CryptoNetAccount> getByIdLiveData( long accountId);

View file

@ -3,6 +3,7 @@ package cy.agorise.crystalwallet.fragments;
import android.app.Dialog;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
@ -36,16 +37,21 @@ import butterknife.OnClick;
import butterknife.OnItemSelected;
import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.cryptonetinforequests.ValidateBitsharesSendRequest;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountListViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
import cy.agorise.crystalwallet.viewmodels.validators.SendTransactionValidator;
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
import cy.agorise.crystalwallet.views.CryptoCurrencyAdapter;
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class SendTransactionFragment extends DialogFragment implements UIValidatorListener, ZXingScannerView.ResultHandler {
@ -144,8 +150,15 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
}
});
// TODO SendTransactionValidator to accept spFrom
//sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
sendTransactionValidator = new SendTransactionValidator(this.getContext(), this.cryptoNetAccount, spFrom, etTo, spAsset, etAmount, etMemo);
sendTransactionValidator.setListener(this);
CryptoNetAccountListViewModel cryptoNetAccountListViewModel = ViewModelProviders.of(this).get(CryptoNetAccountListViewModel.class);
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
spFrom.setAdapter(fromSpinnerAdapter);
spFrom.setSelection(0);
// etFrom.setText(this.grapheneAccount.getName());
}
@ -214,11 +227,11 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
this.dismiss();
}
//@OnClick(R.id.btnSend)
@OnClick(R.id.btnSend)
public void sendTransaction(){
if (this.sendTransactionValidator.isValid()) {
//TODO convert the amount to long type using the precision of the currency
ValidateBitsharesSendRequest sendRequest = new ValidateBitsharesSendRequest(
final ValidateBitsharesSendRequest sendRequest = new ValidateBitsharesSendRequest(
this.getContext(),
this.grapheneAccount,
this.etTo.getText().toString(),
@ -227,7 +240,19 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
etMemo.getText().toString()
);
//this.finish();
sendRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if (sendRequest.isSend()){
try {
this.finalize();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(sendRequest);
}
}
@ -241,16 +266,18 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
public void onValidationSucceeded(final ValidationField field) {
final SendTransactionFragment fragment = this;
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (field.getView() == spFrom) {
tvFromError.setText("");
} else if (field.getView() == etTo){
} else if (field.getView() == etTo) {
tvToError.setText("");
} else if (field.getView() == etAmount){
} else if (field.getView() == etAmount) {
tvAmountError.setText("");
} else if (field.getView() == spAsset){
} else if (field.getView() == spAsset) {
tvAssetError.setText("");
} else if (field.getView() == etMemo){
} else if (field.getView() == etMemo) {
tvMemoError.setText("");
}
@ -262,21 +289,28 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
}
}
}
});
}
@Override
public void onValidationFailed(ValidationField field) {
public void onValidationFailed(final ValidationField field) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (field.getView() == spFrom) {
tvFromError.setText(field.getMessage());
} else if (field.getView() == etTo){
} else if (field.getView() == etTo) {
tvToError.setText(field.getMessage());
} else if (field.getView() == spAsset){
} else if (field.getView() == spAsset) {
tvAssetError.setText(field.getMessage());
} else if (field.getView() == etAmount){
} else if (field.getView() == etAmount) {
tvAmountError.setText(field.getMessage());
} else if (field.getView() == etMemo){
} else if (field.getView() == etMemo) {
tvMemoError.setText(field.getMessage());
}
}
});
}
@Override
public void handleResult(Result result) {

View file

@ -48,6 +48,12 @@ public class CryptoNetAccount {
@ColumnInfo(name = "crypto_net")
private CryptoNet mCryptoNet;
/*
* The name of the account
*/
@ColumnInfo(name = "name")
private String mName;
public CryptoNetAccount() {
}
@ -90,4 +96,16 @@ public class CryptoNetAccount {
public void setCryptoNet(CryptoNet cryptoNet) {
this.mCryptoNet = cryptoNet;
}
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
public String toString(){
return this.getName();
}
}

View file

@ -0,0 +1,29 @@
package cy.agorise.crystalwallet.viewmodels;
import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.LiveData;
import java.util.List;
import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.CryptoCoinBalance;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
/**
* Created by Henry Varona on 1/21/2018.
*/
public class CryptoNetAccountListViewModel extends AndroidViewModel {
private CrystalDatabase db;
public CryptoNetAccountListViewModel(Application application) {
super(application);
this.db = CrystalDatabase.getAppDatabase(application.getApplicationContext());
}
public List<CryptoNetAccount> getCryptoNetAccountList(){
return this.db.cryptoNetAccountDao().getAllCryptoNetAccount();
}
}

View file

@ -28,4 +28,8 @@ public class CryptoNetBalanceListViewModel extends AndroidViewModel {
public LiveData<List<CryptoNetBalance>> getCryptoNetBalanceList(){
return this.cryptoNetBalanceList;
}
public long getFirstBitsharesAccountId(){
return this.db.cryptoCoinBalanceDao().getFirstBitsharesAccountId();
}
}

View file

@ -20,7 +20,7 @@ public class SendTransactionValidator extends UIValidator {
private CryptoNetAccount account;
public SendTransactionValidator(Context context, CryptoNetAccount account, EditText fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){
public SendTransactionValidator(Context context, CryptoNetAccount account, Spinner fromEdit, EditText toEdit, Spinner assetSpinner, EditText amountEdit, EditText memoEdit){
super(context);
this.account = account;
this.addField(new FromValidationField(fromEdit));

View file

@ -42,22 +42,18 @@ public class AmountValidationField extends ValidationField {
CryptoCoinBalance balance = CrystalDatabase.getAppDatabase(amountField.getContext()).cryptoCoinBalanceDao().getBalanceFromAccount(this.account.getId(),cryptoCurrency.getId());
if (newAmountValue > balance.getBalance()){
setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.insufficient_amount));
setValidForValue(mixedValues, false);
setMessage(validator.getContext().getResources().getString(R.string.insufficient_amount));
validator.validationFailed(field);
} else if (newAmountValue == 0){
setMessageForValue(mixedValues, validator.getContext().getResources().getString(R.string.amount_should_be_greater_than_zero));
setValidForValue(mixedValues, false);
setMessage(validator.getContext().getResources().getString(R.string.amount_should_be_greater_than_zero));
validator.validationFailed(field);
} else {
setValidForValue(mixedValues, true);
validator.validationSucceeded(field);
}
} catch (NumberFormatException e){
setLastValue("");
setMessageForValue("",validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
setValidForValue("", false);
setMessage(validator.getContext().getResources().getString(R.string.please_enter_valid_amount));
validator.validationFailed(this);
}
}
}

View file

@ -28,13 +28,11 @@ public class AssetValidationField extends ValidationField {
final String newValue = "" + cryptoCurrencySelected.getId();
this.setLastValue(newValue);
setValidForValue(newValue, true);
validator.validationSucceeded(this);
} else {
final String newValue = ""+-1;
setMessage("Select a currency");
setMessageForValue(newValue,"Select a currency");
this.setLastValue(newValue);
setValidForValue(newValue, false);
validator.validationFailed(this);
}
}
}

View file

@ -36,12 +36,10 @@ public class BitsharesAccountMnemonicValidationField extends ValidationField {
@Override
public void onCarryOut() {
if (!request.getMnemonicIsCorrect()){
setMessageForValue(mixedValue,validator.getContext().getResources().getString(R.string.error_invalid_account));
setValidForValue(mixedValue, false);
setMessage(validator.getContext().getResources().getString(R.string.error_invalid_account));
validator.validationFailed(field);
} else {
setValidForValue(mixedValue, true);
validator.validationSucceeded(field);
}
}
});

View file

@ -27,7 +27,7 @@ public class BitsharesAccountNameDoesntExistsValidationField extends ValidationF
if (newValue.equals("")){
setValidForValue("", false);
setMessage("");
setMessageForValue("","");
validator.validationFailed(this);
} else {
@ -38,12 +38,10 @@ public class BitsharesAccountNameDoesntExistsValidationField extends ValidationF
@Override
public void onCarryOut() {
if (request.getAccountExists()) {
setMessageForValue(newValue,validator.getContext().getResources().getString(R.string.account_name_already_exist,"'"+newValue+"'"));
setValidForValue(newValue, false);
setMessage(validator.getContext().getResources().getString(R.string.account_name_already_exist,"'"+newValue+"'"));
validator.validationFailed(field);
} else {
setValidForValue(newValue, true);
validator.validationSucceeded(field);
}
}
});

View file

@ -31,12 +31,10 @@ public class BitsharesAccountNameValidationField extends ValidationField {
@Override
public void onCarryOut() {
if (!request.getAccountExists()){
setMessageForValue(newValue,validator.getContext().getResources().getString(R.string.account_name_not_exist));
setValidForValue(newValue, false);
setMessage(validator.getContext().getResources().getString(R.string.account_name_not_exist));
validator.validationFailed(field);
} else {
setValidForValue(newValue, true);
validator.validationSucceeded(field);
}
}
});

View file

@ -1,6 +1,7 @@
package cy.agorise.crystalwallet.viewmodels.validators.validationfields;
import android.widget.EditText;
import android.widget.Spinner;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener;
@ -13,15 +14,23 @@ import cy.agorise.crystalwallet.cryptonetinforequests.ValidateExistBitsharesAcco
public class FromValidationField extends ValidationField {
private EditText fromField;
//private EditText fromField;
private Spinner fromField;
public FromValidationField(EditText fromField){
public FromValidationField(Spinner fromField){
super(fromField);
this.fromField = fromField;
}
public void validate(){
final String newValue = fromField.getText().toString();
final String newValue;
if (fromField.getSelectedItem() != null) {
newValue = fromField.getSelectedItem().toString();
} else {
newValue = "";
}
this.setLastValue(newValue);
this.startValidating();
final ValidationField field = this;
@ -31,12 +40,10 @@ public class FromValidationField extends ValidationField {
@Override
public void onCarryOut() {
if (!request.getAccountExists()){
setMessageForValue(newValue,validator.getContext().getResources().getString(R.string.account_name_not_exist, "'"+newValue+"'"));
setValidForValue(newValue, false);
setMessage(validator.getContext().getResources().getString(R.string.account_name_not_exist));
validator.validationFailed(field);
} else {
setValidForValue(newValue, true);
validator.validationSucceeded(field);
}
}
});

View file

@ -29,12 +29,10 @@ public class PinConfirmationValidationField extends ValidationField {
if (!newConfirmationValue.equals(newValue)){
this.setMessageForValue(mixedValue,this.validator.getContext().getResources().getString(R.string.mismatch_pin));
this.setValidForValue(mixedValue,false);
this.setMessage(this.validator.getContext().getResources().getString(R.string.mismatch_pin));
this.validator.validationFailed(this);
} else {
this.setValidForValue(mixedValue, true);
this.validator.validationSucceeded(this);
}
}
}

View file

@ -25,12 +25,10 @@ public class PinValidationField extends ValidationField {
this.startValidating();
if (newValue.length() < 6) {
this.setMessageForValue(newValue, this.validator.getContext().getResources().getString(R.string.pin_number_warning));
this.setValidForValue(newValue, false);
this.setMessage(this.validator.getContext().getResources().getString(R.string.pin_number_warning));
this.validator.validationFailed(this);
} else {
this.setValidForValue(newValue, true);
this.validator.validationSucceeded(this);
}
}
}

View file

@ -1,6 +1,7 @@
package cy.agorise.crystalwallet.viewmodels.validators.validationfields;
import android.widget.EditText;
import android.widget.Spinner;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener;
@ -13,17 +14,22 @@ import cy.agorise.crystalwallet.cryptonetinforequests.ValidateExistBitsharesAcco
public class ToValidationField extends ValidationField {
private EditText fromField;
private Spinner fromField;
private EditText toField;
public ToValidationField(EditText fromField, EditText toField){
public ToValidationField(Spinner fromField, EditText toField){
super(toField);
this.fromField = fromField;
this.toField = toField;
}
public void validate(){
final String fromNewValue = fromField.getText().toString();
final String fromNewValue;
if (fromField.getSelectedItem() != null) {
fromNewValue = fromField.getSelectedItem().toString();
} else {
fromNewValue = "";
}
final String toNewValue = toField.getText().toString();
final String mixedValue = fromNewValue+"_"+toNewValue;
this.setLastValue(mixedValue);
@ -31,9 +37,8 @@ public class ToValidationField extends ValidationField {
final ValidationField field = this;
if (fromNewValue.equals(toNewValue)){
setMessageForValue(mixedValue,validator.getContext().getResources().getString(R.string.warning_msg_same_account));
setValidForValue(mixedValue, false);
setMessage(validator.getContext().getResources().getString(R.string.warning_msg_same_account));
validator.validationFailed(field);
} else {
final ValidateExistBitsharesAccountRequest request = new ValidateExistBitsharesAccountRequest(toNewValue);
@ -41,12 +46,10 @@ public class ToValidationField extends ValidationField {
@Override
public void onCarryOut() {
if (!request.getAccountExists()) {
setMessageForValue(mixedValue, validator.getContext().getResources().getString(R.string.account_name_not_exist,"'"+toNewValue+"'"));
setValidForValue(mixedValue, false);
setMessage(validator.getContext().getResources().getString(R.string.account_name_not_exist));
validator.validationFailed(field);
} else {
setValidForValue(mixedValue, true);
validator.validationSucceeded(field);
}
}
});

View file

@ -41,15 +41,23 @@ public abstract class ValidationField {
this.validating = false;
}
public void setValidForValue(String value, boolean newValue){
public void setValidForValue(String value, boolean isValid){
if (this.lastValue.equals(value)) {
this.validating = false;
this.valid = newValue;
this.valid = isValid;
if (isValid) {
validator.validationSucceeded(this);
} else {
validator.validationFailed(this);
}
}
}
public void setMessage(String newValue){
this.message = newValue;
public void setMessageForValue(String value, String message){
if (this.lastValue.equals(value)) {
this.message = message;
}
}
public String getMessage(){

View file

@ -0,0 +1,51 @@
package cy.agorise.crystalwallet.views;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.List;
import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.models.CryptoCurrency;
import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
/**
* Created by Henry Varona on 01/20/2018.
*
* The adapter to show a list of crypto net account in a spinner.
*/
public class CryptoNetAccountAdapter extends ArrayAdapter<CryptoNetAccount> {
private List<CryptoNetAccount> data;
public CryptoNetAccountAdapter(Context context, int resource, List<CryptoNetAccount> objects) {
super(context, resource, objects);
this.data = objects;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
/*
* Creates the view for every element of the spinner
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.crypto_net_account_adapter_item, parent, false);
TextView tvCryptoNetAccountName = v.findViewById(R.id.tvCryptoNetAccountName);
CryptoNetAccount cryptoNetAccount = getItem(position);
tvCryptoNetAccountName.setText(cryptoNetAccount.getName());
return v;
}
}

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp">
<TextView
android:id="@+id/tvCryptoNetAccountName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" />
</LinearLayout>