From bc004857ee208b43daf409701c48e6d0b345d435 Mon Sep 17 00:00:00 2001 From: pokkst Date: Sat, 2 Dec 2023 20:13:56 -0600 Subject: [PATCH] 0.4.7 Transaction screen redesign. Now auto-updates as well. Tx builder fee calculation fixes (thanks to Monero C++ bug fixes). Wallet balance now displays immediately once synced, fixing a recent bug where it was delayed by a few seconds. --- app/build.gradle | 4 +- .../java/net/mynero/wallet/MainActivity.java | 6 +- .../java/net/mynero/wallet/data/Node.java | 6 +- .../dialog/AddNodeBottomSheetDialog.java | 11 +- .../dialog/EditNodeBottomSheetDialog.java | 5 +- .../wallet/fragment/home/HomeFragment.java | 2 +- .../wallet/fragment/send/SendFragment.java | 8 +- .../transaction/TransactionFragment.java | 84 +++++-- .../transaction/TransactionViewModel.java | 21 -- .../mynero/wallet/service/HistoryService.java | 4 +- .../wallet/service/MoneroHandlerThread.java | 14 +- .../mynero/wallet/service/UTXOService.java | 20 +- .../layout/add_node_bottom_sheet_dialog.xml | 25 +- .../layout/edit_node_bottom_sheet_dialog.xml | 30 ++- .../main/res/layout/fragment_transaction.xml | 232 +++++++++--------- app/src/main/res/values/strings.xml | 14 +- 16 files changed, 269 insertions(+), 217 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index b37d28b..b1de24f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "net.mynero.wallet" minSdkVersion 21 targetSdkVersion 34 - versionCode 40600 - versionName "0.4.6 'Fluorine Fermi'" + versionCode 40700 + versionName "0.4.7 'Fluorine Fermi'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { diff --git a/app/src/main/java/net/mynero/wallet/MainActivity.java b/app/src/main/java/net/mynero/wallet/MainActivity.java index 0735a03..700a255 100644 --- a/app/src/main/java/net/mynero/wallet/MainActivity.java +++ b/app/src/main/java/net/mynero/wallet/MainActivity.java @@ -108,8 +108,10 @@ public class MainActivity extends AppCompatActivity implements MoneroHandlerThre } @Override - public void onRefresh() { - this.utxoService.refreshUtxos(); + public void onRefresh(boolean walletSynced) { + if(walletSynced) + this.utxoService.refreshUtxos(); + this.historyService.refreshHistory(); this.balanceService.refreshBalance(); this.blockchainService.refreshBlockchain(); diff --git a/app/src/main/java/net/mynero/wallet/data/Node.java b/app/src/main/java/net/mynero/wallet/data/Node.java index 328a3e5..43f7070 100644 --- a/app/src/main/java/net/mynero/wallet/data/Node.java +++ b/app/src/main/java/net/mynero/wallet/data/Node.java @@ -351,13 +351,17 @@ public class Node { } public String getAddress() { - return getHost() + ":" + rpcPort; + return getHost() + ":" + getRpcPort(); } public String getHost() { return host; } + public int getRpcPort() { + return rpcPort; + } + public void setHost(String host) throws UnknownHostException { if ((host == null) || (host.isEmpty())) throw new UnknownHostException("loopback not supported (yet?)"); diff --git a/app/src/main/java/net/mynero/wallet/fragment/dialog/AddNodeBottomSheetDialog.java b/app/src/main/java/net/mynero/wallet/fragment/dialog/AddNodeBottomSheetDialog.java index 470d75c..e615639 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/dialog/AddNodeBottomSheetDialog.java +++ b/app/src/main/java/net/mynero/wallet/fragment/dialog/AddNodeBottomSheetDialog.java @@ -41,6 +41,7 @@ public class AddNodeBottomSheetDialog extends BottomSheetDialogFragment { super.onViewCreated(view, savedInstanceState); Button addNodeButton = view.findViewById(R.id.add_node_button); EditText addressEditText = view.findViewById(R.id.address_edittext); + EditText portEditText = view.findViewById(R.id.node_port_edittext); EditText nodeNameEditText = view.findViewById(R.id.node_name_edittext); EditText usernameEditText = view.findViewById(R.id.username_edittext); EditText passwordEditText = view.findViewById(R.id.password_edittext); @@ -67,14 +68,15 @@ public class AddNodeBottomSheetDialog extends BottomSheetDialogFragment { addPasteListener(view, passwordEditText, R.id.paste_password_imagebutton); addNodeButton.setOnClickListener(view1 -> { - String node = addressEditText.getText().toString(); + String nodeAddr = addressEditText.getText().toString(); + String portString = portEditText.getText().toString(); String name = nodeNameEditText.getText().toString(); String user = usernameEditText.getText().toString(); String pass = passwordEditText.getText().toString(); if(name.isEmpty()) { Toast.makeText(getContext(), "Enter node name", Toast.LENGTH_SHORT).show(); return; - } else if(node.isEmpty()) { + } else if(nodeAddr.isEmpty() || portString.isEmpty()) { Toast.makeText(getContext(), "Enter node address", Toast.LENGTH_SHORT).show(); return; } else if(!user.isEmpty() && pass.isEmpty()) { @@ -88,10 +90,9 @@ public class AddNodeBottomSheetDialog extends BottomSheetDialogFragment { jsonObject.put("username", user); jsonObject.put("password", pass); } - String[] nodeParts = node.split(":"); - jsonObject.put("host", nodeParts[0]); - jsonObject.put("rpcPort", nodeParts[1]); + jsonObject.put("host", nodeAddr); + jsonObject.put("rpcPort", Integer.parseInt(portString)); jsonObject.put("network", "mainnet"); jsonObject.put("name", name); diff --git a/app/src/main/java/net/mynero/wallet/fragment/dialog/EditNodeBottomSheetDialog.java b/app/src/main/java/net/mynero/wallet/fragment/dialog/EditNodeBottomSheetDialog.java index b9c7593..e84783f 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/dialog/EditNodeBottomSheetDialog.java +++ b/app/src/main/java/net/mynero/wallet/fragment/dialog/EditNodeBottomSheetDialog.java @@ -48,13 +48,16 @@ public class EditNodeBottomSheetDialog extends BottomSheetDialogFragment { Button deleteNodeButton = view.findViewById(R.id.delete_node_button); Button doneEditingButton = view.findViewById(R.id.done_editing_button); EditText addressEditText = view.findViewById(R.id.address_edittext); + EditText portEditText = view.findViewById(R.id.node_port_edittext); EditText nodeNameEditText = view.findViewById(R.id.node_name_edittext); EditText usernameEditText = view.findViewById(R.id.username_edittext); EditText passwordEditText = view.findViewById(R.id.password_edittext); ImageButton pastePasswordImageButton = view.findViewById(R.id.paste_password_imagebutton); Node node = Node.fromJson(nodeJson); - addressEditText.setText(node.getAddress()); + if(node == null) return; + addressEditText.setText(node.getHost()); + portEditText.setText(node.getRpcPort()); nodeNameEditText.setText(node.getName()); usernameEditText.setText(node.getUsername()); if(!node.getPassword().isEmpty()) { diff --git a/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.java b/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.java index 50606f7..edfa4fb 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.java +++ b/app/src/main/java/net/mynero/wallet/fragment/home/HomeFragment.java @@ -120,7 +120,7 @@ public class HomeFragment extends Fragment implements TransactionInfoAdapter.TxI if (height > 1 && daemonHeight > 1) { progressBar.setProgress(x); progressBarText.setVisibility(View.VISIBLE); - progressBarText.setText("Syncing... " + height + " / " + daemonHeight); + progressBarText.setText("Syncing... " + n + " blocks remaining"); } else { progressBarText.setVisibility(View.GONE); } diff --git a/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.java b/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.java index 81976ab..fb5e370 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.java +++ b/app/src/main/java/net/mynero/wallet/fragment/send/SendFragment.java @@ -434,21 +434,23 @@ public class SendFragment extends Fragment { mViewModel.setPendingTransaction(pendingTx); } else { Activity activity = getActivity(); - if (activity != null) { + if (activity != null && pendingTx != null) { activity.runOnUiThread(() -> { createButton.setEnabled(true); sendMaxButton.setEnabled(true); - Toast.makeText(getActivity(), getString(R.string.error_creating_tx), Toast.LENGTH_SHORT).show(); + if(pendingTx.getErrorString() != null) + Toast.makeText(activity, getString(R.string.error_creating_tx, pendingTx.getErrorString()), Toast.LENGTH_SHORT).show(); }); } } } catch (Exception e) { + e.printStackTrace(); Activity activity = getActivity(); if (activity != null) { activity.runOnUiThread(() -> { createButton.setEnabled(true); sendMaxButton.setEnabled(true); - Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, getString(R.string.error_creating_tx, e.getMessage()), Toast.LENGTH_SHORT).show(); }); } } diff --git a/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionFragment.java b/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionFragment.java index 8a7c6b0..3e1f9f8 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionFragment.java +++ b/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionFragment.java @@ -19,18 +19,22 @@ import androidx.lifecycle.ViewModelProvider; import net.mynero.wallet.R; import net.mynero.wallet.model.TransactionInfo; import net.mynero.wallet.model.Wallet; +import net.mynero.wallet.model.WalletManager; +import net.mynero.wallet.service.HistoryService; import net.mynero.wallet.service.PrefService; import net.mynero.wallet.util.Constants; import net.mynero.wallet.util.Helper; import java.util.Calendar; import java.util.Date; +import java.util.List; import java.util.Objects; import java.util.TimeZone; public class TransactionFragment extends Fragment { private TransactionViewModel mViewModel; + private TransactionInfo transactionInfo = null; @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @@ -48,8 +52,7 @@ public class TransactionFragment extends Fragment { mViewModel = new ViewModelProvider(this).get(TransactionViewModel.class); Bundle args = getArguments(); if (args != null) { - TransactionInfo txInfo = getArguments().getParcelable(Constants.NAV_ARG_TXINFO); - mViewModel.init(txInfo); + this.transactionInfo = getArguments().getParcelable(Constants.NAV_ARG_TXINFO); } bindObservers(view); @@ -59,25 +62,26 @@ public class TransactionFragment extends Fragment { private void bindListeners(View view) { ImageButton copyTxHashImageButton = view.findViewById(R.id.copy_txhash_imagebutton); copyTxHashImageButton.setOnClickListener(view1 -> { - TransactionInfo txInfo = mViewModel.transaction.getValue(); + TransactionInfo txInfo = this.transactionInfo; if (txInfo != null) { Helper.clipBoardCopy(getContext(), "transaction_hash", txInfo.hash); } }); ImageButton copyTxAddressImageButton = view.findViewById(R.id.copy_txaddress_imagebutton); + TextView addressTextView = view.findViewById(R.id.transaction_address_textview); copyTxAddressImageButton.setOnClickListener(view1 -> { - TransactionInfo txInfo = mViewModel.transaction.getValue(); + TransactionInfo txInfo = this.transactionInfo; if (txInfo != null) { - String destination = mViewModel.destination.getValue(); - if (destination != null) { - Helper.clipBoardCopy(getContext(), "transaction_address", destination); - } + String destination = addressTextView.getText().toString(); + Helper.clipBoardCopy(getContext(), "transaction_address", destination); } }); } private void bindObservers(View view) { + TextView txActionTextView = view.findViewById(R.id.transaction_action_textview); + TextView confLabel2 = view.findViewById(R.id.transaction_conf_label2_textview); TextView txHashTextView = view.findViewById(R.id.transaction_hash_textview); TextView txConfTextView = view.findViewById(R.id.transaction_conf_textview); TextView txAddressTextView = view.findViewById(R.id.transaction_address_textview); @@ -85,43 +89,73 @@ public class TransactionFragment extends Fragment { TextView txDateTextView = view.findViewById(R.id.transaction_date_textview); TextView txAmountTextView = view.findViewById(R.id.transaction_amount_textview); TextView blockHeightTextView = view.findViewById(R.id.tx_block_height_textview); - TextView blockHeightLabelTextView = view.findViewById(R.id.transaction_block_height_label_textview); - mViewModel.transaction.observe(getViewLifecycleOwner(), transactionInfo -> { - txHashTextView.setText(transactionInfo.hash); - txConfTextView.setText("" + transactionInfo.confirmations); - txDateTextView.setText(getDateTime(transactionInfo.timestamp)); - if(transactionInfo.confirmations > 0) { - blockHeightTextView.setText("" + transactionInfo.blockheight); + HistoryService.getInstance().history.observe(getViewLifecycleOwner(), transactionInfos -> { + TransactionInfo newTransactionInfo = findNewestVersionOfTransaction(this.transactionInfo, transactionInfos); + if(newTransactionInfo == null) return; + + txHashTextView.setText(newTransactionInfo.hash); + txConfTextView.setText("" + newTransactionInfo.confirmations); + txDateTextView.setText(getDateTime(newTransactionInfo.timestamp)); + if(newTransactionInfo.confirmations > 1) { + confLabel2.setText(getString(R.string.transaction_conf_desc2_confirmed)); + blockHeightTextView.setText("" + newTransactionInfo.blockheight); + blockHeightTextView.setVisibility(View.VISIBLE); + } else if(newTransactionInfo.confirmations == 1) { + confLabel2.setText(getString(R.string.transaction_conf_1_desc2_confirmed)); + blockHeightTextView.setText("" + newTransactionInfo.blockheight); blockHeightTextView.setVisibility(View.VISIBLE); - blockHeightLabelTextView.setVisibility(View.VISIBLE); } else { blockHeightTextView.setVisibility(View.GONE); - blockHeightLabelTextView.setVisibility(View.GONE); + confLabel2.setText(getString(R.string.transaction_conf_desc2_unconfirmed)); } Context ctx = getContext(); if(ctx != null) { boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false); - String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Wallet.getDisplayAmount(transactionInfo.amount); - if (transactionInfo.direction == TransactionInfo.Direction.Direction_In) { + String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Helper.getDisplayAmount(newTransactionInfo.amount, 12); + if (newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) { + txActionTextView.setText(getString(R.string.transaction_action_recv)); txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_positiveColor)); - txAmountTextView.setText(getString(R.string.tx_list_amount_positive, balanceString)); } else { + txActionTextView.setText(getString(R.string.transaction_action_sent)); txAmountTextView.setTextColor(ContextCompat.getColor(ctx, R.color.oled_negativeColor)); - txAmountTextView.setText(getString(R.string.tx_list_amount_negative, balanceString)); + } + txAmountTextView.setText(balanceString); + } + + String destination = "-"; + Wallet wallet = WalletManager.getInstance().getWallet(); + if (newTransactionInfo.txKey == null) { + newTransactionInfo.txKey = wallet.getTxKey(newTransactionInfo.hash); + } + if (newTransactionInfo.address == null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) { + destination = wallet.getSubaddress(newTransactionInfo.accountIndex, newTransactionInfo.addressIndex); + } else if (newTransactionInfo.address != null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_In) { + destination = newTransactionInfo.address; + } else if (newTransactionInfo.transfers != null && newTransactionInfo.direction == TransactionInfo.Direction.Direction_Out) { + if (newTransactionInfo.transfers.size() == 1) { + destination = newTransactionInfo.transfers.get(0).address; } } - }); - mViewModel.destination.observe(getViewLifecycleOwner(), s -> { - txAddressTextView.setText(Objects.requireNonNullElse(s, "-")); - if (s == null) { + txAddressTextView.setText(Objects.requireNonNullElse(destination, "-")); + if (destination == null) { copyTxAddressImageButton.setVisibility(View.INVISIBLE); } }); } + private TransactionInfo findNewestVersionOfTransaction(TransactionInfo oldTransactionInfo, List transactionInfoList) { + for(TransactionInfo transactionInfo : transactionInfoList) { + if(transactionInfo.hash.equals(oldTransactionInfo.hash)) { + this.transactionInfo = transactionInfo; + return this.transactionInfo; + } + } + return null; + } + private String getDateTime(long time) { return DATETIME_FORMATTER.format(new Date(time * 1000)); } diff --git a/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionViewModel.java b/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionViewModel.java index 9f35b33..e86ded1 100644 --- a/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionViewModel.java +++ b/app/src/main/java/net/mynero/wallet/fragment/transaction/TransactionViewModel.java @@ -9,25 +9,4 @@ import net.mynero.wallet.model.Wallet; import net.mynero.wallet.model.WalletManager; public class TransactionViewModel extends ViewModel { - private final MutableLiveData _transaction = new MutableLiveData<>(null); - private final MutableLiveData _destination = new MutableLiveData<>(null); - public LiveData transaction = _transaction; - public LiveData destination = _destination; - - public void init(TransactionInfo info) { - Wallet wallet = WalletManager.getInstance().getWallet(); - if (info.txKey == null) { - info.txKey = wallet.getTxKey(info.hash); - } - if (info.address == null && info.direction == TransactionInfo.Direction.Direction_In) { - _destination.setValue(wallet.getSubaddress(info.accountIndex, info.addressIndex)); - } else if (info.address != null && info.direction == TransactionInfo.Direction.Direction_In) { - _destination.setValue(info.address); - } else if (info.transfers != null && info.direction == TransactionInfo.Direction.Direction_Out) { - if (info.transfers.size() == 1) { - _destination.setValue(info.transfers.get(0).address); - } - } - this._transaction.setValue(info); - } } \ No newline at end of file diff --git a/app/src/main/java/net/mynero/wallet/service/HistoryService.java b/app/src/main/java/net/mynero/wallet/service/HistoryService.java index b874e7a..c02d940 100644 --- a/app/src/main/java/net/mynero/wallet/service/HistoryService.java +++ b/app/src/main/java/net/mynero/wallet/service/HistoryService.java @@ -9,7 +9,7 @@ import net.mynero.wallet.model.WalletManager; import java.util.List; public class HistoryService extends ServiceBase { - public static HistoryService instance = null; + private static HistoryService instance = null; private final MutableLiveData> _history = new MutableLiveData<>(); public LiveData> history = _history; @@ -26,7 +26,7 @@ public class HistoryService extends ServiceBase { _history.postValue(getHistory()); } - public List getHistory() { + private List getHistory() { return WalletManager.getInstance().getWallet().getHistory().getAll(); } } diff --git a/app/src/main/java/net/mynero/wallet/service/MoneroHandlerThread.java b/app/src/main/java/net/mynero/wallet/service/MoneroHandlerThread.java index 85dd5a7..dcb322a 100644 --- a/app/src/main/java/net/mynero/wallet/service/MoneroHandlerThread.java +++ b/app/src/main/java/net/mynero/wallet/service/MoneroHandlerThread.java @@ -17,9 +17,7 @@ package net.mynero.wallet.service; -import net.mynero.wallet.data.DefaultNodes; import net.mynero.wallet.data.Node; -import net.mynero.wallet.data.TxData; import net.mynero.wallet.model.CoinsInfo; import net.mynero.wallet.model.PendingTransaction; import net.mynero.wallet.model.TransactionOutput; @@ -57,7 +55,7 @@ public class MoneroHandlerThread extends Thread implements WalletListener { @Override public synchronized void start() { super.start(); - this.listener.onRefresh(); + this.listener.onRefresh(false); } @Override @@ -120,12 +118,12 @@ public class MoneroHandlerThread extends Thread implements WalletListener { BlockchainService.getInstance().setConnectionStatus(status); } - private void refresh(boolean refreshCoins) { + private void refresh(boolean walletSynced) { wallet.refreshHistory(); - if(refreshCoins) { + if(walletSynced) { wallet.refreshCoins(); } - listener.onRefresh(); + listener.onRefresh(walletSynced); } public PendingTransaction createTx(String address, String amountStr, boolean sendAll, PendingTransaction.Priority feePriority, ArrayList selectedUtxos) throws Exception { @@ -146,7 +144,7 @@ public class MoneroHandlerThread extends Thread implements WalletListener { ArrayList preferredInputs; if (selectedUtxos.isEmpty()) { // no inputs manually selected, we are sending from home screen most likely, or user somehow broke the app - preferredInputs = UTXOService.getInstance().selectUtxos(totalAmount, sendAll); + preferredInputs = UTXOService.getInstance().selectUtxos(totalAmount, sendAll, feePriority); } else { preferredInputs = selectedUtxos; checkSelectedAmounts(preferredInputs, totalAmount, sendAll); @@ -233,7 +231,7 @@ public class MoneroHandlerThread extends Thread implements WalletListener { } public interface Listener { - void onRefresh(); + void onRefresh(boolean walletSynced); void onConnectionFail(); } } diff --git a/app/src/main/java/net/mynero/wallet/service/UTXOService.java b/app/src/main/java/net/mynero/wallet/service/UTXOService.java index 1215b71..84d0ed3 100644 --- a/app/src/main/java/net/mynero/wallet/service/UTXOService.java +++ b/app/src/main/java/net/mynero/wallet/service/UTXOService.java @@ -5,7 +5,6 @@ import android.util.Pair; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import net.mynero.wallet.model.Coins; import net.mynero.wallet.model.CoinsInfo; import net.mynero.wallet.model.PendingTransaction; import net.mynero.wallet.model.Wallet; @@ -22,6 +21,7 @@ import java.util.List; public class UTXOService extends ServiceBase { public static UTXOService instance = null; + private List internalCachedUtxos = new ArrayList<>(); private final MutableLiveData> _utxos = new MutableLiveData<>(); public LiveData> utxos = _utxos; private ArrayList frozenCoins = new ArrayList<>(); @@ -41,12 +41,13 @@ public class UTXOService extends ServiceBase { } public void refreshUtxos() { - _utxos.postValue(getUtxosInternal()); + List coinsInfos = getUtxosInternal(); + _utxos.postValue(coinsInfos); + internalCachedUtxos = coinsInfos; } public List getUtxos() { - List value = utxos.getValue(); - return value != null ? value : List.of(); + return Collections.unmodifiableList(internalCachedUtxos); } private List getUtxosInternal() { @@ -93,12 +94,12 @@ public class UTXOService extends ServiceBase { prefService.edit().putString(Constants.PREF_FROZEN_COINS, jsonArray.toString()).apply(); } - public ArrayList selectUtxos(long amount, boolean sendAll) throws Exception { - final long basicFeeEstimate = calculateBasicFee(amount); + public ArrayList selectUtxos(long amount, boolean sendAll, PendingTransaction.Priority feePriority) throws Exception { + final long basicFeeEstimate = calculateBasicFee(amount, feePriority); final long amountWithBasicFee = amount + basicFeeEstimate; ArrayList selectedUtxos = new ArrayList<>(); ArrayList seenTxs = new ArrayList<>(); - List utxos = getUtxos(); + List utxos = new ArrayList<>(getUtxos()); long amountSelected = 0; Collections.sort(utxos); //loop through each utxo @@ -127,11 +128,10 @@ public class UTXOService extends ServiceBase { return selectedUtxos; } - private long calculateBasicFee(long amount) { + private long calculateBasicFee(long amount, PendingTransaction.Priority feePriority) { ArrayList> destinations = new ArrayList<>(); destinations.add(new Pair<>("87MRtZPrWUCVUgcFHdsVb5MoZUcLtqfD3FvQVGwftFb8eSdMnE39JhAJcbuSW8X2vRaRsB9RQfuCpFciybJFHaz3QYPhCLw", amount)); // destination string doesn't actually matter here, so i'm using the donation address. amount also technically doesn't matter - // priority also isn't accounted for in the Monero C++ code. maybe this is a bug by the core Monero team, or i'm using an outdated method. - return WalletManager.getInstance().getWallet().estimateTransactionFee(destinations, PendingTransaction.Priority.Priority_Low); + return WalletManager.getInstance().getWallet().estimateTransactionFee(destinations, feePriority); } } diff --git a/app/src/main/res/layout/add_node_bottom_sheet_dialog.xml b/app/src/main/res/layout/add_node_bottom_sheet_dialog.xml index f5a8eb3..f55a3ef 100644 --- a/app/src/main/res/layout/add_node_bottom_sheet_dialog.xml +++ b/app/src/main/res/layout/add_node_bottom_sheet_dialog.xml @@ -45,15 +45,13 @@ android:id="@+id/paste_address_imagebutton" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" android:background="@android:color/transparent" android:minWidth="48dp" android:minHeight="48dp" android:src="@drawable/ic_content_paste_24dp" app:layout_constraintBottom_toBottomOf="@id/address_edittext" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@id/address_edittext" + app:layout_constraintStart_toEndOf="@id/node_port_edittext" app:layout_constraintTop_toTopOf="@id/address_edittext" tools:ignore="SpeakableTextPresentCheck" /> @@ -61,16 +59,30 @@ android:id="@+id/address_edittext" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="8dp" android:layout_marginBottom="16dp" android:background="@drawable/edittext_bg" android:hint="@string/node_address_hint" android:inputType="text" android:digits="-QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890.:" app:layout_constraintBottom_toTopOf="@id/username_edittext" - app:layout_constraintEnd_toStartOf="@id/paste_address_imagebutton" + app:layout_constraintEnd_toStartOf="@id/node_port_edittext" app:layout_constraintStart_toStartOf="parent" /> + +