master
Henry Varona 2018-09-15 12:06:45 -04:00
commit edd23d7ff3
34 changed files with 1102 additions and 593 deletions

View File

@ -18,8 +18,7 @@
android:configChanges="locale" android:configChanges="locale"
android:theme="@style/AppTheme"> android:theme="@style/AppTheme">
<activity <activity
android:name=".activities.LicenseActivity" android:name=".activities.LicenseActivity">
android:theme="@style/AppTheme.NoActionBar">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@ -31,7 +30,7 @@
android:theme="@style/AppTheme.NoActionBar"> android:theme="@style/AppTheme.NoActionBar">
</activity> </activity>
<activity android:name=".activities.BoardActivity" <activity android:name=".activities.BoardActivity"
android:theme="@style/AppTheme.NoActionBar" > android:theme="@style/AppTheme.NoActionBar">
</activity> </activity>
<activity android:name=".activities.CreateSeedActivity" > <activity android:name=".activities.CreateSeedActivity" >
</activity> </activity>

View File

@ -18,6 +18,7 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.fragments.BackupsSettingsFragment;
import cy.agorise.crystalwallet.models.AccountSeed; import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel; import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
@ -28,7 +29,7 @@ public class BackupSeedActivity extends AppCompatActivity {
@BindView(R.id.tvBrainKey) @BindView(R.id.tvBrainKey)
TextView textfieldBrainkey; TextView textfieldBrainkey;
@BindView(R.id.btnOk) @BindView(R.id.btnCancel)
Button btnOk; Button btnOk;
@BindView(R.id.btnCopy) @BindView(R.id.btnCopy)
Button btnCopy; Button btnCopy;
@ -60,14 +61,14 @@ public class BackupSeedActivity extends AppCompatActivity {
accountSeedViewModel.loadSeed(seedId); accountSeedViewModel.loadSeed(seedId);
} else { } else {
finish(); finish();
} }
} }
@OnClick(R.id.btnOk) @OnClick(R.id.btnCancel)
public void btnOkClick(){ public void btnOkClick(){
Intent intent = new Intent(this, IntroActivity.class); finish();
startActivity(intent);
} }
/* /*

View File

@ -13,6 +13,7 @@ import cy.agorise.crystalwallet.R
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog import cy.agorise.crystalwallet.dialogs.material.CrystalDialog
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest import cy.agorise.crystalwallet.requestmanagers.ValidateCreateBitsharesAccountRequest
import cy.agorise.crystalwallet.requestmanagers.ValidateExistBitsharesAccountRequest
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener import cy.agorise.crystalwallet.viewmodels.validators.customImpl.interfaces.UIValidatorListener
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation
import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist import cy.agorise.crystalwallet.viewmodels.validators.customImpl.validationFields.BitsharesAccountNameValidation.OnAccountExist
@ -62,16 +63,12 @@ class CreateSeedActivity : CustomActivity() {
runOnUiThread { runOnUiThread {
val customTextInputEditText = customValidationField.currentView as CustomTextInputEditText val customTextInputEditText = customValidationField.currentView as CustomTextInputEditText
customTextInputEditText.error = null customTextInputEditText.error = null
customTextInputEditText.fieldValidatorModel.setValid()
} }
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} }
/*
* Validate if can continue
* */
validateFieldsToContinue()
} }
override fun onValidationFailed(customValidationField: CustomValidationField) { override fun onValidationFailed(customValidationField: CustomValidationField) {
@ -82,6 +79,7 @@ class CreateSeedActivity : CustomActivity() {
runOnUiThread { runOnUiThread {
val customTextInputEditText = customValidationField.currentView as CustomTextInputEditText val customTextInputEditText = customValidationField.currentView as CustomTextInputEditText
customTextInputEditText.error = customTextInputEditText.fieldValidatorModel.message customTextInputEditText.error = customTextInputEditText.fieldValidatorModel.message
customTextInputEditText.fieldValidatorModel.setInvalid()
} }
} }
} }
@ -131,6 +129,8 @@ class CreateSeedActivity : CustomActivity() {
* Validate continue to create account * Validate continue to create account
* */ * */
validateFieldsToContinue() validateFieldsToContinue()
} }
@OnTextChanged(value = R.id.tietPinConfirmation, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) @OnTextChanged(value = R.id.tietPinConfirmation, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
@ -148,9 +148,9 @@ class CreateSeedActivity : CustomActivity() {
this.fieldsValidator.validate() this.fieldsValidator.validate()
/* /*
* Always disable till the server response comes * Validate continue to create account
* */ * */
disableCreate() validateFieldsToContinue()
} }
@OnClick(R.id.btnCancel) @OnClick(R.id.btnCancel)
@ -221,8 +221,59 @@ class CreateSeedActivity : CustomActivity() {
* If the result is true so the user can continue to the creation of the account * If the result is true so the user can continue to the creation of the account
* */ * */
if (result) { if (result) {
enableCreate()
/*
* Show the dialog for connection with the server
* */
val creatingAccountMaterialDialog = CrystalDialog(globalActivity)
creatingAccountMaterialDialog.setText(globalActivity.resources.getString(R.string.window_create_seed_Server_validation))
creatingAccountMaterialDialog.progress()
creatingAccountMaterialDialog.show()
/*
* Validate the account does not exists
* */
val request = ValidateExistBitsharesAccountRequest(tietAccountName?.text.toString())
request.setListener {
/*
* Dismiss the dialog of loading
* */
creatingAccountMaterialDialog.dismiss()
if (request.accountExists) {
/*
* The account exists and is not valid
* */
tietAccountName.fieldValidatorModel.setInvalid()
tietAccountName.fieldValidatorModel.message = tietAccountName.resources.getString(R.string.account_name_already_exist)
/*
* Disaible button create
* */
disableCreate()
} else {
/*
* Passed all validations
* */
tietAccountName.fieldValidatorModel.setValid()
/*
* Enable button create
* */
enableCreate()
}
}
CryptoNetInfoRequests.getInstance().addRequest(request)
} else { } else {
/*
* Disaible button create
* */
disableCreate() disableCreate()
} }
} }

View File

@ -1,22 +1,31 @@
package cy.agorise.crystalwallet.activities; package cy.agorise.crystalwallet.activities;
import android.arch.lifecycle.ViewModelProviders; import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.text.Editable; import android.text.Editable;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
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.enums.CryptoNet;
import cy.agorise.crystalwallet.enums.SeedType; import cy.agorise.crystalwallet.enums.SeedType;
import cy.agorise.crystalwallet.manager.BitsharesAccountManager;
import cy.agorise.crystalwallet.models.AccountSeed; import cy.agorise.crystalwallet.models.AccountSeed;
import cy.agorise.crystalwallet.models.CryptoNetAccount; import cy.agorise.crystalwallet.models.CryptoNetAccount;
import cy.agorise.crystalwallet.models.GrapheneAccount;
import cy.agorise.crystalwallet.models.GrapheneAccountInfo; import cy.agorise.crystalwallet.models.GrapheneAccountInfo;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequestListener;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests;
import cy.agorise.crystalwallet.requestmanagers.ImportBackupRequest;
import cy.agorise.crystalwallet.requestmanagers.ValidateImportBitsharesAccountRequest;
import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel; import cy.agorise.crystalwallet.viewmodels.AccountSeedViewModel;
import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel; import cy.agorise.crystalwallet.viewmodels.CryptoNetAccountViewModel;
import cy.agorise.crystalwallet.viewmodels.GrapheneAccountInfoViewModel; import cy.agorise.crystalwallet.viewmodels.GrapheneAccountInfoViewModel;
@ -100,7 +109,46 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
@OnClick(R.id.btnImport) @OnClick(R.id.btnImport)
public void importSeed(){ public void importSeed(){
final ImportSeedActivity thisActivity = this;
if (this.importSeedValidator.isValid()) { if (this.importSeedValidator.isValid()) {
final ValidateImportBitsharesAccountRequest validatorRequest =
new ValidateImportBitsharesAccountRequest(etAccountName.getText().toString(), etSeedWords.getText().toString(), getApplicationContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override
public void onCarryOut() {
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);
AccountSeed seed = new AccountSeed(); AccountSeed seed = new AccountSeed();
//TODO verify if words are already in the db //TODO verify if words are already in the db
@ -122,7 +170,8 @@ public class ImportSeedActivity extends AppCompatActivity implements UIValidator
grapheneAccountInfo.setName(etAccountName.getText().toString()); grapheneAccountInfo.setName(etAccountName.getText().toString());
grapheneAccountInfoViewModel.addGrapheneAccountInfo(grapheneAccountInfo); grapheneAccountInfoViewModel.addGrapheneAccountInfo(grapheneAccountInfo);
this.finish(); this.finish();*/
CryptoNetInfoRequests.getInstance().addRequest(validatorRequest);
} }
} }

View File

@ -158,5 +158,6 @@ public class IntroActivity extends CustomActivity {
// Create and show the dialog. // Create and show the dialog.
ImportAccountOptionsFragment newFragment = ImportAccountOptionsFragment.newInstance(); ImportAccountOptionsFragment newFragment = ImportAccountOptionsFragment.newInstance();
newFragment.show(ft, "importAccountOptions"); newFragment.show(ft, "importAccountOptions");
newFragment.setIntroActivity(globalActivity); //This activity should close when import succeds
} }
} }

View File

@ -8,6 +8,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
import cy.agorise.crystalwallet.dao.BitsharesAssetDao; import cy.agorise.crystalwallet.dao.BitsharesAssetDao;
import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao; import cy.agorise.crystalwallet.dao.CryptoCoinBalanceDao;
import cy.agorise.crystalwallet.dao.CryptoCurrencyDao; import cy.agorise.crystalwallet.dao.CryptoCurrencyDao;
@ -78,17 +79,15 @@ public abstract class GrapheneApiGenerator {
/** /**
* This is used for manager each listener in the subscription thread * This is used for manager each listener in the subscription thread
*/ */
private static HashMap<Long, SubscriptionListener> currentBitsharesListener = new HashMap<>(); private static HashMap<Long,SubscriptionListener> currentBitsharesListener = new HashMap<>();
/** /**
* Retrieves the data of an account searching by it's id * Retrieves the data of an account searching by it's id
* *
* @param accountId The accountId to retrieve * @param accountId The accountId to retrieve
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountById(String accountId, final ApiRequest request) { public static void getAccountById(String accountId, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId, WebSocketThread thread = new WebSocketThread(new GetAccounts(accountId,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
@ -97,7 +96,7 @@ public abstract class GrapheneApiGenerator {
List list = (List) response.result; List list = (List) response.result;
if (list.size() > 0) { if (list.size() > 0) {
if (list.get(0).getClass() == AccountProperties.class) { if (list.get(0).getClass() == AccountProperties.class) {
request.getListener().success(list.get(0), request.getId()); request.getListener().success(list.get(0),request.getId());
return; return;
} }
} }
@ -109,7 +108,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -119,20 +118,17 @@ public abstract class GrapheneApiGenerator {
* @param address The address to retrieve * @param address The address to retrieve
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountByOwnerOrActiveAddress(Address address, final ApiRequest request) { public static void getAccountByOwnerOrActiveAddress(Address address, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true, WebSocketThread thread = new WebSocketThread(new GetKeyReferences(address, true,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result; final List<List<UserAccount>> resp = (List<List<UserAccount>>) response.result;
if (resp.size() > 0) { if(resp.size() > 0){
List<UserAccount> accounts = resp.get(0); List<UserAccount> accounts = resp.get(0);
if (accounts.size() > 0) { if(accounts.size() > 0){
for (UserAccount account : accounts) { for(UserAccount account : accounts) {
request.getListener().success(account, request.getId()); request.getListener().success(account,request.getId());}}}
}
}
}
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
@ -140,7 +136,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -149,25 +145,25 @@ public abstract class GrapheneApiGenerator {
* Gets the Transaction for an Account * Gets the Transaction for an Account
* *
* @param accountGrapheneId The account id to search * @param accountGrapheneId The account id to search
* @param start The start index of the transaction list * @param start The start index of the transaction list
* @param stop The stop index of the transaction list * @param stop The stop index of the transaction list
* @param limit the maximun transactions to retrieve * @param limit the maximun transactions to retrieve
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountTransaction(String accountGrapheneId, int start, int stop, public static void getAccountTransaction(String accountGrapheneId, int start, int stop,
int limit, final ApiRequest request) { int limit, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId), WebSocketThread thread = new WebSocketThread(new GetRelativeAccountHistory(new UserAccount(accountGrapheneId),
start, limit, stop, new WitnessResponseListener() { start, limit, stop, new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
request.getListener().success(response.result, request.getId()); request.getListener().success(response.result,request.getId());
} }
@Override @Override
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -175,18 +171,18 @@ public abstract class GrapheneApiGenerator {
* Retrieves the account id by the name of the account * Retrieves the account id by the name of the account
* *
* @param accountName The account Name to find * @param accountName The account Name to find
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountByName(String accountName, final ApiRequest request) { public static void getAccountByName(String accountName, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName, WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
AccountProperties accountProperties = (AccountProperties) response.result; AccountProperties accountProperties = (AccountProperties)response.result;
if (accountProperties == null) { if(accountProperties == null){
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} else { }else{
request.getListener().success(accountProperties, request.getId()); request.getListener().success(accountProperties,request.getId());
} }
} }
@ -194,7 +190,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -202,18 +198,18 @@ public abstract class GrapheneApiGenerator {
* Retrieves the account id by the name of the account * Retrieves the account id by the name of the account
* *
* @param accountName The account Name to find * @param accountName The account Name to find
* @param request The Api request object, to answer this petition * @param request The Api request object, to answer this petition
*/ */
public static void getAccountIdByName(String accountName, final ApiRequest request) { public static void getAccountIdByName(String accountName, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName, WebSocketThread thread = new WebSocketThread(new GetAccountByName(accountName,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
AccountProperties accountProperties = (AccountProperties) response.result; AccountProperties accountProperties = (AccountProperties)response.result;
if (accountProperties == null) { if(accountProperties == null){
request.getListener().success(null, request.getId()); request.getListener().success(null,request.getId());
} else { }else{
request.getListener().success(accountProperties.id, request.getId()); request.getListener().success(accountProperties.id,request.getId());
} }
} }
@ -221,7 +217,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -229,23 +225,23 @@ public abstract class GrapheneApiGenerator {
* Broadcast a transaction, this is use for sending funds * Broadcast a transaction, this is use for sending funds
* *
* @param transaction The graphene transaction * @param transaction The graphene transaction
* @param feeAsset The feeAseet, this needs only the id of the asset * @param feeAsset The feeAseet, this needs only the id of the asset
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void broadcastTransaction(Transaction transaction, Asset feeAsset, public static void broadcastTransaction(Transaction transaction, Asset feeAsset,
final ApiRequest request) { final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new TransactionBroadcastSequence(transaction, WebSocketThread thread = new WebSocketThread(new TransactionBroadcastSequence(transaction,
feeAsset, new WitnessResponseListener() { feeAsset, new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
request.getListener().success(true, request.getId()); request.getListener().success(true,request.getId());
} }
@Override @Override
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -253,20 +249,20 @@ public abstract class GrapheneApiGenerator {
* This gets the asset information using only the asset name * This gets the asset information using only the asset name
* *
* @param assetNames The list of the names of the assets to be retrieve * @param assetNames The list of the names of the assets to be retrieve
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getAssetByName(ArrayList<String> assetNames, final ApiRequest request) { public static void getAssetByName(ArrayList<String> assetNames, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames, true, WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assetNames,true,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
List<Asset> assets = (List<Asset>) response.result; List<Asset> assets = (List<Asset>) response.result;
if (assets.size() <= 0) { if(assets.size() <= 0){
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} else { }else{
ArrayList<BitsharesAsset> responseAssets = new ArrayList<>(); ArrayList<BitsharesAsset> responseAssets = new ArrayList<>();
for (Asset asset : assets) { for(Asset asset: assets){
//TODO asset type //TODO asset type
BitsharesAsset.Type assetType = BitsharesAsset.Type.UIA; BitsharesAsset.Type assetType = BitsharesAsset.Type.UIA;
/*if(asset.getAssetType().equals(Asset.AssetType.CORE_ASSET)){ /*if(asset.getAssetType().equals(Asset.AssetType.CORE_ASSET)){
@ -279,10 +275,10 @@ public abstract class GrapheneApiGenerator {
assetType = BitsharesAsset.Type.PREDICTION_MARKET; assetType = BitsharesAsset.Type.PREDICTION_MARKET;
}*/ }*/
BitsharesAsset responseAsset = new BitsharesAsset(asset.getSymbol(), BitsharesAsset responseAsset = new BitsharesAsset(asset.getSymbol(),
asset.getPrecision(), asset.getObjectId(), assetType); asset.getPrecision(),asset.getObjectId(),assetType);
responseAssets.add(responseAsset); responseAssets.add(responseAsset);
} }
request.getListener().success(responseAssets, request.getId()); request.getListener().success(responseAssets,request.getId());
} }
} }
@ -290,32 +286,31 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
/** /**
* Gets the asset ifnormation using the id of the net * Gets the asset ifnormation using the id of the net
*
* @param assetIds The list of the ids to retrieve * @param assetIds The list of the ids to retrieve
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getAssetById(ArrayList<String> assetIds, final ApiRequest request) { public static void getAssetById(ArrayList<String> assetIds, final ApiRequest request){
ArrayList<Asset> assets = new ArrayList<>(); ArrayList<Asset> assets = new ArrayList<>();
for (String assetId : assetIds) { for(String assetId : assetIds){
Asset asset = new Asset(assetId); Asset asset = new Asset(assetId);
assets.add(asset); assets.add(asset);
} }
WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assets, true, new WitnessResponseListener() { WebSocketThread thread = new WebSocketThread(new LookupAssetSymbols(assets,true, new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
List<Asset> assets = (List<Asset>) response.result; List<Asset> assets = (List<Asset>) response.result;
if (assets.size() <= 0) { if(assets.size() <= 0){
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} else { }else{
ArrayList<BitsharesAsset> responseAssets = new ArrayList<>(); ArrayList<BitsharesAsset> responseAssets = new ArrayList<>();
for (Asset asset : assets) { for(Asset asset: assets){
//TODO asset type //TODO asset type
BitsharesAsset.Type assetType = BitsharesAsset.Type.UIA; BitsharesAsset.Type assetType = BitsharesAsset.Type.UIA;
/*if(asset.getAssetType().equals(Asset.AssetType.CORE_ASSET)){ /*if(asset.getAssetType().equals(Asset.AssetType.CORE_ASSET)){
@ -328,10 +323,10 @@ public abstract class GrapheneApiGenerator {
assetType = BitsharesAsset.Type.PREDICTION_MARKET; assetType = BitsharesAsset.Type.PREDICTION_MARKET;
}*/ }*/
BitsharesAsset responseAsset = new BitsharesAsset(asset.getSymbol(), BitsharesAsset responseAsset = new BitsharesAsset(asset.getSymbol(),
asset.getPrecision(), asset.getObjectId(), assetType); asset.getPrecision(),asset.getObjectId(),assetType);
responseAssets.add(responseAsset); responseAssets.add(responseAsset);
} }
request.getListener().success(responseAssets, request.getId()); request.getListener().success(responseAssets,request.getId());
} }
} }
@ -339,20 +334,20 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
/** /**
* Subscribe a bitshares account to receive real time updates * Subscribe a bitshares account to receive real time updates
* *
* @param accountId The id opf the database of the account * @param accountId The id opf the database of the account
* @param accountBitsharesId The bitshares id of the account * @param accountBitsharesId The bitshares id of the account
* @param context The android context of this application * @param context The android context of this application
*/ */
public static void subscribeBitsharesAccount(final long accountId, final String accountBitsharesId, public static void subscribeBitsharesAccount(final long accountId, final String accountBitsharesId,
final Context context) { final Context context){
if (!currentBitsharesListener.containsKey(accountId)) { if(!currentBitsharesListener.containsKey(accountId)){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao(); final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao(); final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
@ -365,15 +360,15 @@ public abstract class GrapheneApiGenerator {
@Override @Override
public void onSubscriptionUpdate(SubscriptionResponse response) { public void onSubscriptionUpdate(SubscriptionResponse response) {
List<Serializable> updatedObjects = (List<Serializable>) response.params.get(1); List<Serializable> updatedObjects = (List<Serializable>) response.params.get(1);
if (updatedObjects.size() > 0) { if(updatedObjects.size() > 0){
for (Serializable update : updatedObjects) { for(Serializable update : updatedObjects){
if (update instanceof BroadcastedTransaction) { if(update instanceof BroadcastedTransaction){
BroadcastedTransaction transactionUpdate = (BroadcastedTransaction) update; BroadcastedTransaction transactionUpdate = (BroadcastedTransaction) update;
for (BaseOperation operation : transactionUpdate.getTransaction().getOperations()) { for(BaseOperation operation : transactionUpdate.getTransaction().getOperations()){
if (operation instanceof TransferOperation) { if(operation instanceof TransferOperation){
final TransferOperation tOperation = (TransferOperation) operation; final TransferOperation tOperation = (TransferOperation) operation;
if (tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)) { if(tOperation.getFrom().getObjectId().equals(accountBitsharesId) || tOperation.getTo().getObjectId().equals(accountBitsharesId)){
GrapheneApiGenerator.getAccountBalance(accountId, accountBitsharesId, context); GrapheneApiGenerator.getAccountBalance(accountId,accountBitsharesId,context);
final CryptoCoinTransaction transaction = new CryptoCoinTransaction(); final CryptoCoinTransaction transaction = new CryptoCoinTransaction();
transaction.setAccountId(accountId); transaction.setAccountId(accountId);
transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue()); transaction.setAmount(tOperation.getAssetAmount().getAmount().longValue());
@ -384,13 +379,13 @@ public abstract class GrapheneApiGenerator {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
ArrayList<BitsharesAsset> assets = (ArrayList<BitsharesAsset>) answer; ArrayList<BitsharesAsset> assets = (ArrayList<BitsharesAsset>) answer;
for (BitsharesAsset asset : assets) { for(BitsharesAsset asset : assets){
long idCryptoCurrency = cryptoCurrencyDao.insertCryptoCurrency(asset)[0]; long idCryptoCurrency = cryptoCurrencyDao.insertCryptoCurrency(asset)[0];
BitsharesAssetInfo info = new BitsharesAssetInfo(asset); BitsharesAssetInfo info = new BitsharesAssetInfo(asset);
info.setCryptoCurrencyId(idCryptoCurrency); info.setCryptoCurrencyId(idCryptoCurrency);
asset.setId((int) idCryptoCurrency); asset.setId((int)idCryptoCurrency);
bitsharesAssetDao.insertBitsharesAssetInfo(info); bitsharesAssetDao.insertBitsharesAssetInfo(info);
saveTransaction(transaction, cryptoCurrencyDao.getById(info.getCryptoCurrencyId()), accountBitsharesId, tOperation, context); saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context);
} }
} }
@ -401,9 +396,9 @@ public abstract class GrapheneApiGenerator {
}); });
ArrayList<String> assets = new ArrayList<>(); ArrayList<String> assets = new ArrayList<>();
assets.add(tOperation.getAssetAmount().getAsset().getObjectId()); assets.add(tOperation.getAssetAmount().getAsset().getObjectId());
GrapheneApiGenerator.getAssetById(assets, assetRequest); GrapheneApiGenerator.getAssetById(assets,assetRequest);
} else { }else{
saveTransaction(transaction, cryptoCurrencyDao.getById(info.getCryptoCurrencyId()), accountBitsharesId, tOperation, context); saveTransaction(transaction,cryptoCurrencyDao.getById(info.getCryptoCurrencyId()),accountBitsharesId,tOperation,context);
} }
} }
} }
@ -415,62 +410,56 @@ public abstract class GrapheneApiGenerator {
} }
}; };
currentBitsharesListener.put(accountId, balanceListener); currentBitsharesListener.put(accountId,balanceListener);
bitsharesSubscriptionHub.addSubscriptionListener(balanceListener); bitsharesSubscriptionHub.addSubscriptionListener(balanceListener);
try {
if (!subscriptionThread.isConnected() && !subscriptionThread.isAlive()) {
subscriptionThread.start(); if(!subscriptionThread.isConnected()){
subscriptionThread.start();
} else if (bitsharesSubscriptionHub != null && !bitsharesSubscriptionHub.isSubscribed()) { }else if(!bitsharesSubscriptionHub.isSubscribed()){
bitsharesSubscriptionHub.resubscribe(); bitsharesSubscriptionHub.resubscribe();
}
} catch (Exception e) {
e.printStackTrace();
} }
} }
} }
/** /**
* Function to save a transaction retrieved from the update * Function to save a transaction retrieved from the update
* * @param transaction The transaction db object
* @param transaction The transaction db object * @param currency The currency of the transaccion
* @param currency The currency of the transaccion
* @param accountBitsharesId The id of the account in the bitshares network * @param accountBitsharesId The id of the account in the bitshares network
* @param tOperation The transfer operation fetched from the update * @param tOperation The transfer operation fetched from the update
* @param context The context of this app * @param context The context of this app
*/ */
private static void saveTransaction(CryptoCoinTransaction transaction, CryptoCurrency currency, private static void saveTransaction(CryptoCoinTransaction transaction, CryptoCurrency currency,
String accountBitsharesId, TransferOperation tOperation, String accountBitsharesId, TransferOperation tOperation ,
Context context) { Context context){
transaction.setIdCurrency((int) currency.getId()); transaction.setIdCurrency((int)currency.getId());
transaction.setConfirmed(true); //graphene transaction are always confirmed transaction.setConfirmed(true); //graphene transaction are always confirmed
transaction.setFrom(tOperation.getFrom().getObjectId()); transaction.setFrom(tOperation.getFrom().getObjectId());
transaction.setInput(!tOperation.getFrom().getObjectId().equals(accountBitsharesId)); transaction.setInput(!tOperation.getFrom().getObjectId().equals(accountBitsharesId));
transaction.setTo(tOperation.getTo().getObjectId()); transaction.setTo(tOperation.getTo().getObjectId());
transaction.setDate(new Date()); transaction.setDate(new Date());
CrystalDatabase.getAppDatabase(context).transactionDao().insertTransaction(transaction); CrystalDatabase.getAppDatabase(context).transactionDao().insertTransaction(transaction);
if (transaction.getInput()) { if(transaction.getInput()){
CryptoNetEvents.getInstance().fireEvent(new ReceivedFundsCryptoNetEvent(transaction.getAccount(), currency, transaction.getAmount())); CryptoNetEvents.getInstance().fireEvent(new ReceivedFundsCryptoNetEvent(transaction.getAccount(),currency,transaction.getAmount()));
} }
} }
/** /**
* Cancels all bitshares account subscriptions * Cancels all bitshares account subscriptions
*/ */
public static void cancelBitsharesAccountSubscriptions() { public static void cancelBitsharesAccountSubscriptions(){
bitsharesSubscriptionHub.cancelSubscriptions(); bitsharesSubscriptionHub.cancelSubscriptions();
} }
/** /**
* Retrieve the account balance of an account * Retrieve the account balance of an account
* *
* @param accountId The dataabase id of the account * @param accountId The dataabase id of the account
* @param accountGrapheneId The bitshares id of the account * @param accountGrapheneId The bitshares id of the account
* @param context The android context of this application * @param context The android context of this application
*/ */
public static void getAccountBalance(final long accountId, final String accountGrapheneId, public static void getAccountBalance(final long accountId, final String accountGrapheneId,
final Context context) { final Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao(); final CryptoCoinBalanceDao balanceDao = db.cryptoCoinBalanceDao();
@ -481,19 +470,19 @@ public abstract class GrapheneApiGenerator {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
List<AssetAmount> balances = (List<AssetAmount>) response.result; List<AssetAmount> balances = (List<AssetAmount>) response.result;
for (final AssetAmount balance : balances) { for(final AssetAmount balance : balances){
final CryptoCoinBalance ccBalance = new CryptoCoinBalance(); final CryptoCoinBalance ccBalance = new CryptoCoinBalance();
ccBalance.setAccountId(accountId); ccBalance.setAccountId(accountId);
ccBalance.setBalance(balance.getAmount().longValue()); ccBalance.setBalance(balance.getAmount().longValue());
BitsharesAssetInfo assetInfo = bitsharesAssetDao.getBitsharesAssetInfoById(balance.getAsset().getObjectId()); BitsharesAssetInfo assetInfo = bitsharesAssetDao.getBitsharesAssetInfoById(balance.getAsset().getObjectId());
if (assetInfo == null) { if(assetInfo == null ){
ArrayList<String> idAssets = new ArrayList<>(); ArrayList<String> idAssets = new ArrayList<>();
idAssets.add(balance.getAsset().getObjectId()); idAssets.add(balance.getAsset().getObjectId());
ApiRequest getAssetRequest = new ApiRequest(1, new ApiRequestListener() { ApiRequest getAssetRequest = new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
List<BitsharesAsset> assets = (List<BitsharesAsset>) answer; List<BitsharesAsset> assets = (List<BitsharesAsset>) answer;
for (BitsharesAsset asset : assets) { for(BitsharesAsset asset : assets) {
BitsharesAssetInfo info = new BitsharesAssetInfo(asset); BitsharesAssetInfo info = new BitsharesAssetInfo(asset);
long[] cryptoCurrencyId = cryptoCurrencyDao.insertCryptoCurrency((CryptoCurrency) asset); long[] cryptoCurrencyId = cryptoCurrencyDao.insertCryptoCurrency((CryptoCurrency) asset);
info.setCryptoCurrencyId(cryptoCurrencyId[0]); info.setCryptoCurrencyId(cryptoCurrencyId[0]);
@ -507,9 +496,9 @@ public abstract class GrapheneApiGenerator {
public void fail(int idPetition) { public void fail(int idPetition) {
} }
}); });
getAssetById(idAssets, getAssetRequest); getAssetById(idAssets,getAssetRequest);
} else { }else {
ccBalance.setCryptoCurrencyId(assetInfo.getCryptoCurrencyId()); ccBalance.setCryptoCurrencyId(assetInfo.getCryptoCurrencyId());
balanceDao.insertCryptoCoinBalance(ccBalance); balanceDao.insertCryptoCoinBalance(ccBalance);
@ -521,7 +510,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
@ -531,15 +520,15 @@ public abstract class GrapheneApiGenerator {
* Gets the date time of a block header * Gets the date time of a block header
* *
* @param blockHeader The block header to retrieve the date time * @param blockHeader The block header to retrieve the date time
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getBlockHeaderTime(long blockHeader, final ApiRequest request) { public static void getBlockHeaderTime(long blockHeader, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() { WebSocketThread thread = new WebSocketThread(new GetBlockHeader(blockHeader, new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
if (response == null) { if(response == null){
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} else { }else {
request.getListener().success(response.result, request.getId()); request.getListener().success(response.result, request.getId());
} }
} }
@ -548,7 +537,7 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); }),CryptoNetManager.getURL(CryptoNet.BITSHARES));
thread.start(); thread.start();
} }
@ -556,21 +545,21 @@ public abstract class GrapheneApiGenerator {
/** /**
* Gets a single equivalent value * Gets a single equivalent value
* *
* @param baseId The base asset bistshares id * @param baseId The base asset bistshares id
* @param quoteId the quote asset bitshares id * @param quoteId the quote asset bitshares id
* @param request the api request object, to answer this petition * @param request the api request object, to answer this petition
*/ */
public static void getEquivalentValue(final String baseId, String quoteId, final ApiRequest request) { public static void getEquivalentValue(final String baseId, String quoteId, final ApiRequest request){
WebSocketThread thread = new WebSocketThread(new GetLimitOrders(baseId, quoteId, 10, WebSocketThread thread = new WebSocketThread(new GetLimitOrders(baseId, quoteId, 10,
new WitnessResponseListener() { new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
List<LimitOrder> orders = (List<LimitOrder>) response.result; List<LimitOrder> orders = (List<LimitOrder>) response.result;
if (orders.size() <= 0) { if(orders.size()<= 0){
//TODO indirect equivalent value //TODO indirect equivalent value
} }
for (LimitOrder order : orders) { for(LimitOrder order : orders){
if (order.getSellPrice().base.getAsset().getBitassetId().equals(baseId)) { if(order.getSellPrice().base.getAsset().getBitassetId().equals(baseId)) {
Converter converter = new Converter(); Converter converter = new Converter();
double equiValue = converter.getConversionRate(order.getSellPrice(), double equiValue = converter.getConversionRate(order.getSellPrice(),
Converter.BASE_TO_QUOTE); Converter.BASE_TO_QUOTE);
@ -584,23 +573,23 @@ public abstract class GrapheneApiGenerator {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
request.getListener().fail(request.getId()); request.getListener().fail(request.getId());
} }
}), CryptoNetManager.getURL(CryptoNet.BITSHARES)); //todo change equivalent url for current server url }), BitsharesConstant.EQUIVALENT_URL); //todo change equivalent url for current server url
thread.start(); thread.start();
} }
/** /**
* Gets equivalent value and store it on the database * Gets equivalent value and store it on the database
* *
* @param baseAsset The baset asset as a bitshares asset, it needs the CryptoCurrency and thge BitsharesInfo * @param baseAsset The baset asset as a bitshares asset, it needs the CryptoCurrency and thge BitsharesInfo
* @param quoteAssets The list of the qutoe assets as a full bitshares asset object * @param quoteAssets The list of the qutoe assets as a full bitshares asset object
* @param context The android context of this application * @param context The android context of this application
*/ */
public static void getEquivalentValue(BitsharesAsset baseAsset, public static void getEquivalentValue(BitsharesAsset baseAsset,
final List<BitsharesAsset> quoteAssets, final Context context) { final List<BitsharesAsset> quoteAssets, final Context context){
for (BitsharesAsset quoteAsset : quoteAssets) { for(BitsharesAsset quoteAsset : quoteAssets){
WebSocketThread thread = new WebSocketThread(new GetLimitOrders(baseAsset.getBitsharesId(), WebSocketThread thread = new WebSocketThread(new GetLimitOrders(baseAsset.getBitsharesId(),
quoteAsset.getBitsharesId(), 10, new EquivalentValueListener(baseAsset, quoteAsset.getBitsharesId(), 10, new EquivalentValueListener(baseAsset,
quoteAsset, context)), CryptoNetManager.getURL(CryptoNet.BITSHARES)); //todo change equivalent url for current server url quoteAsset,context)), BitsharesConstant.EQUIVALENT_URL); //todo change equivalent url for current server url
thread.start(); thread.start();
} }
} }
@ -609,25 +598,25 @@ public abstract class GrapheneApiGenerator {
* Retrieves the equivalent value from a list of assets to a base asset * Retrieves the equivalent value from a list of assets to a base asset
* *
* @param baseAssetName The base asset to use * @param baseAssetName The base asset to use
* @param quoteAssets The list of quotes assets to query * @param quoteAssets The list of quotes assets to query
* @param context The Context of this Application * @param context The Context of this Application
*/ */
public static void getEquivalentValue(String baseAssetName, final List<BitsharesAsset> quoteAssets, final Context context) { public static void getEquivalentValue(String baseAssetName, final List<BitsharesAsset> quoteAssets, final Context context){
CrystalDatabase db = CrystalDatabase.getAppDatabase(context); CrystalDatabase db = CrystalDatabase.getAppDatabase(context);
final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao(); final CryptoCurrencyDao cryptoCurrencyDao = db.cryptoCurrencyDao();
final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao(); final BitsharesAssetDao bitsharesAssetDao = db.bitsharesAssetDao();
CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName); CryptoCurrency baseCurrency = cryptoCurrencyDao.getByName(baseAssetName);
BitsharesAssetInfo info = null; BitsharesAssetInfo info = null;
if (baseCurrency != null) { if(baseCurrency != null){
info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId()); info = db.bitsharesAssetDao().getBitsharesAssetInfo(baseCurrency.getId());
} }
if (baseCurrency == null || info == null) { if(baseCurrency == null || info == null){
ApiRequest getAssetRequest = new ApiRequest(1, new ApiRequestListener() { ApiRequest getAssetRequest = new ApiRequest(1, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
if (answer instanceof BitsharesAsset) { if(answer instanceof BitsharesAsset){
BitsharesAssetInfo info = new BitsharesAssetInfo((BitsharesAsset) answer); BitsharesAssetInfo info = new BitsharesAssetInfo((BitsharesAsset) answer);
long cryptoCurrencyId = cryptoCurrencyDao.insertCryptoCurrency((CryptoCurrency) answer)[0]; long cryptoCurrencyId = cryptoCurrencyDao.insertCryptoCurrency((CryptoCurrency)answer )[0];
info.setCryptoCurrencyId(cryptoCurrencyId); info.setCryptoCurrencyId(cryptoCurrencyId);
bitsharesAssetDao.insertBitsharesAssetInfo(info); bitsharesAssetDao.insertBitsharesAssetInfo(info);
GrapheneApiGenerator.getEquivalentValue((BitsharesAsset) answer, quoteAssets, context); GrapheneApiGenerator.getEquivalentValue((BitsharesAsset) answer, quoteAssets, context);
@ -641,12 +630,12 @@ public abstract class GrapheneApiGenerator {
}); });
ArrayList<String> names = new ArrayList<>(); ArrayList<String> names = new ArrayList<>();
names.add(baseAssetName); names.add(baseAssetName);
GrapheneApiGenerator.getAssetByName(names, getAssetRequest); GrapheneApiGenerator.getAssetByName(names,getAssetRequest);
} else { }else {
BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency); BitsharesAsset baseAsset = new BitsharesAsset(baseCurrency);
baseAsset.loadInfo(info); baseAsset.loadInfo(info);
getEquivalentValue(baseAsset, quoteAssets, context); getEquivalentValue(baseAsset,quoteAssets,context);
} }
@ -655,7 +644,7 @@ public abstract class GrapheneApiGenerator {
/** /**
* Listener of the equivalent value the answer is stored in the database, for use in conjuntion with LiveData * Listener of the equivalent value the answer is stored in the database, for use in conjuntion with LiveData
*/ */
private static class EquivalentValueListener implements WitnessResponseListener { private static class EquivalentValueListener implements WitnessResponseListener{
/** /**
* The base asset * The base asset
*/ */
@ -678,10 +667,10 @@ public abstract class GrapheneApiGenerator {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
List<LimitOrder> orders = (List<LimitOrder>) response.result; List<LimitOrder> orders = (List<LimitOrder>) response.result;
if (orders.size() <= 0) { if(orders.size()<= 0){
//TODO indirect equivalent value //TODO indirect equivalent value
} }
for (LimitOrder order : orders) { for(LimitOrder order : orders){
try { try {
//if (order.getSellPrice().base.getAsset().getBitassetId().equals(baseAsset.getBitsharesId())) { //if (order.getSellPrice().base.getAsset().getBitassetId().equals(baseAsset.getBitsharesId())) {
Converter converter = new Converter(); Converter converter = new Converter();
@ -692,7 +681,7 @@ public abstract class GrapheneApiGenerator {
CrystalDatabase.getAppDatabase(context).cryptoCurrencyEquivalenceDao().insertCryptoCurrencyEquivalence(equivalence); CrystalDatabase.getAppDatabase(context).cryptoCurrencyEquivalenceDao().insertCryptoCurrencyEquivalence(equivalence);
break; break;
//} //}
} catch (Exception e) { }catch(Exception e){
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -703,4 +692,5 @@ public abstract class GrapheneApiGenerator {
} }
} }
}
}

View File

@ -43,6 +43,7 @@ open abstract class DialogMaterial{
* Init the builder * Init the builder
* */ * */
builder = MaterialDialog.Builder(activity) builder = MaterialDialog.Builder(activity)
builder.cancelable(false)
} }
/* /*

View File

@ -2,6 +2,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.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
@ -24,6 +25,8 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.activities.BackupSeedActivity;
import cy.agorise.crystalwallet.activities.IntroActivity;
import cy.agorise.crystalwallet.dao.CrystalDatabase; import cy.agorise.crystalwallet.dao.CrystalDatabase;
import cy.agorise.crystalwallet.models.GeneralSetting; import cy.agorise.crystalwallet.models.GeneralSetting;
import cy.agorise.crystalwallet.requestmanagers.CreateBackupRequest; import cy.agorise.crystalwallet.requestmanagers.CreateBackupRequest;
@ -47,6 +50,9 @@ public class BackupsSettingsFragment extends Fragment{
return fragment; return fragment;
} }
@BindView(R.id.btnBrainkey)
public Button btnBrainkey;
@BindView(R.id.tvBinFile) @BindView(R.id.tvBinFile)
public TextView tvBinFile; public TextView tvBinFile;
@ -81,6 +87,15 @@ public class BackupsSettingsFragment extends Fragment{
return ssb; return ssb;
} }
@OnClick(R.id.btnBrainkey)
public void btnBrainOnClick(){
Intent intent = new Intent(getContext(), BackupSeedActivity.class);
startActivity(intent);
}
@OnClick(R.id.btnBinFile) @OnClick(R.id.btnBinFile)
public void makeBackupFile(){ public void makeBackupFile(){
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

View File

@ -1,12 +1,15 @@
package cy.agorise.crystalwallet.fragments; package cy.agorise.crystalwallet.fragments;
import android.app.Activity;
import android.app.Dialog; import android.app.Dialog;
import android.arch.lifecycle.ViewModelProviders;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -22,12 +25,16 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import cy.agorise.crystalwallet.R; import cy.agorise.crystalwallet.R;
import cy.agorise.crystalwallet.activities.BoardActivity;
import cy.agorise.crystalwallet.activities.ImportSeedActivity; import cy.agorise.crystalwallet.activities.ImportSeedActivity;
import cy.agorise.crystalwallet.activities.IntroActivity; import cy.agorise.crystalwallet.activities.IntroActivity;
import cy.agorise.crystalwallet.dialogs.material.CrystalDialog;
import cy.agorise.crystalwallet.dialogs.material.DialogMaterial;
import cy.agorise.crystalwallet.requestmanagers.FileServiceRequestListener; import cy.agorise.crystalwallet.requestmanagers.FileServiceRequestListener;
import cy.agorise.crystalwallet.requestmanagers.FileServiceRequests; import cy.agorise.crystalwallet.requestmanagers.FileServiceRequests;
import cy.agorise.crystalwallet.requestmanagers.ImportBackupRequest; import cy.agorise.crystalwallet.requestmanagers.ImportBackupRequest;
import cy.agorise.crystalwallet.util.UriTranslator; import cy.agorise.crystalwallet.util.UriTranslator;
import cy.agorise.crystalwallet.viewmodels.AccountSeedListViewModel;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
@ -45,6 +52,21 @@ public class ImportAccountOptionsFragment extends DialogFragment {
@BindView(R.id.btnImportBackup) @BindView(R.id.btnImportBackup)
Button btnImportBackup; Button btnImportBackup;
/*
Dialog for loading
*/
private CrystalDialog crystalDialog;
/*
* Contains the activity to close in case import succed
* */
private Activity introActivity;
public ImportAccountOptionsFragment() { public ImportAccountOptionsFragment() {
// Required empty public constructor // Required empty public constructor
} }
@ -141,14 +163,30 @@ public class ImportAccountOptionsFragment extends DialogFragment {
@Override @Override
public void run() { public void run() {
if (importBackupRequest.getStatus() == ImportBackupRequest.StatusCode.SUCCEEDED) { if (importBackupRequest.getStatus() == ImportBackupRequest.StatusCode.SUCCEEDED) {
Toast toast = Toast.makeText(
getContext(), "Backup restored!", Toast.LENGTH_LONG);
toast.show();
Intent intent = new Intent(getContext(), IntroActivity.class); //Checks if the user has any seed created
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); AccountSeedListViewModel accountSeedListViewModel = ViewModelProviders.of((FragmentActivity) getContext()).get(AccountSeedListViewModel.class);
if(introActivity!=null){
introActivity.finish();
}
Intent intent = new Intent(getContext(), BoardActivity.class);
startActivity(intent); startActivity(intent);
dismiss();
/*
* Hide the loading dialog
* */
crystalDialog.dismiss();
} else if (importBackupRequest.getStatus() == ImportBackupRequest.StatusCode.FAILED) { } else if (importBackupRequest.getStatus() == ImportBackupRequest.StatusCode.FAILED) {
/*
* Hide the loading dialog
* */
crystalDialog.dismiss();
Toast toast = Toast.makeText( Toast toast = Toast.makeText(
getContext(), "An error ocurred while restoring the backup!", Toast.LENGTH_LONG); getContext(), "An error ocurred while restoring the backup!", Toast.LENGTH_LONG);
toast.show(); toast.show();
@ -159,6 +197,14 @@ public class ImportAccountOptionsFragment extends DialogFragment {
}); });
FileServiceRequests.getInstance().addRequest(importBackupRequest); FileServiceRequests.getInstance().addRequest(importBackupRequest);
/*
* Show loading dialog
* */
crystalDialog = new CrystalDialog((Activity) getContext());
crystalDialog.setText(getContext().getString(R.string.Creating_backup_from_file));
crystalDialog.progress();
crystalDialog.show();
} }
}) })
.setNegativeButton("Cancel", .setNegativeButton("Cancel",
@ -173,4 +219,9 @@ public class ImportAccountOptionsFragment extends DialogFragment {
} }
} }
public void setIntroActivity(Activity introActivity) {
this.introActivity = introActivity;
}
} }

View File

@ -56,7 +56,10 @@ public class SecuritySettingsFragment extends Fragment {
return fragment; return fragment;
} }
private NfcAdapter mNfcAdapter; /*
* Functionality not needed for now
* */
//private NfcAdapter mNfcAdapter;
private PendingIntent pendingIntent; private PendingIntent pendingIntent;
private IntentFilter ndef; private IntentFilter ndef;
IntentFilter[] intentFiltersArray; IntentFilter[] intentFiltersArray;
@ -100,7 +103,11 @@ public class SecuritySettingsFragment extends Fragment {
mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout)); mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager)); tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mPager));
mNfcAdapter = NfcAdapter.getDefaultAdapter(this.getActivity()); /*
* Functionality not needed for now
* */
//mNfcAdapter = NfcAdapter.getDefaultAdapter(this.getActivity());
this.configureForegroundDispatch(); this.configureForegroundDispatch();
return v; return v;
@ -149,32 +156,37 @@ public class SecuritySettingsFragment extends Fragment {
} }
public void configureForegroundDispatch(){ public void configureForegroundDispatch(){
if (mNfcAdapter != null) {
pendingIntent = PendingIntent.getActivity(
this.getActivity(), 0, new Intent(this.getActivity(), getActivity().getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); /*
try { * Functionality not needed for now
ndef.addDataType("*/*"); /* Handles all MIME based dispatches. * */
You should specify only the ones that you need. */ //if (mNfcAdapter != null) {
} catch (IntentFilter.MalformedMimeTypeException e) { //pendingIntent = PendingIntent.getActivity(
throw new RuntimeException("fail", e); // this.getActivity(), 0, new Intent(this.getActivity(), getActivity().getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
intentFiltersArray = new IntentFilter[]{ndef,};
techList = new String[][]{ new String[] {IsoDep.class.getName(), NfcA.class.getName(), MifareClassic.class.getName(), NdefFormatable.class.getName()} };
} else { //ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
Toast.makeText(this.getContext(), "This device doesn't support NFC.", Toast.LENGTH_LONG).show(); //try {
} //ndef.addDataType("*/*");
// Handles all MIME based dispatches.
//You should specify only the ones that you need.
//} catch (IntentFilter.MalformedMimeTypeException e) {
//throw new RuntimeException("fail", e);
//}
//intentFiltersArray = new IntentFilter[]{ndef,};
//techList = new String[][]{ new String[] {IsoDep.class.getName(), NfcA.class.getName(), MifareClassic.class.getName(), NdefFormatable.class.getName()} };
//} else {
//Toast.makeText(this.getContext(), "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
//}
} }
public void enableNfc(){ public void enableNfc(){
mNfcAdapter.enableForegroundDispatch(this.getActivity(), pendingIntent, intentFiltersArray, techList); //mNfcAdapter.enableForegroundDispatch(this.getActivity(), pendingIntent, intentFiltersArray, techList);
Toast.makeText(this.getContext(), "Tap with your yubikey", Toast.LENGTH_LONG).show(); Toast.makeText(this.getContext(), "Tap with your yubikey", Toast.LENGTH_LONG).show();
} }
public void disableNfc(){ public void disableNfc(){
mNfcAdapter.disableForegroundDispatch(this.getActivity()); //mNfcAdapter.disableForegroundDispatch(this.getActivity());
} }
public void onPause() { public void onPause() {
@ -184,9 +196,9 @@ public class SecuritySettingsFragment extends Fragment {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if (mNfcAdapter != null) { /*if (mNfcAdapter != null) {
enableNfc(); enableNfc();
} }*/
} }
public void onNewIntent(Intent intent) { public void onNewIntent(Intent intent) {

View File

@ -24,15 +24,18 @@ import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window; import android.view.Window;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import com.google.zxing.Result; import com.google.zxing.Result;
import com.jaredrummler.materialspinner.MaterialSpinner; import com.jaredrummler.materialspinner.MaterialSpinner;
import com.vincent.filepicker.ToastUtil;
import java.io.File; import java.io.File;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -79,12 +82,16 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
TextView tvFromError; TextView tvFromError;
@BindView(R.id.etTo) @BindView(R.id.etTo)
EditText etTo; EditText etTo;
@BindView(R.id.viewSend)
View viewSend;
@BindView(R.id.tvToError) @BindView(R.id.tvToError)
TextView tvToError; TextView tvToError;
@BindView(R.id.spAsset) @BindView(R.id.spAsset)
Spinner spAsset; Spinner spAsset;
@BindView(R.id.tvAssetError) @BindView(R.id.tvAssetError)
TextView tvAssetError; TextView tvAssetError;
@BindView(R.id.scrollMain)
ScrollView scrollMain;
@BindView(R.id.etAmount) @BindView(R.id.etAmount)
EditText etAmount; EditText etAmount;
@BindView(R.id.tvAmountError) @BindView(R.id.tvAmountError)
@ -136,15 +143,65 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
fabSend.hide(); fabSend.hide();
//AlertDialog.Builder //AlertDialog.Builder
builder = new AlertDialog.Builder(getActivity(), R.style.SendTransactionTheme); builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
//builder.setTitle("Send"); //builder.setTitle("Send");
LayoutInflater inflater = getActivity().getLayoutInflater(); LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.send_transaction, null); View view = inflater.inflate(R.layout.send_transaction, null);
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
/*
* Detet scroll changes
* */
scrollMain.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
View view = scrollMain.getChildAt(scrollMain.getChildCount() - 1);
int diff = (view.getBottom() - (scrollMain.getHeight() + scrollMain.getScrollY()));
float traslationY = btnSend.getTranslationY();
if(diff<=266 && diff>128){
//btnSend.setTranslationY(0);
//viewSend.setTranslationY(0);
btnSend.animate().y(880);
viewSend.animate().y(800);
}
else if(diff<=128 && diff>10){
//btnSend.setTranslationY(-130);
//viewSend.setTranslationY(-130);
btnSend.animate().y(880);
viewSend.animate().y(800);
}
else if(diff<=10 && diff>0){
//btnSend.setTranslationY(-170);
//viewSend.setTranslationY(-170);
btnSend.animate().y(680);
viewSend.animate().y(600);
}
else if(diff==0){
//btnSend.setTranslationY(-190);
//viewSend.setTranslationY(-190);
btnSend.animate().y(680);
viewSend.animate().y(600);
}
}
});
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1); this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
/*
* Add style to the spinner android
* */
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
if (this.cryptoNetAccountId != -1) { if (this.cryptoNetAccountId != -1) {
db = CrystalDatabase.getAppDatabase(this.getContext()); db = CrystalDatabase.getAppDatabase(this.getContext());
this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId); this.cryptoNetAccount = db.cryptoNetAccountDao().getById(this.cryptoNetAccountId);
@ -153,8 +210,8 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
* this is only for graphene accounts. * this is only for graphene accounts.
* *
**/ **/
//this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount); this.grapheneAccount = new GrapheneAccount(this.cryptoNetAccount);
//this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId)); this.grapheneAccount.loadInfo(db.grapheneAccountInfoDao().getByAccountId(this.cryptoNetAccountId));
final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId); final LiveData<List<CryptoCoinBalance>> balancesList = db.cryptoCoinBalanceDao().getBalancesFromAccount(cryptoNetAccountId);
balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() { balancesList.observe(this, new Observer<List<CryptoCoinBalance>>() {
@ -178,7 +235,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList(); List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts); CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
//spFrom.setAdapter(fromSpinnerAdapter); spFrom.setAdapter(fromSpinnerAdapter);
//spFrom.setSelection(0); //spFrom.setSelection(0);
/* /*

View File

@ -19,6 +19,7 @@ import cy.agorise.crystalwallet.apigenerator.BitsharesFaucetApiGenerator;
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator; import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder; import cy.agorise.crystalwallet.apigenerator.grapheneoperation.AccountUpgradeOperationBuilder;
import cy.agorise.crystalwallet.application.constant.BitsharesConstant; import cy.agorise.crystalwallet.application.constant.BitsharesConstant;
import cy.agorise.crystalwallet.dao.AccountSeedDao;
import cy.agorise.crystalwallet.models.BitsharesAccountNameCache; import cy.agorise.crystalwallet.models.BitsharesAccountNameCache;
import cy.agorise.crystalwallet.models.seed.BIP39; import cy.agorise.crystalwallet.models.seed.BIP39;
import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest; import cy.agorise.crystalwallet.requestmanagers.CryptoNetEquivalentRequest;
@ -246,6 +247,9 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
*/ */
private void validateImportAccount(final ValidateImportBitsharesAccountRequest importRequest){ private void validateImportAccount(final ValidateImportBitsharesAccountRequest importRequest){
//TODO check internet and server status //TODO check internet and server status
final CrystalDatabase db = CrystalDatabase.getAppDatabase(importRequest.getContext());
final AccountSeedDao accountSeedDao = db.accountSeedDao();
ApiRequest checkAccountName = new ApiRequest(0, new ApiRequestListener() { ApiRequest checkAccountName = new ApiRequest(0, new ApiRequestListener() {
@Override @Override
public void success(Object answer, int idPetition) { public void success(Object answer, int idPetition) {
@ -259,7 +263,8 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
if((new Address(activeKey.getKey(),"BTS")).toString().equals(bk.getPublicAddress("BTS").toString())){ if((new Address(activeKey.getKey(),"BTS")).toString().equals(bk.getPublicAddress("BTS").toString())){
importRequest.setSeedType(SeedType.BRAINKEY); importRequest.setSeedType(SeedType.BRAINKEY);
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED); importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
return;
break;
} }
} }
BIP39 bip39 = new BIP39(-1, importRequest.getMnemonic()); BIP39 bip39 = new BIP39(-1, importRequest.getMnemonic());
@ -267,9 +272,29 @@ public class BitsharesAccountManager implements CryptoAccountManager, CryptoNetI
if((new Address(activeKey.getKey(),"BTS")).toString().equals(new Address(ECKey.fromPublicOnly(bip39.getBitsharesActiveKey(0).getPubKey())).toString())){ if((new Address(activeKey.getKey(),"BTS")).toString().equals(new Address(ECKey.fromPublicOnly(bip39.getBitsharesActiveKey(0).getPubKey())).toString())){
importRequest.setSeedType(SeedType.BIP39); importRequest.setSeedType(SeedType.BIP39);
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED); importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED);
return; break;
} }
} }
if ((importRequest.getStatus() == ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)){
if (importRequest.addAccountIfValid()) {
AccountSeed seed = new AccountSeed();
seed.setName(importRequest.getAccountName());
seed.setType(importRequest.getSeedType());
seed.setMasterSeed(importRequest.getMnemonic());
long idSeed = accountSeedDao.insertAccountSeed(seed);
if (idSeed >= 0) {
GrapheneAccount account = new GrapheneAccount();
account.setCryptoNet(CryptoNet.BITSHARES);
account.setAccountIndex(0);
account.setSeedId(idSeed);
account.setName(importRequest.getAccountName());
importAccountFromSeed(account, importRequest.getContext());
}
}
return;
}
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.BAD_SEED); importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.BAD_SEED);
} }
importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.PETITION_FAILED); importRequest.setStatus(ValidateImportBitsharesAccountRequest.StatusCode.PETITION_FAILED);

View File

@ -234,14 +234,14 @@ public class FileBackupManager implements FileServiceRequestsListener {
final AccountSeedDao accountSeedDao = db.accountSeedDao(); final AccountSeedDao accountSeedDao = db.accountSeedDao();
for(BitsharesSeedName seedName : seedNames) { for(BitsharesSeedName seedName : seedNames) {
final ValidateImportBitsharesAccountRequest validatorRequest = final ValidateImportBitsharesAccountRequest validatorRequest =
new ValidateImportBitsharesAccountRequest(seedName.accountName, seedName.accountSeed); new ValidateImportBitsharesAccountRequest(seedName.accountName, seedName.accountSeed, request.getContext(), true);
validatorRequest.setListener(new CryptoNetInfoRequestListener() { validatorRequest.setListener(new CryptoNetInfoRequestListener() {
@Override @Override
public void onCarryOut() { public void onCarryOut() {
if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) { if (!validatorRequest.getStatus().equals(ValidateImportBitsharesAccountRequest.StatusCode.SUCCEEDED)) {
request.setStatus(ImportBackupRequest.StatusCode.FAILED); // TODO reason bad seed request.setStatus(ImportBackupRequest.StatusCode.FAILED); // TODO reason bad seed
} else { } else {
AccountSeed seed = new AccountSeed(); /*AccountSeed seed = new AccountSeed();
seed.setName(validatorRequest.getAccountName()); seed.setName(validatorRequest.getAccountName());
seed.setType(validatorRequest.getSeedType()); seed.setType(validatorRequest.getSeedType());
seed.setMasterSeed(validatorRequest.getMnemonic()); seed.setMasterSeed(validatorRequest.getMnemonic());
@ -257,7 +257,8 @@ public class FileBackupManager implements FileServiceRequestsListener {
request.setStatus(ImportBackupRequest.StatusCode.SUCCEEDED); request.setStatus(ImportBackupRequest.StatusCode.SUCCEEDED);
}else{ }else{
request.setStatus(ImportBackupRequest.StatusCode.FAILED); //TODO reason couldn't insert seed request.setStatus(ImportBackupRequest.StatusCode.FAILED); //TODO reason couldn't insert seed
} }*/
request.setStatus(ImportBackupRequest.StatusCode.SUCCEEDED);
} }
} }
}); });

View File

@ -1,6 +1,5 @@
package cy.agorise.crystalwallet.network; package cy.agorise.crystalwallet.network;
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.enums.CryptoNet; import cy.agorise.crystalwallet.enums.CryptoNet;
import cy.agorise.graphenej.interfaces.WitnessResponseListener; import cy.agorise.graphenej.interfaces.WitnessResponseListener;
import cy.agorise.graphenej.models.BaseResponse; import cy.agorise.graphenej.models.BaseResponse;
@ -24,21 +23,15 @@ public class BitsharesCryptoNetVerifier extends CryptoNetVerifier {
private final String CHAIN_ID = "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";//testnet private final String CHAIN_ID = "9cf6f255a208100d2bb275a3c52f4b1589b7ec9c9bfc2cb2a5fe6411295106d8";//testnet
//private final String CHAIN_ID = "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8";//mainnet //private final String CHAIN_ID = "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8";//mainnet
@Override
public void checkURL(final String url) {
public BitsharesCryptoNetVerifier(){
/**/
final long startTime = System.currentTimeMillis(); final long startTime = System.currentTimeMillis();
thread = new WebSocketThread(new GetChainId(new WitnessResponseListener() { WebSocketThread thread = new WebSocketThread(new GetChainId(new WitnessResponseListener() {
@Override @Override
public void onSuccess(WitnessResponse response) { public void onSuccess(WitnessResponse response) {
if(response.result instanceof String) { if(response.result instanceof String) {
if(response.result.equals(CHAIN_ID)) { if(response.result.equals(CHAIN_ID)) {
CryptoNetManager.verifiedCryptoNetURL(cryptoNet, null, System.currentTimeMillis() - startTime); CryptoNetManager.verifiedCryptoNetURL(cryptoNet, url, System.currentTimeMillis() - startTime);
}else{ }else{
System.out.println(" BitsharesCryptoNetVerifier Error we are not in the net current chain id " + response.result + " excepted " + CHAIN_ID); System.out.println(" BitsharesCryptoNetVerifier Error we are not in the net current chain id " + response.result + " excepted " + CHAIN_ID);
//TODO handle error bad chain //TODO handle error bad chain
@ -50,19 +43,12 @@ public class BitsharesCryptoNetVerifier extends CryptoNetVerifier {
public void onError(BaseResponse.Error error) { public void onError(BaseResponse.Error error) {
//TODO handle error //TODO handle error
} }
}),null); }),url);
thread.start();
}
@Override
public void checkURL(final String url) {
thread.setmUrl(url); //Set the url
thread.start(); //Run the thread connection
} }
@Override @Override
public String getChainId() { public String getChainId() {
return CHAIN_ID; return CHAIN_ID;
} }
} }

View File

@ -1,8 +1,5 @@
package cy.agorise.crystalwallet.network; package cy.agorise.crystalwallet.network;
import android.app.Activity;
import cy.agorise.crystalwallet.apigenerator.GrapheneApiGenerator;
import cy.agorise.crystalwallet.enums.CryptoNet; import cy.agorise.crystalwallet.enums.CryptoNet;
/** /**
@ -15,14 +12,6 @@ import cy.agorise.crystalwallet.enums.CryptoNet;
public abstract class CryptoNetVerifier { public abstract class CryptoNetVerifier {
/*
* Contains the worker connection thread
*/
protected WebSocketThread thread;
static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){ static CryptoNetVerifier getNetworkVerify(CryptoNet cryptoNet){
if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){ if(cryptoNet.getLabel().equals(CryptoNet.BITSHARES.getLabel())){
return new BitsharesCryptoNetVerifier(); return new BitsharesCryptoNetVerifier();
@ -33,9 +22,4 @@ public abstract class CryptoNetVerifier {
public abstract void checkURL(final String url); public abstract void checkURL(final String url);
public abstract String getChainId(); public abstract String getChainId();
}
public WebSocketThread getThread() {
return thread;
}
}

View File

@ -3,6 +3,7 @@ package cy.agorise.crystalwallet.network;
import android.util.Log; import android.util.Log;
import com.neovisionaries.ws.client.WebSocket; import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory; import com.neovisionaries.ws.client.WebSocketFactory;
import com.neovisionaries.ws.client.WebSocketListener; import com.neovisionaries.ws.client.WebSocketListener;
@ -33,11 +34,6 @@ public class WebSocketThread extends Thread {
private boolean canChange = true; private boolean canChange = true;
/*
* Object needed for socket connection
* */
private WebSocketFactory factory;
/** /**
* Basic constructor, * Basic constructor,
* *
@ -47,27 +43,16 @@ public class WebSocketThread extends Thread {
* @param url The url to connect * @param url The url to connect
*/ */
public WebSocketThread(WebSocketListener webSocketListener, String url) { public WebSocketThread(WebSocketListener webSocketListener, String url) {
try {
/* WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000);
* The listener always can be setted this.mUrl = url;
* */ this.mWebSocketListener = webSocketListener;
this.mWebSocketListener = webSocketListener; this.mWebSocket = factory.createSocket(this.mUrl);
this.mWebSocket.addListener(this.mWebSocketListener);
/* } catch (IOException e) {
* Log.e(TAG, "IOException. Msg: "+e.getMessage());
* If at this point the url is not defined, this will be set after } catch(NullPointerException e){
* */ Log.e(TAG, "NullPointerException at WebsocketWorkerThreas. Msg: "+e.getMessage());
if(url!=null){
try {
factory = new WebSocketFactory().setConnectionTimeout(5000);
this.mUrl = url;
this.mWebSocket = factory.createSocket(this.mUrl);
this.mWebSocket.addListener(this.mWebSocketListener);
} catch (IOException e) {
Log.e(TAG, "IOException. Msg: "+e.getMessage());
} catch(NullPointerException e){
Log.e(TAG, "NullPointerException at WebsocketWorkerThreas. Msg: "+e.getMessage());
}
} }
} }
@ -125,28 +110,16 @@ public class WebSocketThread extends Thread {
@Override @Override
public void run() { public void run() {
canChange = false; canChange = false;
// Moves the current Thread into the background // Moves the current Thread into the background
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
try { try {
/*
* If the initialization of the socket comes after
* */
if(factory==null){
factory = new WebSocketFactory().setConnectionTimeout(5000);
this.mWebSocket = factory.createSocket(this.mUrl);
this.mWebSocket.addListener(this.mWebSocketListener);
}
WebSocketThread.currentThreads.put(this.getId(),this); WebSocketThread.currentThreads.put(this.getId(),this);
mWebSocket.connect(); mWebSocket.connect();
} catch (WebSocketException e) {
} catch (final Exception e) {
Log.e(TAG, "WebSocketException. Msg: "+e.getMessage()); Log.e(TAG, "WebSocketException. Msg: "+e.getMessage());
} catch(NullPointerException e){
Log.e(TAG, "NullPointerException. Msg: "+e.getMessage());
} }
WebSocketThread.currentThreads.remove(this.getId()); WebSocketThread.currentThreads.remove(this.getId());
} }
@ -154,9 +127,4 @@ public class WebSocketThread extends Thread {
public boolean isConnected(){ public boolean isConnected(){
return mWebSocket.isOpen(); return mWebSocket.isOpen();
} }
}
public void setmUrl(String mUrl) {
this.mUrl = mUrl;
}
}

View File

@ -1,5 +1,7 @@
package cy.agorise.crystalwallet.requestmanagers; package cy.agorise.crystalwallet.requestmanagers;
import android.content.Context;
import cy.agorise.crystalwallet.enums.CryptoCoin; import cy.agorise.crystalwallet.enums.CryptoCoin;
import cy.agorise.crystalwallet.enums.SeedType; import cy.agorise.crystalwallet.enums.SeedType;
@ -36,6 +38,11 @@ public class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest
*/ */
private final String mnemonic; private final String mnemonic;
/**
* True - the account must be added if the accountName and mnemonic are correct
*/
private boolean addAccountIfValid = false;
/** /**
* If this seed is BIP39 or Brainkey * If this seed is BIP39 or Brainkey
*/ */
@ -46,10 +53,21 @@ public class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest
*/ */
private StatusCode status = StatusCode.NOT_STARTED; private StatusCode status = StatusCode.NOT_STARTED;
public ValidateImportBitsharesAccountRequest(String accountName, String mnemonic){ private Context context;
public ValidateImportBitsharesAccountRequest(String accountName, String mnemonic, Context context){
super(CryptoCoin.BITSHARES); super(CryptoCoin.BITSHARES);
this.accountName = accountName; this.accountName = accountName;
this.mnemonic = mnemonic; this.mnemonic = mnemonic;
this.context = context;
}
public ValidateImportBitsharesAccountRequest(String accountName, String mnemonic, Context context, boolean addAccountIfValid){
super(CryptoCoin.BITSHARES);
this.accountName = accountName;
this.mnemonic = mnemonic;
this.addAccountIfValid = addAccountIfValid;
this.context = context;
} }
public void validate(){ public void validate(){
@ -70,6 +88,14 @@ public class ValidateImportBitsharesAccountRequest extends CryptoNetInfoRequest
return seedType; return seedType;
} }
public Context getContext() {
return context;
}
public boolean addAccountIfValid(){
return this.addAccountIfValid;
}
public void setSeedType(SeedType seedType) { public void setSeedType(SeedType seedType) {
this.seedType = seedType; this.seedType = seedType;
} }

View File

@ -69,6 +69,7 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
* Remove error * Remove error
* */ * */
accountNameField.error = null accountNameField.error = null
accountNameField.fieldValidatorModel.setValid()
/* /*
Validate at least min length Validate at least min length
@ -87,6 +88,7 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
* Remove error * Remove error
* */ * */
accountNameField.error = null accountNameField.error = null
accountNameField.fieldValidatorModel.setValid()
/* /*
Validate at least one character Validate at least one character
@ -105,6 +107,7 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
* Remove error * Remove error
* */ * */
accountNameField.error = null accountNameField.error = null
accountNameField.fieldValidatorModel.setValid()
/* /*
Validate at least one number for the account string Validate at least one number for the account string
@ -117,12 +120,14 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
result = false result = false
accountNameField.fieldValidatorModel.setInvalid() accountNameField.fieldValidatorModel.setInvalid()
accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_number) accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_number)
} else { } else {
/* /*
* Remove error * Remove error
* */ * */
accountNameField.error = null accountNameField.error = null
accountNameField.fieldValidatorModel.setValid()
/* /*
@ -136,12 +141,14 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
result = false result = false
accountNameField.fieldValidatorModel.setInvalid() accountNameField.fieldValidatorModel.setInvalid()
accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_script) accountNameField.fieldValidatorModel.message = this.accountNameField.resources.getString(R.string.create_account_window_err_at_least_one_script)
} else { } else {
/* /*
* Remove error * Remove error
* */ * */
accountNameField.error = null accountNameField.error = null
accountNameField.fieldValidatorModel.setValid()
} }
} }
} }
@ -162,46 +169,11 @@ class BitsharesAccountNameValidation : CustomValidationField, UIValidator {
} else { } else {
/* /*
* Show the dialog for connection with the server * Deliver result
* */ * */
val creatingAccountMaterialDialog = CrystalDialog(activity) if (uiValidatorListener != null) {
creatingAccountMaterialDialog.setText(activity.resources.getString(R.string.window_create_seed_Server_validation)) uiValidatorListener.onValidationSucceeded(this)
creatingAccountMaterialDialog.build()
creatingAccountMaterialDialog.show()
val request = ValidateExistBitsharesAccountRequest(newValue)
request.setListener {
/*
* Dismiss the dialog of loading
* */
creatingAccountMaterialDialog.dismiss()
if (request.accountExists) {
/*
* The account exists and is not valid
* */
accountNameField.fieldValidatorModel.setInvalid()
accountNameField.fieldValidatorModel.message = accountNameField.resources.getString(R.string.account_name_already_exist)
} else {
/*
* Passed all validations
* */
accountNameField.fieldValidatorModel.setValid()
/*
* Deliver the response
* */
if (uiValidatorListener != null) {
uiValidatorListener.onValidationSucceeded(globalCustomValidationField)
}
}
} }
CryptoNetInfoRequests.getInstance().addRequest(request)
} }
/* /*
* Passed initial validations, next final validations * Passed initial validations, next final validations

View File

@ -30,7 +30,18 @@ public class AmountValidationField extends ValidationField {
try { try {
final float newAmountValue = Float.parseFloat(amountField.getText().toString()); final float newAmountValue = Float.parseFloat(amountField.getText().toString());
final CryptoCurrency cryptoCurrency = (CryptoCurrency)assetSpinner.getSelectedItem(); final CryptoCurrency cryptoCurrency = (CryptoCurrency)assetSpinner.getSelectedItem();
final String mixedValues = newAmountValue+"_"+cryptoCurrency.getId();
/*
* Validation for the money
* */
if(cryptoCurrency==null){
setMessageForValue("",amountField.getContext().getString(R.string.send_assets_error_invalid_cypto_coin_selected));
setValidForValue("", false);
return;
}
final String idCurrency = cryptoCurrency==null?"null ":Long.toString(cryptoCurrency.getId());
final String mixedValues = newAmountValue + "_" + idCurrency;
this.setLastValue(mixedValues); this.setLastValue(mixedValues);
this.startValidating(); this.startValidating();
final ValidationField field = this; final ValidationField field = this;

View File

@ -31,7 +31,7 @@ public class BitsharesAccountMnemonicValidationField extends ValidationField {
this.startValidating(); this.startValidating();
final ValidationField field = this; final ValidationField field = this;
final ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(newAccountNameValue,newMnemonicValue); final ValidateImportBitsharesAccountRequest request = new ValidateImportBitsharesAccountRequest(newAccountNameValue,newMnemonicValue,accountNameField.getContext());
request.setListener(new CryptoNetInfoRequestListener() { request.setListener(new CryptoNetInfoRequestListener() {
@Override @Override
public void onCarryOut() { public void onCarryOut() {

View File

@ -0,0 +1,165 @@
package cy.agorise.crystalwallet.views.natives.spinners
import android.R
import android.content.Context
import android.util.AttributeSet
import android.view.View
import cy.agorise.crystalwallet.models.CryptoNetAccount
import cy.agorise.crystalwallet.requestmanagers.CryptoNetInfoRequests
import cy.agorise.crystalwallet.requestmanagers.ValidateExistBitsharesAccountRequest
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField
import cy.agorise.crystalwallet.views.CryptoNetAccountAdapter
class CryptoNetAccountsSpinner : InternalMaterialSpinner {
/*
* Contains the list of accounts
* */
private var cryptoNetAccounts: MutableList<CryptoNetAccount>? = null
/*
* Contains the current adapter
* */
private var fromSpinnerAdapter:CryptoNetAccountAdapter? = null
/*
* Listeners
* */
private var onValidationField:OnValidationFailed? = null
private var onValidationSucceeded:OnValidationSucceeded? = null
private var onAccountNotExists:OnAccountNotExists? = null
private var onItemSelectedListener:OnItemSelectedListener? = null
private var onAccountExists:OnAccountExists? = null
/*
* Current selected account
* */
private var cryptoNetAccount:CryptoNetAccount? = null
constructor(context: Context?, attrs: AttributeSet?) : super(context,attrs){
/*
* Initialy starts with the android layout
* */
setAndroidLayout()
/*
* When the user changes the item selection save the model
* */
setOnItemSelectedListener(OnItemSelectedListener<CryptoNetAccount> { view, position, id, item ->
/*
* Save the current model
* */
cryptoNetAccount = cryptoNetAccounts?.get(position)
/*
* Deliver response
* */
if(onItemSelectedListener != null){
onItemSelectedListener?.onItemSelectedListener(cryptoNetAccount!!)
}
})
}
/*
* Return the current selected cryptonetaccount
* */
fun getCryptoNetAccountSelected() : CryptoNetAccount{
return this.cryptoNetAccount!!
}
/*
* Set the current layoutview
* */
fun setLayout(layout:Int){
this.layout = layout
}
/*
* Init the spinner, before call this method, this list of items should be set
* */
fun initCryptoNetAccountAdapter(){
fromSpinnerAdapter = CryptoNetAccountAdapter(context, this.layout!!, cryptoNetAccounts)
setAdapter(fromSpinnerAdapter!!)
}
fun setCryptoAccountItems(cryptoNetAccounts:MutableList<CryptoNetAccount>){
this.cryptoNetAccounts = cryptoNetAccounts
}
/*
* Validate if the "selected" account exists
* */
fun validateExistBitsharesAccountRequest(){
if(cryptoNetAccount != null){
val request = ValidateExistBitsharesAccountRequest(cryptoNetAccount?.name)
request.setListener {
if (!request.accountExists) {
if(onAccountNotExists != null){
onAccountNotExists?.onAccountNotExists(this_!!)
}
}
else {
if(onAccountExists != null){
onAccountExists?.onAccountExists(this_!!)
}
}
}
CryptoNetInfoRequests.getInstance().addRequest(request)
}
}
/*
* Listener for validations
* */
fun onValidationFailed(onValidationField:OnValidationFailed){
this.onValidationField = onValidationField
}
fun onValidationSucceeded(onValidationSucceeded: OnValidationSucceeded){
this.onValidationSucceeded = onValidationSucceeded
}
fun onAccountNotExists(onAccountNotExists: OnAccountNotExists){
this.onAccountNotExists = onAccountNotExists
}
fun onItemSelectedListener(onItemSelectedListener: OnItemSelectedListener){
this.onItemSelectedListener = onItemSelectedListener
}
fun onAccountExists(onAccountExists: OnAccountExists){
this.onAccountExists = onAccountExists
}
/*
* End of Listener for validations
* */
/*
* Add the items list to the spinner
* */
fun getCryptoAccountsList() : List<CryptoNetAccount>{
return this.cryptoNetAccounts!!
}
/*
* Interface for validation failed
* */
interface OnAccountNotExists{
fun onAccountNotExists(field: View)
}
interface OnAccountExists{
fun onAccountExists(field: View)
}
interface OnItemSelectedListener{
fun onItemSelectedListener(cryptoNetAccount: CryptoNetAccount)
}
}

View File

@ -0,0 +1,80 @@
package cy.agorise.crystalwallet.views.natives.spinners
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.View
import com.jaredrummler.materialspinner.MaterialSpinner
import cy.agorise.crystalwallet.viewmodels.validators.UIValidatorListener
import cy.agorise.crystalwallet.viewmodels.validators.validationfields.ValidationField
open class InternalMaterialSpinner : MaterialSpinner {
/*
* Contains the current layout for the rows
* */
protected var layout:Int? = null
/*
* Listeners
* */
private var onItemNotSelected: OnItemNotSelected? = null
/*
* Contains the this for interfaces
* */
protected var this_: View? = null
constructor(context: Context?, attrs: AttributeSet?) : super(context,attrs){
/*
* Save the current this
* */
this_ = this
}
/*
* Select the first item in the spinner
* */
fun selectFirstItem(){
this.selectedIndex = 0
}
/*
* Set the default android layout
* */
fun setAndroidLayout(){
this.layout = android.R.layout.simple_spinner_item
}
fun onItemNotSelected(onItemNotSelected:OnItemNotSelected){
this.onItemNotSelected = onItemNotSelected
}
/*
* Validation with listener for item selected or not
* */
fun validateOnItemNotSelected(){
if(this.selectedIndex == -1){
if(onItemNotSelected != null){
onItemNotSelected?.onItemNotSelected()
}
}
}
/*
* Interface for validation failed
* */
interface OnValidationFailed{
fun onValidationFailed(field: ValidationField)
}
interface OnValidationSucceeded{
fun onValidationSucceeded(field: ValidationField)
}
interface OnItemNotSelected{
fun onItemNotSelected()
}
}

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0" android:toXDelta="10" android:duration="1000"
android:interpolator="@anim/cycle_7" />

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="5dp"
android:topRightRadius="5dp"
android:bottomRightRadius="5dp"
android:bottomLeftRadius="5dp" />
<stroke
android:width="1dp"
android:color="@color/transparent" />
<solid android:color="@color/transparent" />
</shape>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="4dp"
android:topRightRadius="4dp"
android:bottomRightRadius="4dp"
android:bottomLeftRadius="4dp" />
<stroke
android:width="1dp"
android:color="#0099ff" />
</shape>

View File

@ -3,88 +3,85 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:background="@color/white"
android:paddingBottom="0dp" android:paddingBottom="0dp"
android:paddingLeft="0dp" android:paddingLeft="25dp"
android:paddingRight="0dp" android:paddingRight="25dp"
android:paddingTop="@dimen/activity_vertical_margin"> android:paddingTop="@dimen/activity_vertical_margin">
<RelativeLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true"> android:background="@color/white"
android:padding="20dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true">
<TextView <TextView
android:id="@+id/tvMnemonicTitle" android:id="@+id/tvMnemonicTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_alignParentTop="true"
android:layout_marginRight="@dimen/activity_horizontal_margin" android:layout_alignStart="@+id/linearlayout1"
android:layout_marginTop="10dp" android:layout_marginTop="35dp"
android:layout_marginBottom="20dp"
android:text="@string/window_seed_backup" android:text="@string/window_seed_backup"
android:layout_centerHorizontal="true" android:textColor="@color/black"
android:textSize="20dp" android:textSize="25dp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <LinearLayout
android:id="@+id/tvBrainKey" android:id="@+id/linearlayout1"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/tvMnemonicTitle" android:layout_below="@+id/tvMnemonicTitle"
android:layout_marginLeft="@dimen/activity_horizontal_margin" android:layout_marginTop="35dp"
android:layout_marginRight="@dimen/activity_horizontal_margin" android:background="@drawable/square"
android:gravity="center" android:padding="10dp">
android:background="@drawable/edittext_bg"
android:layout_centerHorizontal="true"
android:textColor="@color/black"
android:layout_marginBottom="20dp"/>
<ImageView <TextView
android:id="@+id/backup_seeed_imageview_warning" android:id="@+id/tvBrainKey"
android:layout_width="20dp" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginLeft="35dp" android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_alignTop="@+id/backup_seed_textview_leyend_backup" android:gravity="center"
android:background="@drawable/warning" /> android:background="#00000000"
android:textColor="@color/gray" />
</LinearLayout>
<TextView <TextView
android:id="@+id/backup_seed_textview_leyend_backup" android:id="@+id/backup_seed_textview_leyend_backup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/linearlayout1"
android:layout_marginTop="35dp"
android:text="@string/window_seed_leyend_backup"
android:textColor="@color/black"
android:textSize="14dp" />
<Button
android:id="@+id/btnCancel"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="70dp"
android:textColor="@color/send_strong_orange"
android:layout_marginRight="70dp"
android:text="@string/window_seed_leyend_backup"
android:textSize="14dp"
android:layout_below="@+id/tvBrainKey"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:layout_below="@+id/backup_seed_textview_leyend_backup" android:layout_below="@+id/backup_seed_textview_leyend_backup"
android:layout_centerHorizontal="true" android:layout_marginLeft="20dp"
android:weightSum="2"> android:layout_marginTop="35dp"
android:layout_toLeftOf="@+id/btnCopy"
android:text="@string/cancel"
android:textColor="#0099ff"
android:background="?android:attr/selectableItemBackground"/>
<Button <Button
android:id="@+id/btnOk" android:id="@+id/btnCopy"
android:layout_weight="1" android:layout_width="wrap_content"
android:layout_width="40dp" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_alignParentRight="true"
android:background="@drawable/ok"/> android:layout_below="@+id/backup_seed_textview_leyend_backup"
android:layout_marginTop="35dp"
android:text="@string/window_seed_copy"
android:textColor="#0099ff"
android:background="?android:attr/selectableItemBackground"/>
<Button
android:id="@+id/btnCopy"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:text="@string/window_seed_copy"
android:textColor="@color/black" />
</LinearLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -97,7 +97,7 @@
</android.support.v7.widget.Toolbar> </android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout <com.sjaramillo10.animatedtablayout.AnimatedTabLayout
android:id="@+id/tabLayout" android:id="@+id/tabLayout"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:background="@color/transparent" android:background="@color/transparent"

View File

@ -22,7 +22,7 @@
android:layout_below="@+id/tvPasswordInput" android:layout_below="@+id/tvPasswordInput"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:ems="10" android:ems="10"
android:inputType="numberPassword" /> android:inputType="textPassword" />
</RelativeLayout> </RelativeLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>

View File

@ -38,7 +38,6 @@
android:layout_marginTop="24dp" android:layout_marginTop="24dp"
android:text="@string/brainkey_description" android:text="@string/brainkey_description"
android:textSize="15sp" android:textSize="15sp"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@id/tvBinFile" app:layout_constraintEnd_toEndOf="@id/tvBinFile"
app:layout_constraintStart_toStartOf="@id/tvBinFile" app:layout_constraintStart_toStartOf="@id/tvBinFile"
app:layout_constraintTop_toBottomOf="@id/btnBinFile" /> app:layout_constraintTop_toBottomOf="@id/btnBinFile" />
@ -53,7 +52,6 @@
android:text="@string/view_and_copy" android:text="@string/view_and_copy"
android:textColor="@color/white" android:textColor="@color/white"
android:textStyle="bold" android:textStyle="bold"
android:visibility="invisible"
app:layout_constraintStart_toStartOf="@id/btnBinFile" app:layout_constraintStart_toStartOf="@id/btnBinFile"
app:layout_constraintTop_toBottomOf="@id/tvBrainkey" /> app:layout_constraintTop_toBottomOf="@id/tvBrainkey" />

View File

@ -1,244 +1,271 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"
android:theme="@style/ActivityDialog">
<android.support.constraint.ConstraintLayout
<ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="24dp"> android:layout_margin="20dp"
android:background="@color/white"
android:id="@+id/scrollMain">
<View <android.support.constraint.ConstraintLayout
android:id="@+id/topView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:background="@drawable/send_transaction_top_view"
android:layout_height="120dp"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="24dp" android:paddingBottom="24dp">
android:layout_marginTop="24dp"
android:text="@string/title_capital"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<cy.agorise.crystalwallet.util.CircularImageView <View
android:id="@+id/gravatar" android:id="@+id/topView"
android:layout_width="60dp" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="119dp"
android:layout_marginStart="32dp" android:background="@drawable/send_transaction_top_view"
android:layout_marginTop="90dp" app:layout_constraintEnd_toEndOf="parent"
android:src="@drawable/avatar_placeholder" app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<com.jaredrummler.materialspinner.MaterialSpinner <TextView
android:id="@+id/spFrom" android:layout_width="wrap_content"
android:layout_width="0dp" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginStart="24dp"
android:layout_marginEnd="24dp" android:layout_marginTop="24dp"
android:layout_marginStart="16dp" android:text="@string/title_capital"
app:layout_constraintEnd_toEndOf="parent" android:textColor="@color/white"
app:layout_constraintStart_toEndOf="@id/gravatar" android:textSize="20sp"
app:layout_constraintTop_toTopOf="@id/gravatar" /> android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <cy.agorise.crystalwallet.util.CircularImageView
android:id="@+id/tvFromError" android:id="@+id/gravatar"
android:layout_width="0dp" android:layout_width="60dp"
android:layout_height="wrap_content" android:layout_height="60dp"
android:textColor="@color/red" android:layout_marginStart="32dp"
app:layout_constraintEnd_toEndOf="@+id/spFrom" android:layout_marginTop="90dp"
app:layout_constraintStart_toStartOf="@+id/spFrom" android:src="@drawable/avatar_placeholder"
app:layout_constraintTop_toBottomOf="@+id/topView" /> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText <com.jaredrummler.materialspinner.MaterialSpinner
android:id="@+id/etTo" android:id="@+id/spFrom"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="40dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:layout_marginStart="24dp" android:layout_marginStart="16dp"
android:layout_marginTop="24dp" android:textColor="@color/white"
android:gravity="top" app:layout_constraintEnd_toEndOf="parent"
android:inputType="text" app:layout_constraintStart_toEndOf="@id/gravatar"
android:textSize="20sp" app:layout_constraintBottom_toBottomOf="@+id/topView"/>
android:hint="@string/to_capital"
android:maxLength="255"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/gravatar" />
<ImageView <TextView
android:id="@+id/ivPeople" android:id="@+id/tvFromError"
android:layout_width="30dp" android:layout_width="0dp"
android:layout_height="30dp" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" android:textColor="@color/red"
app:srcCompat="@drawable/ic_people" app:layout_constraintEnd_toEndOf="@+id/spFrom"
android:layout_marginBottom="15dp" app:layout_constraintStart_toStartOf="@+id/spFrom"
app:layout_constraintEnd_toEndOf="@id/etTo" app:layout_constraintTop_toBottomOf="@+id/topView" />
app:layout_constraintBottom_toBottomOf="@id/etTo"
android:contentDescription="@string/people_icon" />
<TextView <EditText
android:id="@+id/tvToError" android:id="@+id/etTo"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="@+id/etTo" android:layout_marginStart="24dp"
app:layout_constraintStart_toStartOf="@+id/etTo" android:layout_marginTop="24dp"
app:layout_constraintTop_toBottomOf="@+id/etTo" /> android:gravity="top"
android:inputType="text"
android:textSize="20sp"
android:hint="@string/to_capital"
android:maxLength="255"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/gravatar" />
<EditText <ImageView
android:id="@+id/etAmount" android:id="@+id/ivPeople"
android:layout_width="150dp" android:layout_width="30dp"
android:layout_height="wrap_content" android:layout_height="30dp"
android:layout_marginTop="8dp" android:layout_marginEnd="5dp"
android:layout_marginStart="24dp" app:srcCompat="@drawable/ic_people"
android:inputType="numberDecimal" android:layout_marginBottom="15dp"
android:textSize="20sp" app:layout_constraintEnd_toEndOf="@id/etTo"
android:hint="@string/amount" app:layout_constraintBottom_toBottomOf="@id/etTo"
app:layout_constraintStart_toStartOf="parent" android:contentDescription="@string/people_icon" />
app:layout_constraintTop_toBottomOf="@+id/tvToError" />
<TextView <TextView
android:id="@+id/tvAmountError" android:id="@+id/tvToError"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="@+id/etAmount" app:layout_constraintEnd_toEndOf="@+id/etTo"
app:layout_constraintStart_toStartOf="@+id/etAmount" app:layout_constraintStart_toStartOf="@+id/etTo"
app:layout_constraintTop_toBottomOf="@+id/etAmount" /> app:layout_constraintTop_toBottomOf="@+id/etTo" />
<Spinner <EditText
android:id="@+id/spAsset" android:id="@+id/etAmount"
android:layout_width="150dp" android:layout_width="150dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="24dp" android:layout_marginTop="8dp"
android:layout_marginTop="8dp" android:layout_marginStart="24dp"
android:gravity="top" android:inputType="numberDecimal"
android:inputType="textMultiLine" android:textSize="20sp"
android:textColor="@color/white" android:hint="@string/amount"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/etAmount" /> app:layout_constraintTop_toBottomOf="@+id/tvToError" />
<View <TextView
android:id="@+id/viewSpinner" android:id="@+id/tvAmountError"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="1dp" android:layout_height="wrap_content"
android:layout_marginBottom="7dp" android:textColor="@color/red"
android:background="@color/darkGray" app:layout_constraintEnd_toEndOf="@+id/etAmount"
app:layout_constraintEnd_toEndOf="@+id/spAsset" app:layout_constraintStart_toStartOf="@+id/etAmount"
app:layout_constraintStart_toStartOf="@+id/spAsset" app:layout_constraintTop_toBottomOf="@+id/etAmount" />
app:layout_constraintBottom_toBottomOf="@id/etAmount" />
<TextView <Spinner
android:id="@+id/tvAssetError" android:id="@+id/spAsset"
android:layout_width="0dp" android:layout_width="150dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:layout_marginEnd="24dp"
app:layout_constraintBottom_toBottomOf="@+id/tvAmountError" android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/spAsset" android:gravity="top"
app:layout_constraintStart_toStartOf="@+id/spAsset" /> android:inputType="textMultiLine"
android:textColor="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/etAmount" />
<EditText <View
android:id="@+id/etMemo" android:id="@+id/viewSpinner"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="1dp"
android:layout_marginEnd="24dp" android:layout_marginBottom="7dp"
android:layout_marginStart="24dp" android:background="@color/darkGray"
android:layout_marginTop="8dp" app:layout_constraintEnd_toEndOf="@+id/spAsset"
android:inputType="textMultiLine" app:layout_constraintStart_toStartOf="@+id/spAsset"
android:hint="@string/memo_capital" app:layout_constraintBottom_toBottomOf="@id/etAmount" />
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvAmountError" />
<TextView <TextView
android:id="@+id/tvMemoError" android:id="@+id/tvAssetError"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/red" android:textColor="@color/red"
app:layout_constraintEnd_toEndOf="@+id/etMemo" app:layout_constraintBottom_toBottomOf="@+id/tvAmountError"
app:layout_constraintStart_toStartOf="@+id/etMemo" app:layout_constraintEnd_toEndOf="@+id/spAsset"
app:layout_constraintTop_toBottomOf="@+id/etMemo" /> app:layout_constraintStart_toStartOf="@+id/spAsset" />
<TextView <EditText
android:id="@+id/tvScan" android:id="@+id/etMemo"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginEnd="24dp"
android:layout_marginStart="24dp" android:layout_marginStart="24dp"
android:text="@string/scan_capital" android:layout_marginTop="8dp"
android:textSize="14sp" android:inputType="textMultiLine"
app:layout_constraintStart_toStartOf="parent" android:hint="@string/memo_capital"
app:layout_constraintTop_toBottomOf="@id/tvMemoError" /> android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvAmountError" />
<ImageView <TextView
android:id="@+id/ivCamera" android:id="@+id/tvMemoError"
android:layout_width="180dp" android:layout_width="0dp"
android:layout_height="180dp" android:layout_height="wrap_content"
android:layout_marginBottom="24dp" android:textColor="@color/red"
android:layout_marginStart="24dp" app:layout_constraintEnd_toEndOf="@+id/etMemo"
android:layout_marginTop="8dp" app:layout_constraintStart_toStartOf="@+id/etMemo"
android:src="#666" app:layout_constraintTop_toBottomOf="@+id/etMemo" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvScan"
android:contentDescription="@string/camera_feed_to_scan_qr" />
<android.support.design.widget.FloatingActionButton <TextView
android:id="@+id/fabCloseCamera" android:id="@+id/tvScan"
android:layout_width="30dp" android:layout_width="wrap_content"
android:layout_height="30dp" android:layout_height="wrap_content"
app:fabSize="mini" android:layout_marginTop="4dp"
android:layout_marginBottom="165dp" android:layout_marginStart="24dp"
android:layout_marginStart="165dp" android:text="@string/scan_capital"
app:backgroundTint="@color/send_strong_orange" android:textSize="14sp"
app:srcCompat="@drawable/ic_close" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/ivCamera" app:layout_constraintTop_toBottomOf="@id/tvMemoError" />
app:layout_constraintStart_toStartOf="@+id/ivCamera" />
<View <ImageView
android:id="@+id/viewSend" android:id="@+id/ivCamera"
android:layout_width="120dp" android:layout_width="180dp"
android:layout_height="140dp" android:layout_height="180dp"
android:layout_marginEnd="0dp" android:layout_marginBottom="24dp"
android:background="@drawable/send_transaction_send_view" android:layout_marginStart="24dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="8dp"
app:layout_constraintTop_toTopOf="@id/ivCamera" /> android:src="#666"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvScan"
android:contentDescription="@string/camera_feed_to_scan_qr" />
<android.support.design.widget.FloatingActionButton <android.support.design.widget.FloatingActionButton
android:id="@+id/btnSend" android:id="@+id/fabCloseCamera"
android:layout_width="90dp" android:layout_width="30dp"
android:layout_height="90dp" android:layout_height="30dp"
android:layout_marginTop="24dp" app:fabSize="mini"
app:backgroundTint="@color/send_strong_orange" android:layout_marginBottom="165dp"
app:srcCompat="@drawable/ic_arrow_forward" android:layout_marginStart="165dp"
app:layout_constraintEnd_toEndOf="parent" app:backgroundTint="@color/send_strong_orange"
app:layout_constraintTop_toTopOf="@+id/viewSend" /> app:srcCompat="@drawable/ic_close"
app:layout_constraintBottom_toBottomOf="@+id/ivCamera"
app:layout_constraintStart_toStartOf="@+id/ivCamera" />
<TextView <LinearLayout
android:id="@+id/btnCancel" android:layout_width="wrap_content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginBottom="600dp"
android:layout_marginEnd="24dp" android:layout_marginEnd="24dp"
android:text="@string/cancel_capital" android:layout_marginTop="20dp"
android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent"
android:textSize="18sp" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" android:padding="5dp">
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout> <TextView
android:id="@+id/btnCancel"
android:layout_width="20dp"
android:layout_height="26dp"
android:background="@drawable/ic_close"
android:text=""
android:textSize="18sp"
android:textStyle="bold" />
</ScrollView> </LinearLayout>
</android.support.constraint.ConstraintLayout>
</ScrollView>
<View
android:id="@+id/viewSend"
android:layout_width="120dp"
android:layout_height="140dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginTop="400dp"
android:background="@drawable/send_transaction_send_view" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/btnSend"
android:layout_width="90dp"
android:scaleX="1.7"
android:scaleY="1.7"
app:fabSize="normal"
android:layout_height="90dp"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginRight="30dp"
android:layout_marginTop="441dp"
android:scaleType="center"
app:backgroundTint="@color/send_strong_orange"
app:srcCompat="@drawable/ic_arrow_forward"/>
</RelativeLayout>

View File

@ -279,6 +279,8 @@
<string name="head_block_number">head_block_number</string> <string name="head_block_number">head_block_number</string>
<string name="e_receipt">e_receipt</string> <string name="e_receipt">e_receipt</string>
<string name="Creating_backup_from_file">Creating backup from file</string>
<string name="folder_name">SmartcoinsWallet</string> <string name="folder_name">SmartcoinsWallet</string>
<string name="login_api">{\"id\":1,\"method\":\"call\",\"params\":[1,\"login\",[\"\",\"\"]]}</string> <string name="login_api">{\"id\":1,\"method\":\"call\",\"params\":[1,\"login\",[\"\",\"\"]]}</string>
<string name="exchange_rate_params">{\"id\":7,\"method\":\"call\",\"params\":[1,\"get_limit_orders\",[\"1.3.0\",\"1.3.120\",1]]} <string name="exchange_rate_params">{\"id\":7,\"method\":\"call\",\"params\":[1,\"get_limit_orders\",[\"1.3.0\",\"1.3.120\",1]]}

View File

@ -11,5 +11,7 @@
<string name="network_err_no_server_connection" translatable="false">No server connection</string> <string name="network_err_no_server_connection" translatable="false">No server connection</string>
<string name="send_assets_error_invalid_cypto_coin_selected" translatable="false">Invalid crypto coin selected</string>
</resources> </resources>

View File

@ -11,6 +11,11 @@
<item name="android:windowContentTransitions">true</item> <item name="android:windowContentTransitions">true</item>
</style> </style>
<style name="dialog_theme_full" parent="android:Theme" >
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">false</item>
</style>
<style name="ActivityDialog" parent="Theme.AppCompat.Light.NoActionBar"> <style name="ActivityDialog" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item> <item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowBackground">@android:color/transparent</item>