diff --git a/app/build.gradle b/app/build.gradle index 45cfff8..86d110b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,25 +30,24 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) //androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.1', { - exclude group: 'com.android.support', module: 'support-annotations' + exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:26.1.0' + //testCompile 'com.android.support.test:runner:1.0.1' + + + + + + + compile 'com.android.support:appcompat-v7:26.1.0' compile 'com.android.support:support-v4:26.1.0' compile 'com.android.support:design:26.1.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' - testCompile 'junit:junit:4.12' - testCompile 'org.mockito:mockito-core:1.10.19' - //testCompile 'com.android.support.test:runner:1.0.1' - - compile "android.arch.lifecycle:runtime:1.0.0-alpha9-1" - compile "android.arch.lifecycle:extensions:1.0.0-alpha9-1" - annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha9-1" - compile 'android.arch.persistence.room:runtime:1.0.0-alpha9-1'; - apt "android.arch.persistence.room:compiler:1.0.0-alpha9-1"; - compile "android.arch.paging:runtime:1.0.0-alpha1"; - - compile 'com.idescout.sql:sqlscout-server:2.0'; - + compile 'android.arch.lifecycle:runtime:1.0.0-alpha9-1' + compile 'android.arch.lifecycle:extensions:1.0.0-alpha9-1' + compile 'android.arch.persistence.room:runtime:1.0.0-alpha9-1' + compile 'android.arch.paging:runtime:1.0.0-alpha1' + compile 'com.idescout.sql:sqlscout-server:2.0' compile 'com.google.code.gson:gson:2.2.4' compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' @@ -56,7 +55,10 @@ dependencies { compile 'com.neovisionaries:nv-websocket-client:1.30' compile 'org.tukaani:xz:1.6' compile 'com.jakewharton:butterknife:8.8.1' - apt 'com.jakewharton:butterknife-compiler:8.8.1' compile 'com.github.bilthon:graphenej:0.4.5' - + testCompile 'junit:junit:4.12' + testCompile 'org.mockito:mockito-core:1.10.19' + annotationProcessor 'android.arch.lifecycle:compiler:1.0.0-alpha9-1' + apt 'android.arch.persistence.room:compiler:1.0.0-alpha9-1' + apt 'com.jakewharton:butterknife-compiler:8.8.1' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5f6634b..886b7da 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,8 @@ + + diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/BoardActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/BoardActivity.java new file mode 100644 index 0000000..d797ec8 --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/BoardActivity.java @@ -0,0 +1,64 @@ +package cy.agorise.crystalwallet.activities; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.PagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; + +import butterknife.BindView; +import butterknife.ButterKnife; +import cy.agorise.crystalwallet.R; +import cy.agorise.crystalwallet.fragments.BalanceFragment; +import cy.agorise.crystalwallet.fragments.ContactsFragment; +import cy.agorise.crystalwallet.fragments.TransactionsFragment; + +/** + * Created by Henry Varona on 7/10/2017. + */ + +public class BoardActivity extends AppCompatActivity { + + @BindView(R.id.pager) + public ViewPager mPager; + + public BoardPagerAdapter boardAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.board); + ButterKnife.bind(this); + + boardAdapter = new BoardPagerAdapter(getSupportFragmentManager()); + mPager.setAdapter(boardAdapter); + } + + private class BoardPagerAdapter extends FragmentStatePagerAdapter { + public BoardPagerAdapter(FragmentManager fm) { + super(fm); + } + + @Override + public Fragment getItem(int position) { + switch (position){ + case 0: + return new BalanceFragment(); + case 1: + return new TransactionsFragment(); + case 2: + return new ContactsFragment(); + } + + + return null; //new OnConstructionFragment(); + } + + @Override + public int getCount() { + return 3; + } + } +} 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 3b6ccdc..15fd0b7 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/ImportSeedActivity.java @@ -1,17 +1,12 @@ package cy.agorise.crystalwallet.activities; -import android.arch.lifecycle.LifecycleActivity; 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; -import android.widget.Toast; - -import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; @@ -19,15 +14,12 @@ 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.viewmodels.validators.UIValidatorListener; import cy.agorise.crystalwallet.viewmodels.validators.ValidationField; -import cy.agorise.crystalwallet.views.TransactionListView; -public class ImportSeedActivity extends AppCompatActivity implements ImportSeedValidatorListener { +public class ImportSeedActivity extends AppCompatActivity implements UIValidatorListener { AccountSeedViewModel accountSeedViewModel; ImportSeedValidator importSeedValidator; @@ -60,29 +52,28 @@ public class ImportSeedActivity extends AppCompatActivity implements ImportSeedV ButterKnife.bind(this); + btnImport.setEnabled(false); accountSeedViewModel = ViewModelProviders.of(this).get(AccountSeedViewModel.class); - importSeedValidator = accountSeedViewModel.getValidator(); - + importSeedValidator = new ImportSeedValidator(this.getApplicationContext(),etPin,etPinConfirmation,etAccountName,etSeedWords); importSeedValidator.setListener(this); } @OnTextChanged(value = R.id.etPin, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) void afterPinChanged(Editable editable) { - this.importSeedValidator.validatePin(editable.toString()); - this.importSeedValidator.validatePinConfirmation(etPinConfirmation.getText().toString(),editable.toString()); + this.importSeedValidator.validate(); } @OnTextChanged(value = R.id.etPinConfirmation, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) void afterPinConfirmationChanged(Editable editable) { - this.importSeedValidator.validatePinConfirmation(editable.toString(), etPin.getText().toString()); + this.importSeedValidator.validate(); } @OnTextChanged(value = R.id.etAccountName, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) void afterAccountNameChanged(Editable editable) { - this.importSeedValidator.validateAccountName(editable.toString(), etSeedWords.getText().toString()); + this.importSeedValidator.validate(); } @OnClick(R.id.btnImport) @@ -103,31 +94,27 @@ public class ImportSeedActivity extends AppCompatActivity implements ImportSeedV @Override public void onValidationSucceeded(ValidationField field) { - switch (field.getName()){ - case "pin": - tvPinError.setText(""); - break; - case "pinconfirmation": - tvPinConfirmationError.setText(""); - break; - case "accountname": - tvAccountNameError.setText(""); - break; + if (field.getView() == etPin) { + tvPinError.setText(""); + } else if (field.getView() == etPinConfirmation){ + tvPinConfirmationError.setText(""); + } else if (field.getView() == etAccountName){ + tvAccountNameError.setText(""); + } + + if (this.importSeedValidator.isValid()){ + btnImport.setEnabled(true); } } @Override public void onValidationFailed(ValidationField field) { - switch (field.getName()){ - case "pin": - tvPinError.setText(field.getMessage()); - break; - case "pinconfirmation": - tvPinConfirmationError.setText(field.getMessage()); - break; - case "accountname": - tvAccountNameError.setText(field.getMessage()); - break; + if (field.getView() == etPin) { + tvPinError.setText(field.getMessage()); + } else if (field.getView() == etPinConfirmation){ + tvPinConfirmationError.setText(field.getMessage()); + } else if (field.getView() == etAccountName){ + tvAccountNameError.setText(field.getMessage()); } } } diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java index b5aa54a..89a46a6 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java +++ b/app/src/main/java/cy/agorise/crystalwallet/activities/IntroActivity.java @@ -42,12 +42,15 @@ public class IntroActivity extends AppCompatActivity { //Checks if the user has any seed created AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of(this).get(AccountSeedListViewModel.class); - //if (accountSeedListViewModel.accountSeedsCount() == 0){ + if (accountSeedListViewModel.accountSeedsCount() == 0){ //If the user doesn't have any seeds created, then //send the user to create/import an account Intent intent = new Intent(this, AccountSeedsManagementActivity.class); startActivity(intent); - //} + } else { + Intent intent = new Intent(this, BoardActivity.class); + startActivity(intent); + } /*CrystalDatabase db = CrystalDatabase.getAppDatabase(getApplicationContext()); List seeds = RandomSeedGenerator.generateSeeds(2); diff --git a/app/src/main/java/cy/agorise/crystalwallet/fragments/BalanceFragment.java b/app/src/main/java/cy/agorise/crystalwallet/fragments/BalanceFragment.java new file mode 100644 index 0000000..ed553d5 --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/fragments/BalanceFragment.java @@ -0,0 +1,36 @@ +package cy.agorise.crystalwallet.fragments; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import cy.agorise.crystalwallet.R; + +public class BalanceFragment extends Fragment { + public BalanceFragment() { + // Required empty public constructor + } + + public static BalanceFragment newInstance() { + BalanceFragment fragment = new BalanceFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_balance, container, false); + } +} diff --git a/app/src/main/java/cy/agorise/crystalwallet/fragments/ContactsFragment.java b/app/src/main/java/cy/agorise/crystalwallet/fragments/ContactsFragment.java new file mode 100644 index 0000000..558d81b --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/fragments/ContactsFragment.java @@ -0,0 +1,34 @@ +package cy.agorise.crystalwallet.fragments; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import cy.agorise.crystalwallet.R; + +public class ContactsFragment extends Fragment { + public ContactsFragment() { + // Required empty public constructor + } + + public static ContactsFragment newInstance() { + ContactsFragment fragment = new ContactsFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_contacts, container, false); + } +} diff --git a/app/src/main/java/cy/agorise/crystalwallet/fragments/TransactionsFragment.java b/app/src/main/java/cy/agorise/crystalwallet/fragments/TransactionsFragment.java new file mode 100644 index 0000000..d98763f --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/fragments/TransactionsFragment.java @@ -0,0 +1,34 @@ +package cy.agorise.crystalwallet.fragments; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import cy.agorise.crystalwallet.R; + +public class TransactionsFragment extends Fragment { + public TransactionsFragment() { + // Required empty public constructor + } + + public static TransactionsFragment newInstance() { + TransactionsFragment fragment = new TransactionsFragment(); + Bundle args = new Bundle(); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_transactions, container, false); + } +} 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 4c8a90a..1632798 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/AccountSeedViewModel.java @@ -21,7 +21,6 @@ public class AccountSeedViewModel extends AndroidViewModel { private LiveData accountSeed; private CrystalDatabase db; - private ImportSeedValidator importSeedValidator; private Application app; public AccountSeedViewModel(Application application) { @@ -34,14 +33,6 @@ public class AccountSeedViewModel extends AndroidViewModel { this.accountSeed = this.db.accountSeedDao().findById(seedId); } - public ImportSeedValidator getValidator(){ - if (this.importSeedValidator == null){ - this.importSeedValidator = new ImportSeedValidator(this.app.getResources()); - - } - return this.importSeedValidator; - } - public void addSeed(AccountSeed seed){ this.db.accountSeedDao().insertAccountSeed(seed); } @@ -50,17 +41,4 @@ public class AccountSeedViewModel extends AndroidViewModel { 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/BitsharesAccountMnemonicValidationField.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/BitsharesAccountMnemonicValidationField.java new file mode 100644 index 0000000..b534951 --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/BitsharesAccountMnemonicValidationField.java @@ -0,0 +1,50 @@ +package cy.agorise.crystalwallet.viewmodels.validators; + +import android.widget.EditText; + +import cy.agorise.crystalwallet.R; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests; +import cy.agorise.crystalwallet.cryptonetinforequests.ValidateImportBitsharesAccountRequest; + +/** + * Created by Henry Varona on 7/10/2017. + */ + +public class BitsharesAccountMnemonicValidationField extends ValidationField { + + private EditText mnemonicField; + private EditText accountNameField; + + public BitsharesAccountMnemonicValidationField(EditText mnemonicField, EditText accountNameField){ + super(mnemonicField); + this.mnemonicField = mnemonicField; + this.accountNameField = accountNameField; + } + + public void validate(){ + final String newMnemonicValue = mnemonicField.getText().toString(); + final String newAccountNameValue = accountNameField.getText().toString(); + final String mixedValue = newMnemonicValue+"_"+newAccountNameValue; + + this.setLastValue(mixedValue); + this.startValidating(); + final ValidationField field = this; + + final ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(newAccountNameValue,newMnemonicValue); + request.setListener(new CryptoNetInfoRequestListener() { + @Override + public void onCarryOut() { + if (!request.getMnemonicIsCorrect()){ + setValidForValue(mixedValue, false); + setMessage(validator.getContext().getResources().getString(R.string.account_name_not_exist)); + validator.validationFailed(field); + } else { + setValidForValue(mixedValue, true); + validator.validationSucceeded(field); + } + } + }); + CryptoNetInfoRequests.getInstance().addRequest(request); + } +} diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/BitsharesAccountNameValidationField.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/BitsharesAccountNameValidationField.java new file mode 100644 index 0000000..c38caaa --- /dev/null +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/BitsharesAccountNameValidationField.java @@ -0,0 +1,46 @@ +package cy.agorise.crystalwallet.viewmodels.validators; + +import android.content.Context; +import android.widget.EditText; + +import cy.agorise.crystalwallet.R; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequestListener; +import cy.agorise.crystalwallet.cryptonetinforequests.CryptoNetInfoRequests; +import cy.agorise.crystalwallet.cryptonetinforequests.ValidateImportBitsharesAccountRequest; + +/** + * Created by Henry Varona on 7/10/2017. + */ + +public class BitsharesAccountNameValidationField extends ValidationField { + + private EditText accountNameField; + + public BitsharesAccountNameValidationField(EditText accountNameField){ + super(accountNameField); + this.accountNameField = accountNameField; + } + + public void validate(){ + final String newValue = accountNameField.getText().toString(); + this.setLastValue(newValue); + this.startValidating(); + final ValidationField field = this; + + final ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(newValue,""); + request.setListener(new CryptoNetInfoRequestListener() { + @Override + public void onCarryOut() { + if (!request.getAccountExists()){ + setValidForValue(newValue, false); + setMessage(validator.getContext().getResources().getString(R.string.error_invalid_account)); + validator.validationFailed(field); + } else { + setValidForValue(newValue, true); + validator.validationSucceeded(field); + } + } + }); + CryptoNetInfoRequests.getInstance().addRequest(request); + } +} 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 index e000bc2..55f6742 100644 --- a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java +++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/ImportSeedValidator.java @@ -1,110 +1,19 @@ package cy.agorise.crystalwallet.viewmodels.validators; -import android.accounts.Account; -import android.content.res.Resources; - -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; +import android.content.Context; +import android.widget.EditText; /** * Created by Henry Varona on 2/10/2017. */ -public class ImportSeedValidator { +public class ImportSeedValidator extends UIValidator { - private ImportSeedValidatorListener listener; - private List validationFields; - private AccountSeed accountSeed; - private Resources res; - - private boolean isValid = false; - - public ImportSeedValidator(Resources res){ - this.res = res; - 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 boolean isValid(){ - for(int i=0;i validationFields; + + public UIValidator(Context context){ + this.context = context; + this.validationFields = new ArrayList(); + } + + public void addField(ValidationField newField){ + this.validationFields.add(newField); + newField.setValidator(this); + } + + public Context getContext(){ + return this.context; + } + + public void setListener(UIValidatorListener listener){ + this.listener = listener; + } + + public boolean isValid(){ + for(int i=0;i + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_balance.xml b/app/src/main/res/layout/fragment_balance.xml new file mode 100644 index 0000000..af891c5 --- /dev/null +++ b/app/src/main/res/layout/fragment_balance.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_contacts.xml b/app/src/main/res/layout/fragment_contacts.xml new file mode 100644 index 0000000..2612646 --- /dev/null +++ b/app/src/main/res/layout/fragment_contacts.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_transactions.xml b/app/src/main/res/layout/fragment_transactions.xml new file mode 100644 index 0000000..3f86fe2 --- /dev/null +++ b/app/src/main/res/layout/fragment_transactions.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9eb5aad..4e91a18 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -449,4 +449,7 @@ Current backup password New PIN (6+ digits) + + + Hello blank fragment