diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/dialog/SendBottomSheetDialog.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/dialog/SendBottomSheetDialog.java index e64b9a9..b197992 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/dialog/SendBottomSheetDialog.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/dialog/SendBottomSheetDialog.java @@ -1,8 +1,11 @@ package com.m2049r.xmrwallet.fragment.dialog; +import android.app.Activity; +import android.os.AsyncTask; import android.os.Bundle; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.m2049r.xmrwallet.R; +import com.m2049r.xmrwallet.model.PendingTransaction; import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.service.BalanceService; import com.m2049r.xmrwallet.service.TxService; @@ -25,6 +28,19 @@ import androidx.lifecycle.MutableLiveData; public class SendBottomSheetDialog extends BottomSheetDialogFragment { private MutableLiveData _sendingMax = new MutableLiveData<>(false); public LiveData sendingMax = _sendingMax; + private MutableLiveData _pendingTransaction = new MutableLiveData<>(null); + public LiveData pendingTransaction = _pendingTransaction; + + private EditText addressEditText; + private EditText amountEditText; + private TextView sendAllTextView; + private TextView feeTextView; + private TextView addressTextView; + private TextView amountTextView; + private Button createButton; + private Button sendButton; + private Button sendMaxButton; + private ImageButton pasteAddressImageButton; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -34,12 +50,16 @@ public class SendBottomSheetDialog extends BottomSheetDialogFragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - ImageButton pasteAddressImageButton = view.findViewById(R.id.paste_address_imagebutton); - Button sendMaxButton = view.findViewById(R.id.send_max_button); - EditText addressEditText = view.findViewById(R.id.address_edittext); - EditText amountEditText = view.findViewById(R.id.amount_edittext); - Button sendButton = view.findViewById(R.id.send_button); - TextView sendAllTextView = view.findViewById(R.id.sending_all_textview); + pasteAddressImageButton = view.findViewById(R.id.paste_address_imagebutton); + sendMaxButton = view.findViewById(R.id.send_max_button); + addressEditText = view.findViewById(R.id.address_edittext); + amountEditText = view.findViewById(R.id.amount_edittext); + sendButton = view.findViewById(R.id.send_tx_button); + createButton = view.findViewById(R.id.create_tx_button); + sendAllTextView = view.findViewById(R.id.sending_all_textview); + feeTextView = view.findViewById(R.id.fee_textview); + addressTextView = view.findViewById(R.id.address_pending_textview); + amountTextView = view.findViewById(R.id.amount_pending_textview); pasteAddressImageButton.setOnClickListener(view1 -> { addressEditText.setText(Helper.getClipBoardText(view.getContext())); @@ -50,7 +70,7 @@ public class SendBottomSheetDialog extends BottomSheetDialogFragment { _sendingMax.postValue(!currentValue); }); - sendButton.setOnClickListener(view1 -> { + createButton.setOnClickListener(view1 -> { boolean sendAll = sendingMax.getValue() != null ? sendingMax.getValue() : false; String address = addressEditText.getText().toString().trim(); String amount = amountEditText.getText().toString().trim(); @@ -62,13 +82,9 @@ public class SendBottomSheetDialog extends BottomSheetDialogFragment { Toast.makeText(getActivity(), getString(R.string.send_amount_invalid), Toast.LENGTH_SHORT).show(); return; } - sendButton.setEnabled(false); - boolean success = TxService.getInstance().sendTx(address, amount, sendAll); - if(success) { - dismiss(); - } else { - Toast.makeText(getActivity(), getString(R.string.error_sending_tx), Toast.LENGTH_SHORT).show(); - } + Toast.makeText(getActivity(), getString(R.string.creating_tx), Toast.LENGTH_SHORT).show(); + createButton.setEnabled(false); + createTx(address, amount, sendAll); } else if (!validAddress) { Toast.makeText(getActivity(), getString(R.string.send_address_invalid), Toast.LENGTH_SHORT).show(); } else { @@ -76,16 +92,99 @@ public class SendBottomSheetDialog extends BottomSheetDialogFragment { } }); + sendButton.setOnClickListener(view1 -> { + PendingTransaction pendingTx = pendingTransaction.getValue(); + if(pendingTx != null) { + Toast.makeText(getActivity(), getString(R.string.sending_tx), Toast.LENGTH_SHORT).show(); + sendButton.setEnabled(false); + sendTx(pendingTx); + } + }); + sendingMax.observe(getViewLifecycleOwner(), sendingMax -> { - if(sendingMax) { - amountEditText.setVisibility(View.INVISIBLE); - sendAllTextView.setVisibility(View.VISIBLE); - sendMaxButton.setText(getText(R.string.undo)); - } else { - amountEditText.setVisibility(View.VISIBLE); - sendAllTextView.setVisibility(View.GONE); - sendMaxButton.setText(getText(R.string.send_max)); + if(pendingTransaction.getValue() == null) { + if (sendingMax) { + amountEditText.setVisibility(View.INVISIBLE); + sendAllTextView.setVisibility(View.VISIBLE); + sendMaxButton.setText(getText(R.string.undo)); + } else { + amountEditText.setVisibility(View.VISIBLE); + sendAllTextView.setVisibility(View.GONE); + sendMaxButton.setText(getText(R.string.send_max)); + } + } + }); + + pendingTransaction.observe(getViewLifecycleOwner(), pendingTx -> { + showConfirmationLayout(pendingTx != null); + + if(pendingTx != null) { + String address = addressEditText.getText().toString(); + addressTextView.setText(getString(R.string.tx_address_text, address)); + amountTextView.setText(getString(R.string.tx_amount_text, Helper.getDisplayAmount(pendingTx.getAmount()))); + feeTextView.setText(getString(R.string.tx_fee_text, Helper.getDisplayAmount(pendingTx.getFee()))); } }); } + + private void sendTx(PendingTransaction pendingTx) { + AsyncTask.execute(() -> { + boolean success = TxService.getInstance().sendTx(pendingTx); + Activity activity = getActivity(); + if(activity != null) { + activity.runOnUiThread(() -> { + if (success) { + Toast.makeText(getActivity(), getString(R.string.sent_tx), Toast.LENGTH_SHORT).show(); + dismiss(); + } else { + sendButton.setEnabled(true); + Toast.makeText(getActivity(), getString(R.string.error_sending_tx), Toast.LENGTH_SHORT).show(); + } + }); + } + }); + } + + private void createTx(String address, String amount, boolean sendAll) { + AsyncTask.execute(() -> { + PendingTransaction pendingTx = TxService.getInstance().createTx(address, amount, sendAll); + if(pendingTx != null) { + _pendingTransaction.postValue(pendingTx); + } else { + Activity activity = getActivity(); + if(activity != null) { + activity.runOnUiThread(() -> { + createButton.setEnabled(true); + Toast.makeText(getActivity(), getString(R.string.error_creating_tx), Toast.LENGTH_SHORT).show(); + }); + } + } + }); + } + + private void showConfirmationLayout(boolean show) { + if(show) { + sendButton.setVisibility(View.VISIBLE); + addressEditText.setVisibility(View.GONE); + amountEditText.setVisibility(View.GONE); + sendAllTextView.setVisibility(View.GONE); + createButton.setVisibility(View.GONE); + sendMaxButton.setVisibility(View.GONE); + pasteAddressImageButton.setVisibility(View.GONE); + feeTextView.setVisibility(View.VISIBLE); + addressTextView.setVisibility(View.VISIBLE); + amountTextView.setVisibility(View.VISIBLE); + } else { + sendButton.setVisibility(View.GONE); + addressEditText.setVisibility(View.VISIBLE); + amountEditText.setVisibility(Boolean.TRUE.equals(sendingMax.getValue()) ? View.GONE : View.VISIBLE); + sendAllTextView.setVisibility(Boolean.TRUE.equals(sendingMax.getValue()) ? View.VISIBLE : View.GONE); + createButton.setVisibility(View.VISIBLE); + sendMaxButton.setVisibility(View.VISIBLE); + pasteAddressImageButton.setVisibility(View.VISIBLE); + feeTextView.setVisibility(View.GONE); + addressTextView.setVisibility(View.GONE); + amountTextView.setVisibility(View.GONE); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java b/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java index 4474f1f..60ebee3 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/MoneroHandlerThread.java @@ -60,7 +60,7 @@ public class MoneroHandlerThread extends Thread implements WalletListener { if(usesTor) { String proxy = "127.0.0.1:9050"; WalletManager.getInstance().setProxy(proxy); - WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.MONERUJO_ONION.getUri())); + WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.boldsuck.getUri())); wallet.setProxy(proxy); } else { WalletManager.getInstance().setDaemon(Node.fromString(DefaultNodes.XMRTW.getUri())); @@ -118,9 +118,12 @@ public class MoneroHandlerThread extends Thread implements WalletListener { listener.onRefresh(); } - public boolean sendTx(String address, String amountStr, boolean sendAll) { + public PendingTransaction createTx(String address, String amountStr, boolean sendAll) { long amount = sendAll ? SWEEP_ALL : Wallet.getAmountFromString(amountStr); - PendingTransaction pendingTx = wallet.createTransaction(new TxData(address, amount, 0, PendingTransaction.Priority.Priority_Default)); + return wallet.createTransaction(new TxData(address, amount, 0, PendingTransaction.Priority.Priority_Default)); + } + + public boolean sendTx(PendingTransaction pendingTx) { return pendingTx.commit("", true); } diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/TxService.java b/app/src/main/java/com/m2049r/xmrwallet/service/TxService.java index 76c70ba..32f4795 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/TxService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/TxService.java @@ -2,6 +2,7 @@ package com.m2049r.xmrwallet.service; import com.m2049r.xmrwallet.MainActivity; import com.m2049r.xmrwallet.livedata.SingleLiveEvent; +import com.m2049r.xmrwallet.model.PendingTransaction; public class TxService extends ServiceBase { public static TxService instance = null; @@ -15,7 +16,11 @@ public class TxService extends ServiceBase { instance = this; } - public boolean sendTx(String address, String amount, boolean sendAll) { - return this.getThread().sendTx(address, amount, sendAll); + public PendingTransaction createTx(String address, String amount, boolean sendAll) { + return this.getThread().createTx(address, amount, sendAll); + } + + public boolean sendTx(PendingTransaction pendingTransaction) { + return this.getThread().sendTx(pendingTransaction); } } diff --git a/app/src/main/res/drawable/button_bg.xml b/app/src/main/res/drawable/button_bg.xml index 00eb67d..f5d3fc4 100644 --- a/app/src/main/res/drawable/button_bg.xml +++ b/app/src/main/res/drawable/button_bg.xml @@ -1,13 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_bg_disabled.xml b/app/src/main/res/drawable/button_bg_disabled.xml new file mode 100644 index 0000000..ac19246 --- /dev/null +++ b/app/src/main/res/drawable/button_bg_disabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/drawable/button_bg_enabled.xml b/app/src/main/res/drawable/button_bg_enabled.xml new file mode 100644 index 0000000..00eb67d --- /dev/null +++ b/app/src/main/res/drawable/button_bg_enabled.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 57c0d3b..fcd0aa0 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -62,7 +62,7 @@ android:layout_marginEnd="24dp" android:layout_marginBottom="16dp" android:background="@drawable/button_bg" - android:text="Receive" + android:text="@string/receive" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/send_button" app:layout_constraintBottom_toBottomOf="parent"/> @@ -75,7 +75,7 @@ android:layout_marginEnd="24dp" android:layout_marginBottom="16dp" android:background="@drawable/button_bg" - android:text="Send" + android:text="@string/send" app:layout_constraintStart_toEndOf="@id/receive_button" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 5984809..6e567f0 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -21,6 +21,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/display_recovery_phrase" + android:background="@drawable/button_bg" android:layout_marginTop="16dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/send_bottom_sheet_dialog.xml b/app/src/main/res/layout/send_bottom_sheet_dialog.xml index b2bcca6..d18e9c3 100644 --- a/app/src/main/res/layout/send_bottom_sheet_dialog.xml +++ b/app/src/main/res/layout/send_bottom_sheet_dialog.xml @@ -12,7 +12,7 @@ - + + app:layout_constraintBottom_toTopOf="@id/amount_edittext" + tools:visibility="gone" /> + tools:ignore="SpeakableTextPresentCheck" + tools:visibility="gone" /> + app:layout_constraintBottom_toTopOf="@id/create_tx_button" + tools:visibility="gone"/> + tools:visibility="gone"/>