From 82c32d4442fbbea34e8d7d3b9ca13fd8e32ac06f Mon Sep 17 00:00:00 2001 From: m2049r <30435443+m2049r@users.noreply.github.com> Date: Tue, 5 Dec 2017 07:48:59 +0100 Subject: [PATCH] support integrated address (excl. qr code) (#147) UI & code tweaks --- app/build.gradle | 4 +- .../xmrwallet/SendAddressWizardFragment.java | 59 ++++++++++++- .../xmrwallet/SendAmountWizardFragment.java | 2 +- .../xmrwallet/SendConfirmWizardFragment.java | 12 +-- ...SendFragmentNew.java => SendFragment.java} | 28 +++++-- .../com/m2049r/xmrwallet/WalletActivity.java | 10 +-- .../xmrwallet/layout/SpendViewPager.java | 6 +- .../main/res/drawable/ic_check_gray_24dp.xml | 9 ++ .../main/res/layout/fragment_send_address.xml | 82 ++++++++++++------- .../main/res/layout/fragment_send_amount.xml | 3 +- .../main/res/layout/fragment_send_confirm.xml | 24 ++++-- .../res/layout/fragment_send_settings.xml | 3 +- app/src/main/res/values/strings.xml | 10 ++- app/src/main/res/values/styles.xml | 4 + 14 files changed, 186 insertions(+), 70 deletions(-) rename app/src/main/java/com/m2049r/xmrwallet/{SendFragmentNew.java => SendFragment.java} (96%) create mode 100644 app/src/main/res/drawable/ic_check_gray_24dp.xml diff --git a/app/build.gradle b/app/build.gradle index d2d2d43..b940521 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 25 - versionCode 46 - versionName "1.2.6-alpha" + versionCode 47 + versionName "1.2.7-alpha" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { diff --git a/app/src/main/java/com/m2049r/xmrwallet/SendAddressWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/SendAddressWizardFragment.java index 4310a9f..085da6f 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/SendAddressWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/SendAddressWizardFragment.java @@ -41,6 +41,8 @@ import timber.log.Timber; public class SendAddressWizardFragment extends SendWizardFragment { + static final int INTEGRATED_ADDRESS_LENGTH = 106; + public static SendAddressWizardFragment newInstance(Listener listener) { SendAddressWizardFragment instance = new SendAddressWizardFragment(); instance.setSendListener(listener); @@ -67,6 +69,8 @@ public class SendAddressWizardFragment extends SendWizardFragment { private TextInputLayout etPaymentId; private Button bPaymentId; private CardView cvScan; + private View tvPaymentIdIntegrated; + private View llPaymentId; private String scannedAmount = null; @@ -85,8 +89,50 @@ public class SendAddressWizardFragment extends SendWizardFragment { View view = inflater.inflate(R.layout.fragment_send_address, container, false); + tvPaymentIdIntegrated = view.findViewById(R.id.tvPaymentIdIntegrated); + llPaymentId = view.findViewById(R.id.llPaymentId); + etAddress = (TextInputLayout) view.findViewById(R.id.etAddress); etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); + etAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { + if (checkAddress()) { + if (llPaymentId.getVisibility() == View.VISIBLE) { + etPaymentId.requestFocus(); + } else { + etDummy.requestFocus(); + Helper.hideKeyboard(getActivity()); + } + } + return true; + } + return false; + } + }); + etAddress.getEditText().addTextChangedListener(new TextWatcher() { + @Override + public void afterTextChanged(Editable editable) { + if ((etAddress.getEditText().getText().toString().length() == INTEGRATED_ADDRESS_LENGTH) && + checkAddressNoError()) { // we have an integrated address + etPaymentId.getEditText().getText().clear(); + llPaymentId.setVisibility(View.GONE); + tvPaymentIdIntegrated.setVisibility(View.VISIBLE); + } else { // we don't + llPaymentId.setVisibility(View.VISIBLE); + tvPaymentIdIntegrated.setVisibility(View.GONE); + } + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + } + }); + etPaymentId = (TextInputLayout) view.findViewById(R.id.etPaymentId); etPaymentId.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); @@ -157,13 +203,24 @@ public class SendAddressWizardFragment extends SendWizardFragment { return ok; } + private boolean isIntegratedAddress() { + String address = etAddress.getEditText().getText().toString(); + return Wallet.isAddressValid(address, WalletManager.getInstance().isTestNet()) + && address.length() == 106; + } + private boolean checkPaymentId() { String paymentId = etPaymentId.getEditText().getText().toString(); boolean ok = paymentId.isEmpty() || Wallet.isPaymentIdValid(paymentId); if (!ok) { etPaymentId.setError(getString(R.string.receive_paymentid_invalid)); } else { - etPaymentId.setError(null); + if (!paymentId.isEmpty() && isIntegratedAddress()) { + ok = false; + etPaymentId.setError(getString(R.string.receive_integrated_paymentid_invalid)); + } else { + etPaymentId.setError(null); + } } return ok; } diff --git a/app/src/main/java/com/m2049r/xmrwallet/SendAmountWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/SendAmountWizardFragment.java index c82e2af..f414041 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/SendAmountWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/SendAmountWizardFragment.java @@ -46,7 +46,7 @@ public class SendAmountWizardFragment extends SendWizardFragment { } interface Listener { - SendFragmentNew.Listener getActivityCallback(); + SendFragment.Listener getActivityCallback(); void setAmount(final long amount); diff --git a/app/src/main/java/com/m2049r/xmrwallet/SendConfirmWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/SendConfirmWizardFragment.java index 0c37901..2d779b0 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/SendConfirmWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/SendConfirmWizardFragment.java @@ -53,7 +53,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment { } interface Listener { - SendFragmentNew.Listener getActivityCallback(); + SendFragment.Listener getActivityCallback(); TxData getTxData(); @@ -70,7 +70,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment { private TextView tvTxAmount; private TextView tvTxFee; private TextView tvTxTotal; - private View pbProgress; + private View llProgress; private View bSend; private View llConfirmSend; private View pbProgressSend; @@ -91,7 +91,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment { tvTxFee = (TextView) view.findViewById(R.id.tvTxFee); tvTxTotal = (TextView) view.findViewById(R.id.tvTxTotal); - pbProgress = view.findViewById(R.id.pbProgress); + llProgress = view.findViewById(R.id.llProgress); pbProgressSend = view.findViewById(R.id.pbProgressSend); llConfirmSend = view.findViewById(R.id.llConfirmSend); @@ -111,12 +111,12 @@ public class SendConfirmWizardFragment extends SendWizardFragment { boolean inProgress = false; public void hideProgress() { - pbProgress.setVisibility(View.INVISIBLE); + llProgress.setVisibility(View.INVISIBLE); inProgress = false; } public void showProgress() { - pbProgress.setVisibility(View.VISIBLE); + llProgress.setVisibility(View.VISIBLE); inProgress = true; } @@ -300,7 +300,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment { getActivityCallback().onPrepareSend(txData); } - SendFragmentNew.Listener getActivityCallback() { + SendFragment.Listener getActivityCallback() { return sendListener.getActivityCallback(); } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/SendFragmentNew.java b/app/src/main/java/com/m2049r/xmrwallet/SendFragment.java similarity index 96% rename from app/src/main/java/com/m2049r/xmrwallet/SendFragmentNew.java rename to app/src/main/java/com/m2049r/xmrwallet/SendFragment.java index 56aeba8..8c2f7a2 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/SendFragmentNew.java +++ b/app/src/main/java/com/m2049r/xmrwallet/SendFragment.java @@ -49,7 +49,7 @@ import java.lang.ref.WeakReference; import timber.log.Timber; -public class SendFragmentNew extends Fragment +public class SendFragment extends Fragment implements SendAddressWizardFragment.Listener, SendAmountWizardFragment.Listener, SendSettingsWizardFragment.Listener, @@ -281,15 +281,15 @@ public class SendFragmentNew extends Fragment Timber.d("getItem(%d) CREATE", position); switch (position) { case POS_ADDRESS: - return SendAddressWizardFragment.newInstance(SendFragmentNew.this); + return SendAddressWizardFragment.newInstance(SendFragment.this); case POS_AMOUNT: - return SendAmountWizardFragment.newInstance(SendFragmentNew.this); + return SendAmountWizardFragment.newInstance(SendFragment.this); case POS_SETTINGS: - return SendSettingsWizardFragment.newInstance(SendFragmentNew.this); + return SendSettingsWizardFragment.newInstance(SendFragment.this); case POS_CONFIRM: - return SendConfirmWizardFragment.newInstance(SendFragmentNew.this); + return SendConfirmWizardFragment.newInstance(SendFragment.this); case POS_SUCCESS: - return SendSuccessWizardFragment.newInstance(SendFragmentNew.this); + return SendSuccessWizardFragment.newInstance(SendFragment.this); default: throw new IllegalArgumentException("no such send position(" + position + ")"); } @@ -448,8 +448,8 @@ public class SendFragmentNew extends Fragment confirmFragment.hideProgress(); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - builder.setCancelable(false). - setTitle(getString(R.string.send_error_title)). + builder.setCancelable(true). + setTitle(getString(R.string.send_create_tx_error_title)). setMessage(errorText). create(). show(); @@ -483,4 +483,16 @@ public class SendFragmentNew extends Fragment fragment.sendFailed(); } } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.send_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java index 2a8dd46..21fa397 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java @@ -53,7 +53,7 @@ import java.util.Map; import timber.log.Timber; public class WalletActivity extends SecureActivity implements WalletFragment.Listener, - WalletService.Observer, SendFragmentNew.Listener, TxFragment.Listener, + WalletService.Observer, SendFragment.Listener, TxFragment.Listener, GenerateReviewFragment.ListenerWithWallet, GenerateReviewFragment.Listener, ScannerFragment.OnScannedListener, ReceiveFragment.Listener, @@ -360,7 +360,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis @Override public void onSendRequest() { - replaceFragment(new SendFragmentNew(), null, null); + replaceFragment(new SendFragment(), null, null); } @Override @@ -463,7 +463,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis @Override public void onTransactionCreated(final PendingTransaction pendingTransaction) { try { - final SendFragmentNew sendFragment = (SendFragmentNew) + final SendFragment sendFragment = (SendFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container); runOnUiThread(new Runnable() { public void run() { @@ -488,7 +488,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis @Override public void onSendTransactionFailed(final String error) { try { - final SendFragmentNew sendFragment = (SendFragmentNew) + final SendFragment sendFragment = (SendFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container); runOnUiThread(new Runnable() { public void run() { @@ -504,7 +504,7 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis @Override public void onTransactionSent(final String txId) { try { - final SendFragmentNew sendFragment = (SendFragmentNew) + final SendFragment sendFragment = (SendFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container); runOnUiThread(new Runnable() { public void run() { diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/SpendViewPager.java b/app/src/main/java/com/m2049r/xmrwallet/layout/SpendViewPager.java index e67d72d..4fee6b3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/SpendViewPager.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/SpendViewPager.java @@ -21,9 +21,7 @@ import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.MotionEvent; -import com.m2049r.xmrwallet.SendFragmentNew; - -import timber.log.Timber; +import com.m2049r.xmrwallet.SendFragment; public class SpendViewPager extends ViewPager { @@ -57,7 +55,7 @@ public class SpendViewPager extends ViewPager { } public boolean validateFields(int position) { - OnValidateFieldsListener c = ((SendFragmentNew.SpendPagerAdapter) getAdapter()).getFragment(position); + OnValidateFieldsListener c = ((SendFragment.SpendPagerAdapter) getAdapter()).getFragment(position); return c.onValidateFields(); } diff --git a/app/src/main/res/drawable/ic_check_gray_24dp.xml b/app/src/main/res/drawable/ic_check_gray_24dp.xml new file mode 100644 index 0000000..ded46cf --- /dev/null +++ b/app/src/main/res/drawable/ic_check_gray_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_send_address.xml b/app/src/main/res/layout/fragment_send_address.xml index 49ed3a3..88577fe 100644 --- a/app/src/main/res/layout/fragment_send_address.xml +++ b/app/src/main/res/layout/fragment_send_address.xml @@ -26,45 +26,65 @@ android:textAlignment="textStart" /> - + android:layout_height="96dp" + android:layout_marginBottom="4dp"> - + android:layout_gravity="start|center_vertical" + android:drawablePadding="8dp" + android:drawableStart="@drawable/ic_check_gray_24dp" + android:gravity="center" + android:text="@string/info_paymentid_intergrated" + android:textSize="18sp" + android:visibility="gone" /> - + + - + app:counterEnabled="true" + app:counterMaxLength="16" + app:errorEnabled="true"> -