Compare commits

...

11 Commits

Author SHA1 Message Date
Severiano Jaramillo b12b3b9546 Remove the eula from the strings and placed it instead as a file into the Assets folder.
We found that using the loadUrl WebView's method instead of loadData renders the html page better, for that reason the eula is now saved as a fule in the assets folder and loaded using the WebView's loadUrl method.
2019-01-02 14:29:29 -06:00
Javier Varona d04e847bba Merge branch 'develop' of https://github.com/agorise/crystal-wallet-android into develop 2018-11-30 21:55:46 -04:00
Javier Varona fe1068bcdf - Fixed bitshares QR scan won't load the amount 2018-11-30 21:54:54 -04:00
Severiano Jaramillo af4a4aca8b Merge branch 'develop' of github.com:Agorise/crystal-wallet-android into develop 2018-11-30 19:51:11 -06:00
Severiano Jaramillo 450a7c285b Increase the camera preview area to improve the QR read performance and make some UI improvements. 2018-11-30 19:49:40 -06:00
hvarona 08df53730b Fix send bad request
Change Send manager to send only the required amount from gtxio
added error capture for estimatefee
2018-11-30 20:58:13 -04:00
Severiano Jaramillo 618e71a6ac Fix FloatingActionButtons used in SendTransactionFragment and BoardActivity, after the migration to the new MaterialComponents they got messed up because the way they are designed in XML and its properties changed a bit. 2018-11-30 11:52:53 -06:00
Severiano Jaramillo 52f75eb3cf Make the area that shows the camera feed to always be a square. The camera feed still has a 3:4 aspect ratio but there is a black square behind it that creates the always square illusion. 2018-11-30 11:29:27 -06:00
Severiano Jaramillo 4bf1c14bb8 Temporarily remove AnimatedTabLayout library. 2018-11-29 21:06:36 -06:00
Severiano Jaramillo a32f7c9eb0 Merge branch 'develop' of github.com:Agorise/crystal-wallet-android into develop 2018-11-29 12:23:24 -06:00
hvarona 2c431ef4e0 Fix BitocinGtxIO Foreign Key Definition 2018-11-28 23:42:56 -04:00
15 changed files with 173 additions and 195 deletions

View File

@ -87,8 +87,6 @@ dependencies {
implementation 'com.github.bilthon:graphenej:0.4.6'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'com.github.sjaramillo10:AnimatedTabLayout:1.0.3'
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
implementation 'de.hdodenhof:circleimageview:2.2.0'

File diff suppressed because one or more lines are too long

View File

@ -70,12 +70,7 @@ public class LicenseActivity extends AppCompatActivity {
finish();
}
else{
/*
* Load the licence only if it is necesarry
* */
String html = getString(R.string.licence_html);
wvEULA.loadData(html, "text/html", "UTF-8");
wvEULA.loadUrl("file:///android_asset/crystal_eula.html");
}
}

View File

@ -1,22 +1,19 @@
package cy.agorise.crystalwallet.activities;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.sjaramillo10.animatedtablayout.AnimatedTabLayout;
import butterknife.BindView;
import butterknife.ButterKnife;
@ -37,7 +34,7 @@ public class SettingsActivity extends AppCompatActivity{
public ImageView ivGoBack;
@BindView(R.id.tabLayout)
public AnimatedTabLayout tabLayout;
public TabLayout tabLayout;
@BindView(R.id.pager)
public ViewPager mPager;

View File

@ -35,14 +35,18 @@ public abstract class GetEstimateFee {
call.enqueue(new Callback<JsonObject>() {
@Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
try {
listener.estimateFee((double) (response.body().get("2").getAsDouble()));
}catch (Exception e){
e.printStackTrace();
listener.fail();
}
}
@Override
public void onFailure(Call<JsonObject> call, Throwable t) {
listener.fail();
listener.estimateFee(-1);
}
});
}catch(Exception e){

View File

@ -97,8 +97,8 @@ class InsightApiServiceGenerator {
return chain.proceed(request);
}
});
sClientBuilder.readTimeout(5, TimeUnit.MINUTES);
sClientBuilder.connectTimeout(5, TimeUnit.MINUTES);
sClientBuilder.readTimeout(30, TimeUnit.SECONDS);
sClientBuilder.connectTimeout(30, TimeUnit.SECONDS);
OkHttpClient client = sClientBuilder.build();
Retrofit retrofit = sBuilder.client(client).build();
return retrofit.create(serviceClass);

View File

@ -52,8 +52,8 @@ public class CrystalApplication extends Application {
public static final String BITCOIN_SERVER_URLS[] ={
"https://testnet.blockexplorer.com/",
"https://test-insight.bitpay.com",
//"https://testnet.blockexplorer.com/",
//"https://insight.bitpay.com/"
};

View File

@ -28,8 +28,6 @@ import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
@ -129,9 +127,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
@BindView(R.id.gravatar)
CircularImageView userImg;
@BindView(R.id.viewCamera)
View viewCamera;
/* Flag to control when the camera is visible and when is hidden */
private boolean cameraVisible = false;
@ -142,9 +137,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
private FloatingActionButton fabSend;
private AlertDialog.Builder builder;
/*
Dialog for loading
*/
/* Dialog for loading */
private CrystalDialog crystalDialog;
public static SendTransactionFragment newInstance(long cryptoNetAccountId) {
@ -171,7 +164,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
//AlertDialog.Builder
builder = new AlertDialog.Builder(getActivity(), R.style.dialog_theme_full);
//builder.setTitle("Send");
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.send_transaction, null);
@ -179,11 +171,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
this.cryptoNetAccountId = getArguments().getLong("CRYPTO_NET_ACCOUNT_ID",-1);
final Activity activity = getActivity();
/*
* Add style to the spinner android
* */
/* Add style to the spinner android */
spFrom.setBackground(getContext().getDrawable(R.drawable.square_color));
if (this.cryptoNetAccountId != -1) {
@ -194,36 +182,10 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
List<CryptoNetAccount> cryptoNetAccounts = cryptoNetAccountListViewModel.getCryptoNetAccountList();
CryptoNetAccountAdapter fromSpinnerAdapter = new CryptoNetAccountAdapter(this.getContext(), android.R.layout.simple_spinner_item, cryptoNetAccounts);
/*
* If only one account block the control
* */
//if(cryptoNetAccounts.size()==1){
// spFrom.setEnabled(false);
//}
spFrom.setAdapter(fromSpinnerAdapter);
spFrom.setSelection(0);
setAccountUI();
/*
* Custom material spinner implementation
* */
//spFrom.setItems(cryptoNetAccounts);
//spFrom.setSelectedIndex(0);
//spFrom.setOnItemSelectedListener(new MaterialSpinner.OnItemSelectedListener<CryptoNetAccount>() {
// @Override
// public void onItemSelected(MaterialSpinner view, int position, long id, CryptoNetAccount item) {
// sendTransactionValidator.validate();
// }
//});
//spFrom.setOnNothingSelectedListener(new MaterialSpinner.OnNothingSelectedListener() {
// @Override public void onNothingSelected(MaterialSpinner spinner) {
// }
//});
// etFrom.setText(this.grapheneAccount.getName());
}
loadUserImage();
@ -264,7 +226,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
//cryptoCurrencyList.add(crypto1);
CryptoCurrencyAdapter assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
assetAdapter = new CryptoCurrencyAdapter(getContext(), android.R.layout.simple_spinner_item, cryptoCurrencyList);
spAsset.setAdapter(assetAdapter);
}
});
@ -340,12 +302,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this);
mScannerView.startCamera();
// Force dialog fragment to use the full width of the screen
Window dialogWindow = getDialog().getWindow();
assert dialogWindow != null;
dialogWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
loadUserImage();
}
@ -421,7 +378,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
* */
private void showCamera(){
/* Change visibilities of views */
viewCamera.setVisibility(View.GONE);
mScannerView.setVisibility(View.VISIBLE);
/* Change icon */
@ -440,7 +396,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
* */
private void hideCamera(){
/* Change visibilities of views */
viewCamera.setVisibility(View.VISIBLE);
mScannerView.setVisibility(View.INVISIBLE);
/* Change icon */
@ -516,10 +471,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
if (fromAccountSelected.getCryptoNet() == CryptoNet.BITSHARES) {
/*
* this is only for graphene accounts.
*
**/
/* This is only for graphene accounts. */
GrapheneAccount grapheneAccountSelected = new GrapheneAccount(fromAccountSelected);
grapheneAccountSelected.loadInfo(db.grapheneAccountInfoDao().getByAccountId(fromAccountSelected.getId()));
@ -550,6 +502,7 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace();
}
} else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
}
}
@ -582,22 +535,19 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
throwable.printStackTrace();
}
} else {
crystalDialog.dismiss();
Toast.makeText(getContext(), getContext().getString(R.string.unable_to_send_amount), Toast.LENGTH_LONG);
}
}
});
}
/*
* If exists mode scurity show it and valide events in case of success or fail
* */
/* If exists mode security show it and validate events in case of success or fail */
CrystalSecurityMonitor.getInstance(this.getActivity()).callPasswordRequest(this.getActivity(), new OnResponse() {
@Override
public void onSuccess() {
/*
* Show loading dialog
* */
/* Show loading dialog */
crystalDialog = new CrystalDialog((Activity) getContext());
crystalDialog.setText("Sending");
crystalDialog.progress();
@ -628,10 +578,6 @@ public class SendTransactionFragment extends DialogFragment implements UIValidat
// Camera Permissions
private static final int REQUEST_CAMERA_PERMISSION = 1;
private static String[] PERMISSIONS_CAMERA = {
Manifest.permission.CAMERA
};
@Override
public void onValidationSucceeded(final ValidationField field) {

View File

@ -241,11 +241,12 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setAccountId(address.getAccountId());
ccTransaction.setFrom(addr);
ccTransaction.setInput(false);
amount -= (long) (txi.fee * Math.pow(10, cryptoCoin.getPrecision()));
}
if (ccTransaction.getAccountId() == address.getAccountId()) {
//if (ccTransaction.getAccountId() == address.getAccountId()) {
amount -= (long) (vin.value * Math.pow(10, cryptoCoin.getPrecision()));
}
//}
}
if (ccTransaction.getFrom() == null || ccTransaction.getFrom().isEmpty()) {
@ -280,9 +281,9 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
ccTransaction.setTo(addr);
}
if (ccTransaction.getAccountId() == address.getAccountId()) {
//if (ccTransaction.getAccountId() == address.getAccountId()) {
amount += (long) (vout.value * Math.pow(10, cryptoCoin.getPrecision()));
}
//}
} else {
//TOOD multiple send address
if (ccTransaction.getTo() == null || ccTransaction.getTo().isEmpty()) {
@ -309,7 +310,7 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
btTransaction.setCryptoCoinTransactionId(ccId);
long btId = db.bitcoinTransactionDao().insertBitcoinTransaction(btTransaction)[0];
for (BitcoinTransactionGTxIO gtxio : gtxios) {
gtxio.setBitcoinTransactionId(btId);
gtxio.setBitcoinTransactionId(ccId);
db.bitcoinTransactionDao().insertBitcoinTransactionGTxIO(gtxio);
}
@ -374,39 +375,52 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
//TODO check server connection
//TODO validate to address
System.out.println("GeneralAccount Manager Send request, asking fee");
InsightApiGenerator.getEstimateFee(this.cryptoCoin,new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
Transaction tx = new Transaction(cryptoCoin.getParameters());
long currentAmount = 0;
long fee = -1;
long feeRate = (long)(((double)answer) * Math.pow(10,cryptoCoin.getPrecision()));
fee = 226 * feeRate;
System.out.println("GeneralAccount Manager Send request, fee " + answer.toString());
try {
Transaction tx = new Transaction(cryptoCoin.getParameters());
long currentAmount = 0;
long fee = -1;
long feeRate = (long) (((double) answer) * Math.pow(10, cryptoCoin.getPrecision()));
fee = 226 * feeRate;
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
System.out.println("GeneralAccount Manager Send request getting utxos" );
CrystalDatabase db = CrystalDatabase.getAppDatabase(request.getContext());
db.bitcoinTransactionDao();
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(),db);
List<BitcoinTransactionGTxIO> utxos = getUtxos(request.getSourceAccount().getId(), db);
System.out.println("GeneralAccount Manager Send request utxos found " + utxos.size() );
for(BitcoinTransactionGTxIO utxo : utxos){
currentAmount += utxo.getAmount();
if(currentAmount >= request.getAmount() + fee) {
break;
}
}
if(currentAmount< request.getAmount() + fee){
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
return;
}
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
if (currentAmount < request.getAmount() + fee) {
System.out.println("GeneralAccount Manager Send request no balance" );
request.setStatus(BitcoinSendRequest.StatusCode.NO_BALANCE);
return;
}
//String to an address
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount());
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
AccountSeed seed = db.accountSeedDao().findById(request.getSourceAccount().getSeedId());
DeterministicKey purposeKey = HDKeyDerivation.deriveChildKey((DeterministicKey) seed.getPrivateKey(),
new ChildNumber(44, true));
DeterministicKey coinKey = HDKeyDerivation.deriveChildKey(purposeKey,
new ChildNumber(cryptoCoin.getCoinNumber(), true));
DeterministicKey accountKey = HDKeyDerivation.deriveChildKey(coinKey,
new ChildNumber(request.getSourceAccount().getAccountIndex(), true));
DeterministicKey externalKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(0, false));
DeterministicKey changeKey = HDKeyDerivation.deriveChildKey(accountKey,
new ChildNumber(1, false));
//String to an address
Address toAddr = Address.fromBase58(cryptoCoin.getParameters(), request.getToAccount());
tx.addOutput(Coin.valueOf(request.getAmount()), toAddr);
/*if(request.getMemo()!= null && !request.getMemo().isEmpty()){
String memo = request.getMemo();
@ -421,62 +435,74 @@ public class GeneralAccountManager implements CryptoAccountManager, CryptoNetInf
tx.addOutput(Coin.valueOf(0),memoScript);
}*/
//Change address
long remain = currentAmount - request.getAmount() - fee;
if( remain > 0 ) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if(btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size()<=0){
//Change address
long remain = currentAmount - request.getAmount() - fee;
if (remain > 0) {
long index = db.bitcoinAddressDao().getLastChangeAddress(request.getSourceAccount().getId());
BitcoinAddress btAddress = db.bitcoinAddressDao().getChangeByIndex(index);
Address changeAddr;
if (btAddress != null && db.bitcoinTransactionDao().getGtxIOByAddress(btAddress.getAddress()).size() <= 0) {
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
}else{
if(btAddress == null){
index = 0;
}else{
index++;
} else {
if (btAddress == null) {
index = 0;
} else {
index++;
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
}
btAddress = new BitcoinAddress();
btAddress.setIndex(index);
btAddress.setAccountId(request.getSourceAccount().getId());
btAddress.setChange(true);
btAddress.setAddress(HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false)).toAddress(cryptoCoin.getParameters()).toString());
db.bitcoinAddressDao().insertBitcoinAddresses(btAddress);
changeAddr = Address.fromBase58(cryptoCoin.getParameters(), btAddress.getAddress());
tx.addOutput(Coin.valueOf(remain), changeAddr);
}
tx.addOutput(Coin.valueOf(remain), changeAddr);
for (BitcoinTransactionGTxIO utxo : utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey;
if (btAddress.isChange()) {
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
} else {
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
currentAmount -= utxo.getAmount();
if(currentAmount<= 0){
break;
}
}
System.out.println("GeneralAccount Manager Send request rawtx " +Util.bytesToHex(tx.bitcoinSerialize()) );
InsightApiGenerator.broadcastTransaction(cryptoCoin, Util.bytesToHex(tx.bitcoinSerialize()), new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
System.out.println("GeneralAccount MAnager succed send");
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
System.out.println("GeneralAccount MAnager succed fail");
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
}catch(Exception e){
System.out.println("GeneralAccount Manager Send request error ");
e.printStackTrace();
}
for(BitcoinTransactionGTxIO utxo: utxos) {
Sha256Hash txHash = Sha256Hash.wrap(utxo.getOriginalTxId());
Script script = new Script(Util.hexToBytes(utxo.getScriptHex()));
TransactionOutPoint outPoint = new TransactionOutPoint(cryptoCoin.getParameters(), utxo.getIndex(), txHash);
BitcoinAddress btAddress = db.bitcoinAddressDao().getdadress(utxo.getAddress());
ECKey addrKey;
if(btAddress.isChange()){
addrKey = HDKeyDerivation.deriveChildKey(changeKey, new ChildNumber((int) btAddress.getIndex(), false));
}else{
addrKey = HDKeyDerivation.deriveChildKey(externalKey, new ChildNumber((int) btAddress.getIndex(), true));
}
tx.addSignedInput(outPoint, script, addrKey, Transaction.SigHash.ALL, true);
}
InsightApiGenerator.broadcastTransaction(cryptoCoin,Util.bytesToHex(tx.bitcoinSerialize()),new ApiRequest(1, new ApiRequestListener() {
@Override
public void success(Object answer, int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.SUCCEEDED);
}
@Override
public void fail(int idPetition) {
request.setStatus(BitcoinSendRequest.StatusCode.PETITION_FAILED);
}
}));
}
@Override
public void fail(int idPetition) {
System.out.println("GeneralAccount Manager Send request fee fail" );
request.setStatus(BitcoinSendRequest.StatusCode.NO_FEE);
}

View File

@ -14,8 +14,8 @@ import android.arch.persistence.room.ForeignKey;
primaryKeys = {"bitcoin_transaction_id", "io_index", "is_output"},
foreignKeys = {
@ForeignKey(
entity = BitcoinTransaction.class,
parentColumns = "crypto_coin_transaction_id",
entity = CryptoCoinTransaction.class,
parentColumns = "id",
childColumns = "bitcoin_transaction_id",
onDelete = ForeignKey.CASCADE
)

View File

@ -89,7 +89,7 @@ public class BitcoinSendRequest extends CryptoNetInfoRequest {
public void setStatus(StatusCode code){
this.status = code;
this._fireOnCarryOutEvent();
this.validate();
}
public StatusCode getStatus() {

View File

@ -79,13 +79,12 @@
</android.support.v7.widget.Toolbar>
<com.sjaramillo10.animatedtablayout.AnimatedTabLayout
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
app:tabBoldText="true"
app:tabMode="fixed" />
</RelativeLayout>

View File

@ -96,7 +96,7 @@
</android.support.v7.widget.Toolbar>
<com.sjaramillo10.animatedtablayout.AnimatedTabLayout
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_gravity="bottom"
android:background="@color/transparent"
@ -124,21 +124,25 @@
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabReceive"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start|bottom"
android:layout_marginBottom="-125dp"
android:layout_marginStart="-125dp"
app:fabCustomSize="250dp"
app:maxImageSize="200dp"
app:backgroundTint="@color/white"
app:srcCompat="@drawable/receive_icon" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabSend"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_marginBottom="-125dp"
android:layout_marginEnd="-125dp"
app:fabCustomSize="250dp"
app:maxImageSize="200dp"
app:backgroundTint="@color/white"
app:srcCompat="@drawable/send_icon" />

View File

@ -18,6 +18,13 @@
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5"/>
<android.support.constraint.Guideline
android:id="@+id/cameraVerticalGuideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.65"/>
<View
android:id="@+id/topView"
android:layout_width="match_parent"
@ -206,13 +213,26 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvMemoError" />
<View
android:id="@+id/viewCamera"
android:background="@color/black"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:visibility="visible"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintTop_toBottomOf="@+id/tvScan"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/cameraVerticalGuideline"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fabCloseCamera"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="@color/send_strong_orange"
app:fabSize="mini"
app:layout_constraintStart_toEndOf="@id/centeredVerticalGuideline"
app:fabCustomSize="32dp"
app:layout_constraintStart_toEndOf="@id/cameraVerticalGuideline"
app:layout_constraintTop_toBottomOf="@+id/tvScan"
app:srcCompat="@drawable/ok" />
@ -220,26 +240,12 @@
android:id="@+id/ivCamera"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/camera_feed_to_scan_qr"
android:src="#666"
app:layout_constraintDimensionRatio="h,3:4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/centeredVerticalGuideline"
app:layout_constraintTop_toTopOf="@+id/fabCloseCamera" />
<View
android:id="@+id/viewCamera"
android:background="@color/black"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="visible"
android:src="#666"
app:layout_constraintTop_toTopOf="@id/ivCamera"
app:layout_constraintStart_toStartOf="@id/ivCamera"
app:layout_constraintEnd_toEndOf="@id/ivCamera"
app:layout_constraintBottom_toBottomOf="@+id/ivCamera"/>
app:layout_constraintDimensionRatio="w,3:4"
app:layout_constraintTop_toTopOf="@+id/viewCamera"
app:layout_constraintBottom_toBottomOf="@id/viewCamera"
app:layout_constraintStart_toStartOf="@id/viewCamera"
app:layout_constraintEnd_toEndOf="@id/viewCamera" />
<View
android:id="@+id/viewSend"
@ -248,13 +254,16 @@
android:layout_marginEnd="0dp"
android:background="@drawable/send_transaction_send_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/ivCamera" />
app:layout_constraintTop_toTopOf="@id/viewCamera"
app:layout_constraintBottom_toBottomOf="@id/viewCamera"/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/btnSend"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:fabCustomSize="90dp"
app:maxImageSize="70dp"
app:backgroundTint="@color/send_strong_orange"
app:srcCompat="@drawable/ic_arrow_forward"
app:layout_constraintEnd_toEndOf="parent"

File diff suppressed because one or more lines are too long