diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 52adab6..90f510b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,6 +36,8 @@
+
+
diff --git a/app/src/main/java/cy/agorise/crystalwallet/activities/PinRequestActivity.java b/app/src/main/java/cy/agorise/crystalwallet/activities/PinRequestActivity.java
new file mode 100644
index 0000000..ecc82eb
--- /dev/null
+++ b/app/src/main/java/cy/agorise/crystalwallet/activities/PinRequestActivity.java
@@ -0,0 +1,42 @@
+package cy.agorise.crystalwallet.activities;
+
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.Observer;
+import android.arch.lifecycle.ViewModelProviders;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AppCompatActivity;
+import android.text.Editable;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+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.models.GeneralSetting;
+import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
+
+public class PinRequestActivity extends AppCompatActivity {
+
+ @BindView(R.id.etPassword)
+ EditText etPassword;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pin_request);
+ ButterKnife.bind(this);
+ }
+
+ @OnTextChanged(value = R.id.etPassword,
+ callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
+ void afterPasswordChanged(Editable editable) {
+ this.finish();
+ }
+}
+
+
diff --git a/app/src/main/java/cy/agorise/crystalwallet/application/CrystalApplication.java b/app/src/main/java/cy/agorise/crystalwallet/application/CrystalApplication.java
index fc5f6c7..64e7345 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/application/CrystalApplication.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/application/CrystalApplication.java
@@ -26,5 +26,7 @@ public class CrystalApplication extends Application {
Intent intent = new Intent(getApplicationContext(), CrystalWalletService.class);
startService(intent);
+
+ registerActivityLifecycleCallbacks(new CrystalSecurityMonitor());
}
}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/application/CrystalSecurityMonitor.java b/app/src/main/java/cy/agorise/crystalwallet/application/CrystalSecurityMonitor.java
new file mode 100644
index 0000000..c99729d
--- /dev/null
+++ b/app/src/main/java/cy/agorise/crystalwallet/application/CrystalSecurityMonitor.java
@@ -0,0 +1,70 @@
+package cy.agorise.crystalwallet.application;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.Toast;
+
+import cy.agorise.crystalwallet.activities.CreateSeedActivity;
+import cy.agorise.crystalwallet.activities.PinRequestActivity;
+
+/**
+ * Created by Henry Varona on 27/1/2018.
+ */
+
+class CrystalSecurityMonitor implements Application.ActivityLifecycleCallbacks {
+ private int numStarted = 0;
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ if (numStarted == 0) {
+ callPasswordRequest(activity);
+ }
+ numStarted++;
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ numStarted--;
+ if (numStarted == 0) {
+ callPasswordRequest(activity);
+ }
+ }
+
+ public void callPasswordRequest(Activity activity){
+ if ((!activity.getIntent().hasExtra("ACTIVITY_TYPE")) || (!activity.getIntent().getStringExtra("ACTIVITY_TYPE").equals("PASSWORD_REQUEST"))) {
+ //Intent intent = new Intent(activity, PinRequestActivity.class);
+ //intent.putExtra("ACTIVITY_TYPE", "PASSWORD_REQUEST");
+ //activity.startActivity(intent);
+ }
+ }
+
+ @Override
+ public void onActivityCreated(Activity activity, Bundle bundle) {
+ //
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ //
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ //
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
+ //
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ //
+ }
+
+
+
+}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/dao/CryptoCurrencyDao.java b/app/src/main/java/cy/agorise/crystalwallet/dao/CryptoCurrencyDao.java
index 6826c4f..f821a35 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/dao/CryptoCurrencyDao.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/dao/CryptoCurrencyDao.java
@@ -1,5 +1,6 @@
package cy.agorise.crystalwallet.dao;
+import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
@@ -28,6 +29,9 @@ public interface CryptoCurrencyDao {
@Query("SELECT * FROM crypto_currency WHERE id IN (:ids)")
List getByIds(List ids);
+ @Query("SELECT * FROM crypto_currency WHERE name = :name")
+ LiveData getLiveDataByName(String name);
+
@Query("SELECT * FROM crypto_currency WHERE name = :name")
CryptoCurrency getByName(String name);
diff --git a/app/src/main/java/cy/agorise/crystalwallet/fragments/GeneralSettingsFragment.java b/app/src/main/java/cy/agorise/crystalwallet/fragments/GeneralSettingsFragment.java
index 7be6e28..e91e848 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/fragments/GeneralSettingsFragment.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/fragments/GeneralSettingsFragment.java
@@ -1,19 +1,44 @@
package cy.agorise.crystalwallet.fragments;
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.Observer;
+import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Currency;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+
+import butterknife.BindView;
import butterknife.ButterKnife;
+import butterknife.OnItemSelected;
import cy.agorise.crystalwallet.R;
+import cy.agorise.crystalwallet.models.GeneralSetting;
+import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
/**
* Created by xd on 12/28/17.
*/
public class GeneralSettingsFragment extends Fragment {
+
+ private HashMap countriesMap;
+ private GeneralSettingListViewModel generalSettingListViewModel;
+ private LiveData> generalSettingListLiveData;
+
+ @BindView (R.id.spTaxableCountry)
+ Spinner spTaxableCountry;
+
public GeneralSettingsFragment() {
// Required empty public constructor
}
@@ -37,6 +62,83 @@ public class GeneralSettingsFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_general_settings, container, false);
ButterKnife.bind(this, v);
+ generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
+ generalSettingListLiveData = generalSettingListViewModel.getGeneralSettingList();
+
+ // Initializes the countries spinner
+ countriesMap = new HashMap();
+ String[] countryCodeList = Locale.getISOCountries();
+ ArrayList countryAndCurrencyList = new ArrayList();
+ String countryAndCurrencyLabel = "";
+ for (String countryCode : countryCodeList) {
+ Locale locale = new Locale("", countryCode);
+ try {
+ Currency currency = Currency.getInstance(locale);
+ countryAndCurrencyLabel = locale.getDisplayCountry() + " (" + currency.getCurrencyCode() + ")";
+ countryAndCurrencyList.add(countryAndCurrencyLabel);
+ countriesMap.put(countryCode, countryAndCurrencyLabel);
+ countriesMap.put(countryAndCurrencyLabel, countryCode);
+ } catch (Exception e) {
+
+ }
+ }
+ Collections.sort(countryAndCurrencyList);
+ countryAndCurrencyList.add(0,"SELECT COUNTRY");
+ ArrayAdapter countryAdapter = new ArrayAdapter(this.getContext(), android.R.layout.simple_spinner_item, countryAndCurrencyList);
+ spTaxableCountry.setAdapter(countryAdapter);
+
+ //Observes the general settings data
+ generalSettingListLiveData.observe(this, new Observer>() {
+ @Override
+ public void onChanged(@Nullable List generalSettings) {
+ loadSettings(generalSettings);
+ }
+ });
+
return v;
}
+
+ public GeneralSetting getSetting(String name){
+ for (GeneralSetting generalSetting:this.generalSettingListLiveData.getValue()) {
+ if (generalSetting.getName().equals(name)) {
+ return generalSetting;
+ }
+ }
+
+ return null;
+ }
+
+ @OnItemSelected(R.id.spTaxableCountry)
+ void onItemSelected(int position) {
+ if (position != 0) {
+ GeneralSetting generalSettingCountryCode = this.getSetting(GeneralSetting.SETTING_NAME_PREFERED_COUNTRY);
+ GeneralSetting generalSettingCurrency = this.getSetting(GeneralSetting.SETTING_NAME_PREFERED_CURRENCY);
+
+ if (generalSettingCountryCode == null){
+ generalSettingCountryCode = new GeneralSetting();
+ generalSettingCountryCode.setName(GeneralSetting.SETTING_NAME_PREFERED_COUNTRY);
+ }
+ if (generalSettingCurrency == null){
+ generalSettingCurrency = new GeneralSetting();
+ generalSettingCurrency.setName(GeneralSetting.SETTING_NAME_PREFERED_CURRENCY);
+ }
+
+ String countryCode = countriesMap.get((String) spTaxableCountry.getSelectedItem());
+ Locale locale = new Locale("", countryCode);
+ Currency currency = Currency.getInstance(locale);
+
+ generalSettingCountryCode.setValue(countryCode);
+ generalSettingCurrency.setValue(currency.getCurrencyCode());
+ this.generalSettingListViewModel.saveGeneralSettings(generalSettingCountryCode, generalSettingCurrency);
+ }
+ }
+
+ public void loadSettings(List generalSettings){
+ for (GeneralSetting generalSetting:generalSettings) {
+ if (generalSetting.getName().equals(GeneralSetting.SETTING_NAME_PREFERED_COUNTRY)){
+ String preferedCountryCode = generalSetting.getValue();
+ spTaxableCountry.setSelection(((ArrayAdapter)spTaxableCountry.getAdapter()).getPosition(countriesMap.get(preferedCountryCode)));
+ }
+ }
+ }
}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/fragments/PinSecurityFragment.java b/app/src/main/java/cy/agorise/crystalwallet/fragments/PinSecurityFragment.java
index 52e2c55..6c75211 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/fragments/PinSecurityFragment.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/fragments/PinSecurityFragment.java
@@ -1,19 +1,60 @@
package cy.agorise.crystalwallet.fragments;
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.Observer;
+import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
+import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+import java.util.List;
+
+import butterknife.BindView;
import butterknife.ButterKnife;
+import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R;
+import cy.agorise.crystalwallet.activities.CreateSeedActivity;
+import cy.agorise.crystalwallet.dao.CrystalDatabase;
+import cy.agorise.crystalwallet.models.GeneralSetting;
+import cy.agorise.crystalwallet.util.PasswordManager;
+import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
+import cy.agorise.crystalwallet.viewmodels.validators.PinSecurityValidator;
+import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener;
+import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField;
/**
* Created by xd on 1/18/18.
*/
-public class PinSecurityFragment extends Fragment {
+public class PinSecurityFragment extends Fragment implements UIValidatorListener {
+
+ @BindView(R.id.tvCurrentPin)
+ TextView tvCurrentPin;
+ @BindView(R.id.etCurrentPin)
+ EditText etCurrentPin;
+ @BindView(R.id.etNewPin)
+ EditText etNewPin;
+ @BindView(R.id.etConfirmPin)
+ EditText etConfirmPin;
+
+ @BindView(R.id.tvCurrentPinError)
+ TextView tvCurrentPinError;
+ @BindView(R.id.tvNewPinError)
+ TextView tvNewPinError;
+ @BindView(R.id.tvConfirmPinError)
+ TextView tvConfirmPinError;
+
+ GeneralSettingListViewModel generalSettingListViewModel;
+ GeneralSetting passwordGeneralSetting;
+ PinSecurityValidator pinSecurityValidator;
public PinSecurityFragment() {
// Required empty public constructor
@@ -33,6 +74,140 @@ public class PinSecurityFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_pin_security, container, false);
ButterKnife.bind(this, v);
+ generalSettingListViewModel = ViewModelProviders.of(this).get(GeneralSettingListViewModel.class);
+ LiveData> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
+
+ pinSecurityValidator = new PinSecurityValidator(this.getContext(), etCurrentPin, etNewPin, etConfirmPin);
+ pinSecurityValidator.setListener(this);
+
+ generalSettingsLiveData.observe(this, new Observer>() {
+ @Override
+ public void onChanged(@Nullable List generalSettings) {
+ boolean founded = false;
+
+ if (generalSettings != null){
+ for (GeneralSetting generalSetting:generalSettings) {
+ if (generalSetting.getName().equals(GeneralSetting.SETTING_PASSWORD)){
+ founded = true;
+ if (!generalSetting.getValue().isEmpty()){
+ passwordGeneralSetting = generalSetting;
+ showCurrentPinUI(true);
+ } else {
+ showCurrentPinUI(false);
+ }
+ break;
+ }
+ }
+ if (!founded){
+ showCurrentPinUI(false);
+ }
+ } else {
+ showCurrentPinUI(false);
+ }
+ }
+ });
+
return v;
}
+
+ public void showCurrentPinUI(Boolean visible){
+ if (visible){
+ tvCurrentPin.setVisibility(View.VISIBLE);
+ etCurrentPin.setVisibility(View.VISIBLE);
+ } else {
+ tvCurrentPin.setVisibility(View.GONE);
+ etCurrentPin.setVisibility(View.GONE);
+ }
+ }
+
+ @OnTextChanged(value = R.id.etCurrentPin,
+ callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
+ void afterCurrentPinChanged(Editable editable) {
+ this.pinSecurityValidator.validate();
+ }
+
+ @OnTextChanged(value = R.id.etNewPin,
+ callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
+ void afterNewPinChanged(Editable editable) {
+ this.pinSecurityValidator.validate();
+ }
+
+ @OnTextChanged(value = R.id.etConfirmPin,
+ callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
+ void afterConfirmPinChanged(Editable editable) {
+ this.pinSecurityValidator.validate();
+ }
+
+ public void clearFields(){
+ if (!this.etCurrentPin.getText().toString().equals("")) {
+ this.etCurrentPin.setText("");
+ }
+ if (!this.etNewPin.getText().toString().equals("")) {
+ this.etNewPin.setText("");
+ }
+ if (!this.etConfirmPin.getText().toString().equals("")) {
+ this.etConfirmPin.setText("");
+ }
+ }
+
+ @Override
+ public void onValidationSucceeded(final ValidationField field) {
+ final PinSecurityFragment fragment = this;
+
+ this.getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+
+ if (field.getView() == etCurrentPin) {
+ tvCurrentPinError.setText("");
+ } else if (field.getView() == etNewPin){
+ tvNewPinError.setText("");
+ } else if (field.getView() == etConfirmPin){
+ tvConfirmPinError.setText("");
+ }
+
+ if (pinSecurityValidator.isValid()){
+ CharSequence text = "Your password has been sucessfully changed!";
+ int duration = Toast.LENGTH_SHORT;
+
+ Toast toast = Toast.makeText(getContext(), text, duration);
+ toast.show();
+ //showCurrentPinUI(true);
+
+ savePassword(etNewPin.getText().toString());
+
+
+ clearFields();
+ }
+ }
+ });
+ }
+
+ public void savePassword(String password) {
+ String passwordEncripted = PasswordManager.encriptPassword(password);
+
+ if (passwordGeneralSetting == null) {
+ passwordGeneralSetting = new GeneralSetting();
+ passwordGeneralSetting.setName(GeneralSetting.SETTING_PASSWORD);
+ }
+
+ passwordGeneralSetting.setValue(passwordEncripted);
+ generalSettingListViewModel.saveGeneralSetting(passwordGeneralSetting);
+ }
+
+ @Override
+ public void onValidationFailed(final ValidationField field) {
+ this.getActivity().runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+ if (field.getView() == etCurrentPin) {
+ tvCurrentPinError.setText(field.getMessage());
+ } else if (field.getView() == etNewPin){
+ tvNewPinError.setText(field.getMessage());
+ } else if (field.getView() == etConfirmPin){
+ tvConfirmPinError.setText(field.getMessage());
+ }
+ }
+ });
+ }
}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/models/GeneralSetting.java b/app/src/main/java/cy/agorise/crystalwallet/models/GeneralSetting.java
index b5b322d..822a10e 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/models/GeneralSetting.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/models/GeneralSetting.java
@@ -17,6 +17,7 @@ public class GeneralSetting {
public final static String SETTING_NAME_PREFERED_COUNTRY = "PREFERED_COUNTRY";
public final static String SETTING_NAME_PREFERED_CURRENCY = "PREFERED_CURRENCY";
+ public final static String SETTING_PASSWORD = "PASSWORD";
/**
* The id on the database
diff --git a/app/src/main/java/cy/agorise/crystalwallet/service/CrystalWalletService.java b/app/src/main/java/cy/agorise/crystalwallet/service/CrystalWalletService.java
index 5cecb10..93b89a5 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/service/CrystalWalletService.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/service/CrystalWalletService.java
@@ -109,8 +109,7 @@ public class CrystalWalletService extends LifecycleService {
if (LoadEquivalencesThread != null) {
LoadEquivalencesThread.stopLoadingEquivalences();
- }
- ;
+ };
LoadEquivalencesThread = new EquivalencesThread(service, generalSetting.getValue(), bitsharesAssets);
LoadEquivalencesThread.start();
}
@@ -184,14 +183,14 @@ public class CrystalWalletService extends LifecycleService {
}
//if (LoadEquivalencesThread == null) {
- // LoadEquivalencesThread = new Thread() {
+ // LoadEquivalencesThread = new EquivalencesThread() {
// @Override
// public void run() {
loadEquivalentsValues();
// }
// };
// LoadEquivalencesThread.start();
- //}
+ // }
// If we get killed, after returning from here, restart
return START_STICKY;
diff --git a/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java b/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java
new file mode 100644
index 0000000..7f52970
--- /dev/null
+++ b/app/src/main/java/cy/agorise/crystalwallet/util/PasswordManager.java
@@ -0,0 +1,22 @@
+package cy.agorise.crystalwallet.util;
+
+/**
+ * Created by Henry Varona on 29/1/2018.
+ */
+
+public class PasswordManager {
+
+ //TODO implement password checking using the encryption implemented in encriptPassword
+ public static boolean checkPassword(String encriptedPassword, String passwordToCheck){
+ if (encriptedPassword.equals(passwordToCheck)){
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ //TODO implement password encryption
+ public static String encriptPassword(String password){
+ return password;
+ }
+}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/PinSecurityValidator.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/PinSecurityValidator.java
new file mode 100644
index 0000000..b99f155
--- /dev/null
+++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/PinSecurityValidator.java
@@ -0,0 +1,23 @@
+package cy.agorise.crystalwallet.viewmodels.validators;
+
+import android.content.Context;
+import android.widget.EditText;
+
+import cy.agorise.crystalwallet.viewmodels.validators.validationfields.BitsharesAccountNameDoesntExistsValidationField;
+import cy.agorise.crystalwallet.viewmodels.validators.validationfields.CurrentPinValidationField;
+import cy.agorise.crystalwallet.viewmodels.validators.validationfields.PinConfirmationValidationField;
+import cy.agorise.crystalwallet.viewmodels.validators.validationfields.PinValidationField;
+
+/**
+ * Created by Henry Varona on 1/28/2018.
+ */
+
+public class PinSecurityValidator extends UIValidator {
+
+ public PinSecurityValidator(Context context, EditText currentPinEdit, EditText newPinEdit, EditText newPinConfirmationEdit){
+ super(context);
+ this.addField(new CurrentPinValidationField(currentPinEdit));
+ this.addField(new PinValidationField(newPinEdit));
+ this.addField(new PinConfirmationValidationField(newPinEdit,newPinConfirmationEdit));
+ }
+}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/CurrentPinValidationField.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/CurrentPinValidationField.java
new file mode 100644
index 0000000..7877184
--- /dev/null
+++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/CurrentPinValidationField.java
@@ -0,0 +1,69 @@
+package cy.agorise.crystalwallet.viewmodels.validators.validationfields;
+
+import android.arch.lifecycle.LifecycleOwner;
+import android.arch.lifecycle.LiveData;
+import android.arch.lifecycle.Observer;
+import android.arch.lifecycle.ViewModelProviders;
+import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.widget.EditText;
+
+import java.util.List;
+
+import cy.agorise.crystalwallet.models.GeneralSetting;
+import cy.agorise.crystalwallet.util.PasswordManager;
+import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
+
+/**
+ * Created by Henry Varona on 1/28/2018.
+ */
+
+public class CurrentPinValidationField extends ValidationField {
+
+ private EditText currentPinField;
+ String currentPassword = "";
+
+ public CurrentPinValidationField(EditText currentPinField){
+ super(currentPinField);
+ this.currentPinField = currentPinField;
+ GeneralSettingListViewModel generalSettingListViewModel = ViewModelProviders.of((FragmentActivity)view.getContext()).get(GeneralSettingListViewModel.class);
+ LiveData> generalSettingsLiveData = generalSettingListViewModel.getGeneralSettingList();
+ generalSettingsLiveData.observe((LifecycleOwner) this.view.getContext(), new Observer>() {
+ @Override
+ public void onChanged(@Nullable List generalSettings) {
+ for (GeneralSetting generalSetting:generalSettings) {
+ if (generalSetting.getName().equals(GeneralSetting.SETTING_PASSWORD)){
+ currentPassword = generalSetting.getValue();
+ break;
+ }
+ }
+ }
+ });
+ }
+
+ public void validate(){
+ final String newValue = currentPinField.getText().toString();
+
+ if (this.currentPassword.equals("")) {
+ this.setLastValue("");
+ this.startValidating();
+ setValidForValue("",true);
+ } else if (!newValue.equals(this.getLastValue())) {
+ this.setLastValue(newValue);
+ this.startValidating();
+ if (newValue.equals("")){
+ setMessageForValue(lastValue, "");
+ setValidForValue(lastValue, false);
+ } else {
+
+ if (PasswordManager.checkPassword(this.currentPassword, newValue)) {
+ setValidForValue(lastValue, true);
+ } else {
+ setMessageForValue(lastValue, "Password is invalid.");
+ setValidForValue(lastValue, false);
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinConfirmationValidationField.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinConfirmationValidationField.java
index 00f951e..77b7043 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinConfirmationValidationField.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinConfirmationValidationField.java
@@ -22,18 +22,24 @@ public class PinConfirmationValidationField extends ValidationField {
public void validate(){
String newConfirmationValue = pinConfirmationField.getText().toString();
String newValue = pinField.getText().toString();
- String mixedValue = newValue+"_"+newConfirmationValue;
- if (mixedValue != this.getLastValue()) {
- this.setLastValue(mixedValue);
- this.startValidating();
+ String mixedValue = newValue + "_" + newConfirmationValue;
-
- if (!newConfirmationValue.equals(newValue)){
- this.setMessageForValue(mixedValue,this.validator.getContext().getResources().getString(R.string.mismatch_pin));
- this.setValidForValue(mixedValue,false);
- } else {
- this.setValidForValue(mixedValue, true);
+ if (!newConfirmationValue.equals("")) {
+ if (!mixedValue.equals(this.getLastValue())) {
+ this.setLastValue(mixedValue);
+ this.startValidating();
+ if (!newConfirmationValue.equals(newValue)) {
+ this.setMessageForValue(mixedValue, this.validator.getContext().getResources().getString(R.string.mismatch_pin));
+ this.setValidForValue(mixedValue, false);
+ } else {
+ this.setValidForValue(mixedValue, true);
+ }
}
+ } else {
+ this.setLastValue("");
+ this.startValidating();
+ this.setMessageForValue("", "");
+ this.setValidForValue("", false);
}
}
}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinValidationField.java b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinValidationField.java
index 809b8c6..6228641 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinValidationField.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/viewmodels/validators/validationfields/PinValidationField.java
@@ -20,16 +20,23 @@ public class PinValidationField extends ValidationField {
public void validate(){
String newValue = pinField.getText().toString();
- if (newValue != this.getLastValue()) {
- this.setLastValue(newValue);
- this.startValidating();
+ if (!newValue.equals("")) {
+ if (!newValue.equals(this.getLastValue())) {
+ this.setLastValue(newValue);
+ this.startValidating();
- if (newValue.length() < 6) {
- this.setMessageForValue(newValue, this.validator.getContext().getResources().getString(R.string.pin_number_warning));
- this.setValidForValue(newValue, false);
- } else {
- this.setValidForValue(newValue, true);
+ if (newValue.length() < 6) {
+ this.setMessageForValue(newValue, this.validator.getContext().getResources().getString(R.string.pin_number_warning));
+ this.setValidForValue(newValue, false);
+ } else {
+ this.setValidForValue(newValue, true);
+ }
}
+ } else {
+ this.setLastValue("");
+ this.startValidating();
+ this.setMessageForValue("", "");
+ this.setValidForValue("", false);
}
}
}
diff --git a/app/src/main/java/cy/agorise/crystalwallet/views/CryptoCoinBalanceViewHolder.java b/app/src/main/java/cy/agorise/crystalwallet/views/CryptoCoinBalanceViewHolder.java
index a17cb05..45e0168 100644
--- a/app/src/main/java/cy/agorise/crystalwallet/views/CryptoCoinBalanceViewHolder.java
+++ b/app/src/main/java/cy/agorise/crystalwallet/views/CryptoCoinBalanceViewHolder.java
@@ -80,30 +80,39 @@ public class CryptoCoinBalanceViewHolder extends RecyclerView.ViewHolder {
public void onChanged(@Nullable GeneralSetting generalSetting) {
if (generalSetting != null) {
//Gets the currency object of the preferred currency
- CryptoCurrency currencyTo = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getByName(generalSetting.getValue());
+ LiveData currencyToLiveData = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getLiveDataByName(generalSetting.getValue());
- //Retrieves the equivalent value of this balance using the "From" currency and the "To" currency
- LiveData currencyEquivalenceLiveData = CrystalDatabase.getAppDatabase(context)
- .cryptoCurrencyEquivalenceDao().getByFromTo(
- currencyTo.getId(),
- currencyFrom.getId()
-
- );
-
- //Observes the equivalent value. If the equivalent value changes, this will keep the value showed correct
- currencyEquivalenceLiveData.observe((LifecycleOwner) context, new Observer() {
+ currencyToLiveData.observe((LifecycleOwner) context, new Observer() {
@Override
- public void onChanged(@Nullable CryptoCurrencyEquivalence cryptoCurrencyEquivalence) {
- if (cryptoCurrencyEquivalence != null) {
- CryptoCurrency toCurrency = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getById(cryptoCurrencyEquivalence.getFromCurrencyId());
- String equivalenceString = String.format(
- "%.2f",
- (balance.getBalance()/Math.pow(10,currencyFrom.getPrecision()))/
- (cryptoCurrencyEquivalence.getValue()/Math.pow(10,toCurrency.getPrecision()))
- );
+ public void onChanged(@Nullable CryptoCurrency cryptoCurrency) {
+ if (cryptoCurrency != null) {
+ CryptoCurrency currencyTo = cryptoCurrency;
- cryptoCoinBalanceEquivalence.setText(
- equivalenceString + " " + toCurrency.getName());
+ //Retrieves the equivalent value of this balance using the "From" currency and the "To" currency
+ LiveData currencyEquivalenceLiveData = CrystalDatabase.getAppDatabase(context)
+ .cryptoCurrencyEquivalenceDao().getByFromTo(
+ currencyTo.getId(),
+ currencyFrom.getId()
+
+ );
+
+ //Observes the equivalent value. If the equivalent value changes, this will keep the value showed correct
+ currencyEquivalenceLiveData.observe((LifecycleOwner) context, new Observer() {
+ @Override
+ public void onChanged(@Nullable CryptoCurrencyEquivalence cryptoCurrencyEquivalence) {
+ if (cryptoCurrencyEquivalence != null) {
+ CryptoCurrency toCurrency = CrystalDatabase.getAppDatabase(context).cryptoCurrencyDao().getById(cryptoCurrencyEquivalence.getFromCurrencyId());
+ String equivalenceString = String.format(
+ "%.2f",
+ (balance.getBalance() / Math.pow(10, currencyFrom.getPrecision())) /
+ (cryptoCurrencyEquivalence.getValue() / Math.pow(10, toCurrency.getPrecision()))
+ );
+
+ cryptoCoinBalanceEquivalence.setText(
+ equivalenceString + " " + toCurrency.getName());
+ }
+ }
+ });
}
}
});
diff --git a/app/src/main/res/layout/activity_pin_request.xml b/app/src/main/res/layout/activity_pin_request.xml
new file mode 100644
index 0000000..58fa56f
--- /dev/null
+++ b/app/src/main/res/layout/activity_pin_request.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_general_settings.xml b/app/src/main/res/layout/fragment_general_settings.xml
index 6364bb0..257d0f2 100644
--- a/app/src/main/res/layout/fragment_general_settings.xml
+++ b/app/src/main/res/layout/fragment_general_settings.xml
@@ -56,9 +56,9 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- app:layout_constraintTop_toBottomOf="@+id/tvTaxableCountry"
+ app:layout_constraintEnd_toEndOf="@id/spBackupAsset"
app:layout_constraintStart_toStartOf="@id/spBackupAsset"
- app:layout_constraintEnd_toEndOf="@id/spBackupAsset"/>
+ app:layout_constraintTop_toBottomOf="@+id/tvTaxableCountry" />
+
+
+ app:layout_constraintTop_toBottomOf="@+id/tvCurrentPinError" />
+
-
+ app:layout_constraintTop_toBottomOf="@+id/tvNewPinError" />
+
\ No newline at end of file