From 6e898939a30e0d758c41be7840bb6f3efd44b6c1 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 19 May 2019 17:33:19 +0200 Subject: [PATCH] show account balances (#589) and refactor displayAmount --- .../com/m2049r/xmrwallet/ReceiveFragment.java | 3 +- .../com/m2049r/xmrwallet/WalletActivity.java | 13 +++- .../com/m2049r/xmrwallet/WalletFragment.java | 8 +- .../layout/TransactionInfoAdapter.java | 3 +- .../com/m2049r/xmrwallet/model/Wallet.java | 5 +- .../com/m2049r/xmrwallet/util/Helper.java | 30 ++++---- app/src/main/res/values/strings.xml | 2 + .../com/m2049r/xmrwallet/util/HelperTest.java | 74 +++++++++++++++++++ 8 files changed, 111 insertions(+), 27 deletions(-) create mode 100644 app/src/test/java/com/m2049r/xmrwallet/util/HelperTest.java diff --git a/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java b/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java index 9df51cf..7b2c152 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/ReceiveFragment.java @@ -302,7 +302,7 @@ public class ReceiveFragment extends Fragment { File imagePath = new File(getActivity().getCacheDir(), "images"); File png = new File(imagePath, "QR.png"); Uri contentUri = FileProvider.getUriForFile(getActivity(), - "com.m2049r.xmrwallet.fileprovider", png); + BuildConfig.APPLICATION_ID + ".fileprovider", png); if (contentUri != null) { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); @@ -574,6 +574,7 @@ public class ReceiveFragment extends Fragment { @Override public void onPause() { Timber.d("onPause()"); + Helper.hideKeyboard(getActivity()); super.onPause(); } diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java index 942e375..8565b99 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java @@ -150,8 +150,14 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste final WalletFragment walletFragment = (WalletFragment) getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName()); if (walletFragment != null) walletFragment.resetDismissedTransactions(); - updateAccountsBalance(); forceUpdate(); + runOnUiThread(new Runnable() { + @Override + public void run() { + updateAccountsList(); + updateAccountsBalance(); + } + }); } @Override @@ -1045,8 +1051,11 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste Menu menu = accountsView.getMenu(); menu.removeGroup(R.id.accounts_list); final int n = wallet.getNumAccounts(); + final boolean showBalances = (n > 1) && !isStreetMode(); for (int i = 0; i < n; i++) { - final String label = wallet.getAccountLabel(i); + final String label = (showBalances ? + getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2)) + : wallet.getAccountLabel(i)); final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label); item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp); if (i == wallet.getAccountIndex()) diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java index 6c635e4..22169f4 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java @@ -219,7 +219,7 @@ public class WalletFragment extends Fragment if (isExchanging) return; // wait for exchange to finish - it will fire this itself then. // at this point selection is XMR in case of error String displayB; - double amountA = Double.parseDouble(Wallet.getDisplayAmount(unlockedBalance)); // crash if this fails! + double amountA = Helper.getDecimalAmount(unlockedBalance).doubleValue(); if (!Helper.CRYPTO.equals(balanceCurrency)) { // not XMR double amountB = amountA * balanceRate; displayB = Helper.getFormattedAmount(amountB, false); @@ -235,10 +235,10 @@ public class WalletFragment extends Fragment private final ExchangeApi exchangeApi = Helper.getExchangeApi(); void refreshBalance() { - double unconfirmedXmr = Double.parseDouble(Helper.getDisplayAmount(balance - unlockedBalance)); + double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue(); showUnconfirmed(unconfirmedXmr); if (sCurrency.getSelectedItemPosition() == 0) { // XMR - double amountXmr = Double.parseDouble(Wallet.getDisplayAmount(unlockedBalance)); // assume this cannot fail! + double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue(); showBalance(Helper.getFormattedAmount(amountXmr, true)); } else { // not XMR String currency = (String) sCurrency.getSelectedItem(); @@ -294,7 +294,7 @@ public class WalletFragment extends Fragment public void exchangeFailed() { sCurrency.setSelection(0, true); // default to XMR - double amountXmr = Double.parseDouble(Wallet.getDisplayAmount(unlockedBalance)); // assume this cannot fail! + double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue(); showBalance(Helper.getFormattedAmount(amountXmr, true)); hideExchanging(); } diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index 589b84e..ad72b49 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -30,6 +30,7 @@ import com.m2049r.xmrwallet.model.TransactionInfo; import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.data.UserNotes; +import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -154,7 +155,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter 0)) { - String fee = Helper.getDisplayAmount(infoItem.fee, 5); + String fee = Helper.getDisplayAmount(infoItem.fee, Helper.DISPLAY_DIGITS_INFO); tvFee.setText(context.getString(R.string.tx_list_fee, fee)); tvFee.setVisibility(View.VISIBLE); } else { diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java index d7f3224..1d3ed97 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java @@ -353,9 +353,10 @@ public class Wallet { if (label.equals(NEW_ACCOUNT_NAME)) { String address = getAddress(accountIndex); int len = address.length(); - return address.substring(0, 6) + + label = address.substring(0, 6) + "\u2026" + address.substring(len - 6, len); - } else return label; + } + return label; } public String getSubaddressLabel(int addressIndex) { diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java index 925e998..968dbe1 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java @@ -64,6 +64,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.math.BigDecimal; import java.math.BigInteger; import java.net.MalformedURLException; import java.net.SocketTimeoutException; @@ -186,28 +187,23 @@ public class Helper { act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); } + static public BigDecimal getDecimalAmount(long amount) { + return new BigDecimal(amount).scaleByPowerOfTen(-12); + } + static public String getDisplayAmount(long amount) { return getDisplayAmount(amount, 12); } static public String getDisplayAmount(long amount, int maxDecimals) { - return getDisplayAmount(Wallet.getDisplayAmount(amount), maxDecimals); - } - - // amountString must have '.' as decimal point - private static String getDisplayAmount(String amountString, int maxDecimals) { - int lastZero = 0; - int decimal = 0; - for (int i = amountString.length() - 1; i >= 0; i--) { - if ((lastZero == 0) && (amountString.charAt(i) != '0')) lastZero = i + 1; - // TODO i18n - if (amountString.charAt(i) == '.') { - decimal = i + 1; - break; - } - } - int cutoff = Math.min(Math.max(lastZero, decimal + 2), decimal + maxDecimals); - return amountString.substring(0, cutoff); + // a Java bug does not strip zeros properly if the value is 0 + if (amount == 0) return "0.00"; + BigDecimal d = getDecimalAmount(amount) + .setScale(maxDecimals, BigDecimal.ROUND_HALF_UP) + .stripTrailingZeros(); + if (d.scale() < 2) + d = d.setScale(2, BigDecimal.ROUND_UNNECESSARY); + return d.toPlainString(); } static public String getFormattedAmount(double amount, boolean isXmr) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8bfee35..6874e5a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -430,4 +430,6 @@ Ledger Passphrase (advanced) Invalid Ledger Seed! Entering your Ledger Seed here is a major security risk! + + %1$s (%2$s) diff --git a/app/src/test/java/com/m2049r/xmrwallet/util/HelperTest.java b/app/src/test/java/com/m2049r/xmrwallet/util/HelperTest.java new file mode 100644 index 0000000..05a9431 --- /dev/null +++ b/app/src/test/java/com/m2049r/xmrwallet/util/HelperTest.java @@ -0,0 +1,74 @@ +package com.m2049r.xmrwallet.util; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; + +public class HelperTest { + + @Test + public void testMinus() { + long l = -1000000000000L; + String s = Helper.getDisplayAmount(l, 5); + System.out.println(s); + assertTrue(s.equals("-1.00")); + } + + @Test + public void testTen() { + long l = 10L; + String s = Helper.getDisplayAmount(l); + System.out.println(s); + assertTrue(s.equals("0.00000000001")); + } + + @Test + public void testZero() { + long l = 0L; + String s = Helper.getDisplayAmount(l); + System.out.println(s); + assertTrue(s.equals("0.00")); + } + + @Test + public void testG() { + long l = 1234567891234L; + String s = Helper.getDisplayAmount(l); + System.out.println(s); + assertTrue(s.equals("1.234567891234")); + } + + @Test + public void testG2() { + long l = 1000000000000L; + String s = Helper.getDisplayAmount(l); + System.out.println(s); + assertTrue(s.equals("1.00")); + } + + + @Test + public void testE() { + long l = 1234567891234L; + String s = Helper.getDisplayAmount(l, 4); + System.out.println(s); + assertTrue(s.equals("1.2346")); + } + + @Test + public void testF() { + long l = 1234567891234L; + String s = Helper.getDisplayAmount(l, 12); + System.out.println(s); + assertTrue(s.equals("1.234567891234")); + } + + @Test + public void testH() { + long l = 1004567891234L; + String s = Helper.getDisplayAmount(l, 2); + System.out.println(s); + assertTrue(s.equals("1.00")); + } + +}