This commit is contained in:
hvarona 2018-10-18 21:22:24 -04:00
commit 6b37db9279
7 changed files with 259 additions and 76 deletions

View file

@ -16,12 +16,19 @@ import android.widget.Toast;
import com.thekhaeng.pushdownanim.PushDownAnim; import com.thekhaeng.pushdownanim.PushDownAnim;
import org.jetbrains.annotations.NotNull;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnTextChanged; import butterknife.OnTextChanged;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.application.CrystalSecurityMonitor;
import cy.agorise.crystalwallet.dialogs.material.CrystalLoading; import cy.agorise.crystalwallet.dialogs.material.CrystalLoading;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.dialogs.material.NegativeResponse;
import cy.agorise.crystalwallet.dialogs.material.PositiveResponse;
import cy.agorise.crystalwallet.dialogs.material.QuestionDialog;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests; import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest; import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
@ -41,6 +48,9 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@BindView(R.id.txtErrorPIN) @BindView(R.id.txtErrorPIN)
TextView txtErrorPIN; TextView txtErrorPIN;
@BindView(R.id.txtErrorAccount)
TextView txtErrorAccount;
//@BindView(R.id.tvPinError) //@BindView(R.id.tvPinError)
//TextView tvPinError; //TextView tvPinError;
@ -186,6 +196,11 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
else{ else{
disableCreate(); disableCreate();
} }
/*
* Hide error field
* */
txtErrorAccount.setVisibility(View.INVISIBLE);
} }
}); });
etAccountName.addTextChangedListener(new TextWatcher() { etAccountName.addTextChangedListener(new TextWatcher() {
@ -272,8 +287,6 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
void afterSeedWordsChanged(Editable editable) { void afterSeedWordsChanged(Editable editable) {
this.importSeedValidator.validate(); this.importSeedValidator.validate();
} }
@OnTextChanged(value = R.id.etAccountName, @OnTextChanged(value = R.id.etAccountName,
callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterAccountNameChanged(Editable editable) { void afterAccountNameChanged(Editable editable) {
@ -291,81 +304,111 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
if (this.importSeedValidator.isValid()) { if (this.importSeedValidator.isValid()) {
/* /*
* Loading dialog * Question if continue
* */ * */
final CrystalLoading crystalLoading = new CrystalLoading(activity); final QuestionDialog questionDialog = new QuestionDialog(activity);
crystalLoading.show(); questionDialog.setText(activity.getString(R.string.question_continue));
questionDialog.setOnNegative(new NegativeResponse() {
final ValidateImportBitsharesAccountRequest validatorRequest =
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override @Override
public void onCarryOut() { public void onNegative(@NotNull DialogMaterial dialogMaterial) {
/*
* Hide the loading dialog
* */
crystalLoading.dismiss();
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
String errorText = "An error ocurred attempting to import the account";
switch (validatorRequest.getStatus()){
case PETITION_FAILED:
case NO_INTERNET:
case NO_SERVER_CONNECTION:
errorText = "There was an error with the connection. Try again later";
break;
case ACCOUNT_DOESNT_EXIST:
errorText = "The account doesn't exists";
break;
case BAD_SEED:
errorText = "The seed is not valid";
break;
case NO_ACCOUNT_DATA:
errorText = "The account doesn't have any data";
break;
}
Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
} }
}); });
/*CryptoNetInfoRequests.getInstance().addRequest(validatorRequest); questionDialog.setOnPositive(new PositiveResponse() {
@Override
public void onPositive() {
AccountSeed seed = new AccountSeed(); /*
* Loading dialog
* */
final CrystalLoading crystalLoading = new CrystalLoading(activity);
crystalLoading.show();
//TODO verify if words are already in the db /*
//TODO check if name has been asigned to other seed * Validate mnemonic with the server
seed.setMasterSeed(etSeedWords.getText().toString()); * */
seed.setName(etAccountName.getText().toString()); final ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString().trim(),etSeedWords.getText().toString().trim(),activity);
seed.setType(SeedType.BRAINKEY); request.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
if(request.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
accountSeedViewModel.addSeed(seed); //Correct
CryptoNetAccountViewModel cryptoNetAccountViewModel = ViewModelProviders.of(this).get(CryptoNetAccountViewModel.class); /*
GrapheneAccountInfoViewModel grapheneAccountInfoViewModel = ViewModelProviders.of(this).get(GrapheneAccountInfoViewModel.class); * Final service connection
CryptoNetAccount cryptoNetAccount = new CryptoNetAccount(); * */
cryptoNetAccount.setSeedId(seed.getId()); finalStep(crystalLoading);
cryptoNetAccount.setAccountIndex(0);
cryptoNetAccount.setCryptoNet(cy.agorise.crystalwallet.enums.CryptoNet.BITSHARES);
cryptoNetAccountViewModel.addCryptoNetAccount(cryptoNetAccount);
GrapheneAccountInfo grapheneAccountInfo = new GrapheneAccountInfo(cryptoNetAccount.getId());
grapheneAccountInfo.setName(etAccountName.getText().toString());
grapheneAccountInfoViewModel.addGrapheneAccountInfo(grapheneAccountInfo);
this.finish();*/ }
CryptoNetInfoRequests.getInstance().addRequest(validatorRequest); else{
crystalLoading.dismiss();
txtErrorAccount.setVisibility(View.VISIBLE);
txtErrorAccount.setText(activity.getResources().getString(R.string.error_invalid_account));
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(request);
}
});
questionDialog.show();
} }
} }
private void finalStep(final CrystalLoading crystalLoading){
final ImportSeedActivity thisActivity = this;
final ValidateImportBitsharesAccountRequest validatorRequest =
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
/*
* Hide the loading dialog
* */
crystalLoading.dismiss();
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
String errorText = "An error ocurred attempting to import the account";
switch (validatorRequest.getStatus()){
case PETITION_FAILED:
case NO_INTERNET:
case NO_SERVER_CONNECTION:
errorText = "There was an error with the connection. Try again later";
break;
case ACCOUNT_DOESNT_EXIST:
errorText = "The account doesn't exists";
break;
case BAD_SEED:
errorText = "The seed is not valid";
break;
case NO_ACCOUNT_DATA:
errorText = "The account doesn't have any data";
break;
}
Toast.makeText(thisActivity.getApplicationContext(),errorText,Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(thisActivity, BoardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
});
CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
}
@Override @Override
public void onValidationSucceeded(final ValidationField field) { public void onValidationSucceeded(final ValidationField field) {
final ImportSeedActivity activity = this; final ImportSeedActivity activity = this;

View file

@ -1,18 +1,24 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.app.Activity;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.text.Editable; import android.text.Editable;
import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import com.andrognito.patternlockview.PatternLockView; import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener; import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List; import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -24,8 +30,15 @@ import cy.agorise.crystalwallet.util.PasswordManager;
import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel; import cy.agorise.crystalwallet.viewmodels.GeneralSettingListViewModel;
public class PatternRequestActivity extends AppCompatActivity { public class PatternRequestActivity extends AppCompatActivity {
private String patternEncrypted; private String patternEncrypted;
@BindView(R.id.tvPatternText)
TextView tvPatternText;
@Override @Override
public void onBackPressed() { public void onBackPressed() {
//Do nothing to prevent the user to use the back button //Do nothing to prevent the user to use the back button
@ -34,6 +47,7 @@ public class PatternRequestActivity extends AppCompatActivity {
@BindView(R.id.patternLockView) @BindView(R.id.patternLockView)
PatternLockView patternLockView; PatternLockView patternLockView;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -77,8 +91,7 @@ public class PatternRequestActivity extends AppCompatActivity {
thisActivity.finish(); thisActivity.finish();
} }
} else { } else {
patternLockView.clearPattern(); incorrect();
patternLockView.requestFocus();
} }
} }
@ -96,6 +109,41 @@ public class PatternRequestActivity extends AppCompatActivity {
}); });
} }
private void incorrect(){
/*
* Show error
* */
final Activity activity = this;
tvPatternText.setText(activity.getResources().getString(R.string.Incorrect_pattern));
tvPatternText.setTextColor(Color.RED);
tvPatternText.setVisibility(View.VISIBLE);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
t.cancel();
tvPatternText.setVisibility(View.INVISIBLE);
patternLockView.clearPattern();
patternLockView.requestFocus();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
}
public String patternToString(List<PatternLockView.Dot> pattern){ public String patternToString(List<PatternLockView.Dot> pattern){
String patternString = ""; String patternString = "";
for (PatternLockView.Dot nextDot : pattern){ for (PatternLockView.Dot nextDot : pattern){

View file

@ -3,6 +3,7 @@ package cy.agorise.crystalwallet.fragments;
import android.arch.lifecycle.LiveData; import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer; import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
@ -18,6 +19,8 @@ import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener; import com.andrognito.patternlockview.listener.PatternLockViewListener;
import java.util.List; import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
@ -87,7 +90,8 @@ public class PatternSecurityFragment extends Fragment {
public void showNewPatternUI(){ public void showNewPatternUI(){
removePatternListener(); removePatternListener();
patternLockView.clearPattern(); patternLockView.clearPattern();
tvPatternText.setText("Enter new pattern"); tvPatternText.setTextColor(Color.WHITE);
tvPatternText.setText(getActivity().getResources().getString(R.string.Enter_new_pattern));
actualPatternListener = new PatternLockViewListener() { actualPatternListener = new PatternLockViewListener() {
@Override @Override
@ -118,7 +122,7 @@ public class PatternSecurityFragment extends Fragment {
removePatternListener(); removePatternListener();
patternLockView.clearPattern(); patternLockView.clearPattern();
patternLockView.requestFocus(); patternLockView.requestFocus();
tvPatternText.setText("Confirm new pattern"); tvPatternText.setText(getActivity().getResources().getString(R.string.Confirm_new_pattern));
actualPatternListener = new PatternLockViewListener() { actualPatternListener = new PatternLockViewListener() {
@Override @Override
@ -135,7 +139,9 @@ public class PatternSecurityFragment extends Fragment {
public void onComplete(List<PatternLockView.Dot> pattern) { public void onComplete(List<PatternLockView.Dot> pattern) {
if (patternEntered.equals(patternToString(pattern))){ if (patternEntered.equals(patternToString(pattern))){
savePattern(patternEntered); savePattern(patternEntered);
showNewPatternUI(); }
else{
resetPattern();
} }
} }
@ -147,9 +153,66 @@ public class PatternSecurityFragment extends Fragment {
patternLockView.addPatternLockListener(actualPatternListener); patternLockView.addPatternLockListener(actualPatternListener);
} }
private void resetPattern(){
/*
* Show error
* */
tvPatternText.setText(getActivity().getResources().getString(R.string.Incorrect_pattern));
tvPatternText.setTextColor(Color.RED);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
t.cancel();
showNewPatternUI();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
}
public void savePattern(String pattern){ public void savePattern(String pattern){
String patternEncripted = PasswordManager.encriptPassword(pattern); String patternEncripted = PasswordManager.encriptPassword(pattern);
CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted); CrystalSecurityMonitor.getInstance(null).setPatternEncrypted(patternEncripted);
CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity()); //CrystalSecurityMonitor.getInstance(null).callPasswordRequest(this.getActivity());
/*
* Show success
* */
tvPatternText.setText(getActivity().getResources().getString(R.string.Pattern_set_correctly));
tvPatternText.setTextColor(Color.GREEN);
final Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
t.cancel();
showNewPatternUI();
}
});
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
1000,
//Set the amount of time between each execution (in milliseconds)
1000);
} }
} }

View file

@ -18,7 +18,7 @@ public class ImportSeedValidator extends UIValidator {
super(context); super(context);
this.addField(new PinValidationField(pinEdit)); this.addField(new PinValidationField(pinEdit));
this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit)); this.addField(new PinConfirmationValidationField(pinEdit,pinConfirmationEdit));
this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit)); //this.addField(new BitsharesAccountNameValidationField(bitsharesAccountNameEdit));
this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit)); //this.addField(new BitsharesAccountMnemonicValidationField(mnemonicEdit,bitsharesAccountNameEdit));
} }
} }

View file

@ -5,6 +5,15 @@
android:orientation="vertical" android:orientation="vertical"
android:background="@drawable/gradient"> android:background="@drawable/gradient">
<TextView
android:id="@+id/tvPatternText"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:visibility="invisible"
android:layout_marginTop="25dp"/>
<com.andrognito.patternlockview.PatternLockView <com.andrognito.patternlockview.PatternLockView
android:id="@+id/patternLockView" android:id="@+id/patternLockView"
android:layout_width="280dp" android:layout_width="280dp"

View file

@ -72,7 +72,7 @@
<cy.agorise.crystalwallet.views.natives.CustomTextInputEditText <cy.agorise.crystalwallet.views.natives.CustomTextInputEditText
android:id="@+id/etSeedWords" android:id="@+id/etSeedWords"
android:layout_width="330dp" android:layout_width="330dp"
android:layout_height="120dp" android:layout_height="100dp"
android:hint="@string/Seed" android:hint="@string/Seed"
android:maxLength="255" android:maxLength="255"
android:inputType="textMultiLine" /> android:inputType="textMultiLine" />
@ -99,15 +99,27 @@
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/txtErrorAccount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tilAccountName"
android:textColor="@color/red"
android:textSize="14sp"
android:text="@string/error_invalid_account"
android:layout_marginLeft="30dp"
android:visibility="invisible"
android:layout_marginTop="5dp"/>
<LinearLayout <LinearLayout
android:id="@+id/linearlayoutButtons" android:id="@+id/linearlayoutButtons"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_below="@+id/tilAccountName" android:layout_below="@+id/txtErrorAccount"
android:orientation="horizontal" android:orientation="horizontal"
android:layout_marginTop="40dp"> android:layout_marginTop="10dp">
<Button <Button
android:id="@+id/btnCancel" android:id="@+id/btnCancel"

View file

@ -74,6 +74,14 @@
<string name="pin_number_warning">The pin number must be at least 6 digits</string> <string name="pin_number_warning">The pin number must be at least 6 digits</string>
<string name="old_pin_number_warning">The old pin number must be at least 6 digits</string> <string name="old_pin_number_warning">The old pin number must be at least 6 digits</string>
<string name="mismatch_pin">mismatch pin</string> <string name="mismatch_pin">mismatch pin</string>
<string name="Enter_new_pattern">Enter new pattern</string>
<string name="Incorrect_pattern">Incorrect pattern</string>
<string name="Pattern_set_correctly">Pattern set correctly</string>
<string name="Confirm_new_pattern">Confirm new pattern</string>
<string name="error_invalid_account">Invalid account, please check your brain key for typing errors</string> <string name="error_invalid_account">Invalid account, please check your brain key for typing errors</string>
<string name="key_brainkey" translatable="false">menace saa tenible carless koftgar snarly stoned gear abater outbow defile stowage unsappy scrout cowskin wramp</string> <string name="key_brainkey" translatable="false">menace saa tenible carless koftgar snarly stoned gear abater outbow defile stowage unsappy scrout cowskin wramp</string>
<string name="txt_pin" translatable="false">pin</string> <string name="txt_pin" translatable="false">pin</string>