mirror of https://github.com/m2049r/xmrwallet.git
confirmations indicator (#775)
This commit is contained in:
parent
002dfd5d58
commit
9cd8a75dc6
|
@ -58,7 +58,6 @@ import java.text.NumberFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ public class WalletFragment extends Fragment
|
||||||
currencies.add(Helper.BASE_CRYPTO);
|
currencies.add(Helper.BASE_CRYPTO);
|
||||||
if (Helper.SHOW_EXCHANGERATES)
|
if (Helper.SHOW_EXCHANGERATES)
|
||||||
currencies.addAll(Arrays.asList(getResources().getStringArray(R.array.currency)));
|
currencies.addAll(Arrays.asList(getResources().getStringArray(R.array.currency)));
|
||||||
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(Objects.requireNonNull(getContext()), R.layout.item_spinner_balance, currencies);
|
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(requireContext(), R.layout.item_spinner_balance, currencies);
|
||||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
sCurrency.setAdapter(spinnerAdapter);
|
sCurrency.setAdapter(spinnerAdapter);
|
||||||
|
|
||||||
|
@ -346,13 +345,18 @@ public class WalletFragment extends Fragment
|
||||||
// if account index has changed scroll to top?
|
// if account index has changed scroll to top?
|
||||||
private int accountIndex = 0;
|
private int accountIndex = 0;
|
||||||
|
|
||||||
public void onRefreshed(final Wallet wallet, final boolean full) {
|
public void onRefreshed(final Wallet wallet, boolean full) {
|
||||||
Timber.d("onRefreshed(%b)", full);
|
Timber.d("onRefreshed(%b)", full);
|
||||||
|
|
||||||
|
if (adapter.needsTransactionUpdateOnNewBlock()) {
|
||||||
|
wallet.getHistory().refresh();
|
||||||
|
full = true;
|
||||||
|
}
|
||||||
if (full) {
|
if (full) {
|
||||||
List<TransactionInfo> list = new ArrayList<>();
|
List<TransactionInfo> list = new ArrayList<>();
|
||||||
final long streetHeight = activityCallback.getStreetModeHeight();
|
final long streetHeight = activityCallback.getStreetModeHeight();
|
||||||
Timber.d("StreetHeight=%d", streetHeight);
|
Timber.d("StreetHeight=%d", streetHeight);
|
||||||
|
wallet.getHistory().refresh();
|
||||||
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
for (TransactionInfo info : wallet.getHistory().getAll()) {
|
||||||
Timber.d("TxHeight=%d, Label=%s", info.blockheight, info.subaddressLabel);
|
Timber.d("TxHeight=%d, Label=%s", info.blockheight, info.subaddressLabel);
|
||||||
if ((info.isPending || (info.blockheight >= streetHeight))
|
if ((info.isPending || (info.blockheight >= streetHeight))
|
||||||
|
@ -561,7 +565,7 @@ public class WalletFragment extends Fragment
|
||||||
//TODO figure out why gunther disappears on return from send although he is still set
|
//TODO figure out why gunther disappears on return from send although he is still set
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (streetGunther == null)
|
if (streetGunther == null)
|
||||||
streetGunther = ContextCompat.getDrawable(Objects.requireNonNull(getContext()), R.drawable.ic_gunther_streetmode);
|
streetGunther = ContextCompat.getDrawable(requireContext(), R.drawable.ic_gunther_streetmode);
|
||||||
ivStreetGunther.setImageDrawable(streetGunther);
|
ivStreetGunther.setImageDrawable(streetGunther);
|
||||||
} else
|
} else
|
||||||
ivStreetGunther.setImageDrawable(null);
|
ivStreetGunther.setImageDrawable(null);
|
||||||
|
|
|
@ -30,6 +30,7 @@ import androidx.core.content.ContextCompat;
|
||||||
import androidx.recyclerview.widget.DiffUtil;
|
import androidx.recyclerview.widget.DiffUtil;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.progressindicator.CircularProgressIndicator;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.Crypto;
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
import com.m2049r.xmrwallet.data.UserNotes;
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
|
@ -48,7 +49,9 @@ import java.util.TimeZone;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
|
||||||
private final SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
private final static int MAX_CONFIRMATIONS = 10;
|
||||||
|
|
||||||
|
private final static SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||||
|
|
||||||
private final int outboundColour;
|
private final int outboundColour;
|
||||||
private final int inboundColour;
|
private final int inboundColour;
|
||||||
|
@ -77,6 +80,10 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
DATETIME_FORMATTER.setTimeZone(tz);
|
DATETIME_FORMATTER.setTimeZone(tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean needsTransactionUpdateOnNewBlock() {
|
||||||
|
return (infoItems.size() > 0) && (infoItems.get(0).confirmations < MAX_CONFIRMATIONS);
|
||||||
|
}
|
||||||
|
|
||||||
private static class TransactionInfoDiff extends DiffCallback<TransactionInfo> {
|
private static class TransactionInfoDiff extends DiffCallback<TransactionInfo> {
|
||||||
|
|
||||||
public TransactionInfoDiff(List<TransactionInfo> oldList, List<TransactionInfo> newList) {
|
public TransactionInfoDiff(List<TransactionInfo> oldList, List<TransactionInfo> newList) {
|
||||||
|
@ -95,6 +102,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
return (oldItem.direction == newItem.direction)
|
return (oldItem.direction == newItem.direction)
|
||||||
&& (oldItem.isPending == newItem.isPending)
|
&& (oldItem.isPending == newItem.isPending)
|
||||||
&& (oldItem.isFailed == newItem.isFailed)
|
&& (oldItem.isFailed == newItem.isFailed)
|
||||||
|
&& (oldItem.confirmations == newItem.confirmations)
|
||||||
&& (oldItem.subaddressLabel.equals(newItem.subaddressLabel))
|
&& (oldItem.subaddressLabel.equals(newItem.subaddressLabel))
|
||||||
&& (Objects.equals(oldItem.notes, newItem.notes));
|
&& (Objects.equals(oldItem.notes, newItem.notes));
|
||||||
}
|
}
|
||||||
|
@ -149,6 +157,8 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
final TextView tvFee;
|
final TextView tvFee;
|
||||||
final TextView tvPaymentId;
|
final TextView tvPaymentId;
|
||||||
final TextView tvDateTime;
|
final TextView tvDateTime;
|
||||||
|
final CircularProgressIndicator pbConfirmations;
|
||||||
|
final TextView tvConfirmations;
|
||||||
TransactionInfo infoItem;
|
TransactionInfo infoItem;
|
||||||
|
|
||||||
ViewHolder(View itemView) {
|
ViewHolder(View itemView) {
|
||||||
|
@ -158,6 +168,9 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
tvFee = itemView.findViewById(R.id.tx_fee);
|
tvFee = itemView.findViewById(R.id.tx_fee);
|
||||||
tvPaymentId = itemView.findViewById(R.id.tx_paymentid);
|
tvPaymentId = itemView.findViewById(R.id.tx_paymentid);
|
||||||
tvDateTime = itemView.findViewById(R.id.tx_datetime);
|
tvDateTime = itemView.findViewById(R.id.tx_datetime);
|
||||||
|
pbConfirmations = itemView.findViewById(R.id.pbConfirmations);
|
||||||
|
pbConfirmations.setMax(MAX_CONFIRMATIONS);
|
||||||
|
tvConfirmations = itemView.findViewById(R.id.tvConfirmations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getDateTime(long time) {
|
private String getDateTime(long time) {
|
||||||
|
@ -182,7 +195,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
ivTxType.setVisibility(View.GONE);
|
ivTxType.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ivTxType.setVisibility(View.GONE); // gives us more space for the amount
|
ivTxType.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
String displayAmount = Helper.getDisplayAmount(infoItem.amount, Helper.DISPLAY_DIGITS_INFO);
|
||||||
|
@ -205,12 +218,34 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
|
||||||
this.tvFee.setText(context.getString(R.string.tx_list_failed_text));
|
this.tvFee.setText(context.getString(R.string.tx_list_failed_text));
|
||||||
tvFee.setVisibility(View.VISIBLE);
|
tvFee.setVisibility(View.VISIBLE);
|
||||||
setTxColour(failedColour);
|
setTxColour(failedColour);
|
||||||
|
pbConfirmations.setVisibility(View.GONE);
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
} else if (infoItem.isPending) {
|
} else if (infoItem.isPending) {
|
||||||
setTxColour(pendingColour);
|
setTxColour(pendingColour);
|
||||||
|
pbConfirmations.setVisibility(View.GONE);
|
||||||
|
pbConfirmations.setIndeterminate(true);
|
||||||
|
pbConfirmations.setVisibility(View.VISIBLE);
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
} else if (infoItem.direction == TransactionInfo.Direction.Direction_In) {
|
} else if (infoItem.direction == TransactionInfo.Direction.Direction_In) {
|
||||||
setTxColour(inboundColour);
|
setTxColour(inboundColour);
|
||||||
|
final int confirmations = (int) infoItem.confirmations;
|
||||||
|
if (confirmations <= MAX_CONFIRMATIONS) {
|
||||||
|
pbConfirmations.setVisibility(View.VISIBLE);
|
||||||
|
pbConfirmations.setProgressCompat(confirmations, true);
|
||||||
|
final String confCount = Integer.toString(confirmations);
|
||||||
|
tvConfirmations.setText(confCount);
|
||||||
|
if (confCount.length() == 1) // we only have space for character in the progress circle
|
||||||
|
tvConfirmations.setVisibility(View.VISIBLE);
|
||||||
|
else
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
pbConfirmations.setVisibility(View.GONE);
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setTxColour(outboundColour);
|
setTxColour(outboundColour);
|
||||||
|
pbConfirmations.setVisibility(View.GONE);
|
||||||
|
tvConfirmations.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
String tag = null;
|
String tag = null;
|
||||||
|
|
|
@ -108,16 +108,12 @@ public class WalletService extends Service {
|
||||||
Timber.d("unconfirmedMoneyReceived() %d @ %s", amount, txId);
|
Timber.d("unconfirmedMoneyReceived() %d @ %s", amount, txId);
|
||||||
}
|
}
|
||||||
|
|
||||||
long lastBlockTime = 0;
|
|
||||||
int lastTxCount = 0;
|
int lastTxCount = 0;
|
||||||
|
|
||||||
public void newBlock(long height) {
|
public void newBlock(long height) {
|
||||||
final Wallet wallet = getWallet();
|
final Wallet wallet = getWallet();
|
||||||
if (wallet == null) throw new IllegalStateException("No wallet!");
|
if (wallet == null) throw new IllegalStateException("No wallet!");
|
||||||
// don't flood with an update for every block ...
|
|
||||||
if (lastBlockTime < System.currentTimeMillis() - 2000) {
|
|
||||||
Timber.d("newBlock() @ %d with observer %s", height, observer);
|
Timber.d("newBlock() @ %d with observer %s", height, observer);
|
||||||
lastBlockTime = System.currentTimeMillis();
|
|
||||||
if (observer != null) {
|
if (observer != null) {
|
||||||
boolean fullRefresh = false;
|
boolean fullRefresh = false;
|
||||||
updateDaemonState(wallet, wallet.isSynchronized() ? height : 0);
|
updateDaemonState(wallet, wallet.isSynchronized() ? height : 0);
|
||||||
|
@ -136,7 +132,6 @@ public class WalletService extends Service {
|
||||||
observer.onRefreshed(wallet, fullRefresh);
|
observer.onRefreshed(wallet, fullRefresh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void updated() {
|
public void updated() {
|
||||||
Timber.d("updated()");
|
Timber.d("updated()");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -19,6 +20,11 @@
|
||||||
android:layout_weight="9"
|
android:layout_weight="9"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivTxType"
|
android:id="@+id/ivTxType"
|
||||||
android:layout_width="16dp"
|
android:layout_width="16dp"
|
||||||
|
@ -27,6 +33,31 @@
|
||||||
android:src="@drawable/ic_xmrto_btc"
|
android:src="@drawable/ic_xmrto_btc"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
android:id="@+id/pbConfirmations"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="false"
|
||||||
|
android:max="10"
|
||||||
|
android:progress="8"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:indicatorInset="0dp"
|
||||||
|
app:indicatorSize="30dp"
|
||||||
|
app:trackThickness="4dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvConfirmations"
|
||||||
|
style="@style/MoneroText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingBottom="1dp"
|
||||||
|
android:text="8"
|
||||||
|
android:visibility="visible" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -57,8 +88,8 @@
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_weight="13"
|
android:layout_weight="13"
|
||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
tools:text="0123456789abcdef" />
|
tools:text="0123456789abcdef" />
|
||||||
|
|
|
@ -6,7 +6,7 @@ buildscript {
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.2.0'
|
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue