Finally fixed the fucking bug (0.4.4.4)

This commit is contained in:
pokkst 2023-07-10 02:25:28 -05:00
parent aeb604d370
commit 3545b0ded6
No known key found for this signature in database
GPG key ID: 90C2ED85E67A50FF
4 changed files with 69 additions and 40 deletions

View file

@ -9,8 +9,8 @@ android {
applicationId "net.mynero.wallet" applicationId "net.mynero.wallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 34 targetSdkVersion 34
versionCode 40403 versionCode 40404
versionName "0.4.4.3 'Fluorine Fermi'" versionName "0.4.4.4 'Fluorine Fermi'"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {

View file

@ -21,6 +21,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -32,14 +33,16 @@ import net.mynero.wallet.util.Constants;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.ViewHolder> { public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.ViewHolder> {
private List<CoinsInfo> localDataSet; private List<CoinsInfo> localDataSet; // <public-key, coinsinfo>
private final ArrayList<CoinsInfo> selectedUtxos; private final HashMap<String, CoinsInfo> selectedUtxos; // <public-key, coinsinfo>
private CoinsInfoAdapterListener listener = null; private CoinsInfoAdapterListener listener = null;
private boolean editing = false;
/** /**
* Initialize the dataset of the Adapter. * Initialize the dataset of the Adapter.
@ -47,34 +50,41 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
public CoinsInfoAdapter(CoinsInfoAdapterListener listener) { public CoinsInfoAdapter(CoinsInfoAdapterListener listener) {
this.listener = listener; this.listener = listener;
this.localDataSet = new ArrayList<>(); this.localDataSet = new ArrayList<>();
this.selectedUtxos = new ArrayList<>(); this.selectedUtxos = new HashMap<>();
} }
public void submitList(List<CoinsInfo> dataSet) { public void submitList(HashMap<String, CoinsInfo> dataSet) {
this.localDataSet = dataSet; this.localDataSet = new ArrayList<>(dataSet.values());
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void deselectUtxo(CoinsInfo coinsInfo) { public void deselectUtxo(CoinsInfo coinsInfo) {
this.selectedUtxos.remove(coinsInfo); this.selectedUtxos.remove(coinsInfo.getPubKey());
if(this.selectedUtxos.size() == 0) {
editing = false;
}
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void selectUtxo(CoinsInfo coinsInfo) { public void selectUtxo(CoinsInfo coinsInfo) {
this.selectedUtxos.add(coinsInfo); editing = true;
this.selectedUtxos.put(coinsInfo.getPubKey(), coinsInfo);
notifyDataSetChanged(); notifyDataSetChanged();
} }
public boolean contains(CoinsInfo coinsInfo) { public boolean contains(CoinsInfo coinsInfo) {
return this.selectedUtxos.contains(coinsInfo); return selectedUtxos.containsKey(coinsInfo.getPubKey());
} }
public void clear() { public void clear() {
this.selectedUtxos.clear(); this.selectedUtxos.clear();
editing = false;
notifyDataSetChanged(); notifyDataSetChanged();
} }
public List<CoinsInfo> getSelectedUtxos() { public HashMap<String, CoinsInfo> getSelectedUtxos() {
return selectedUtxos; return selectedUtxos;
} }
@ -85,14 +95,14 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
View view = LayoutInflater.from(viewGroup.getContext()) View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.utxo_selection_item, viewGroup, false); .inflate(R.layout.utxo_selection_item, viewGroup, false);
return new ViewHolder(view); return new ViewHolder(listener, view);
} }
// Replace the contents of a view (invoked by the layout manager) // Replace the contents of a view (invoked by the layout manager)
@Override @Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) { public void onBindViewHolder(ViewHolder viewHolder, final int position) {
CoinsInfo tx = localDataSet.get(position); CoinsInfo tx = localDataSet.get(position);
viewHolder.bind(listener, tx, Collections.unmodifiableList(selectedUtxos)); viewHolder.bind(editing, tx, selectedUtxos);
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@ -109,19 +119,22 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
* Provide a reference to the type of views that you are using * Provide a reference to the type of views that you are using
* (custom ViewHolder). * (custom ViewHolder).
*/ */
public static class ViewHolder extends RecyclerView.ViewHolder { public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
public ViewHolder(View view) { private CoinsInfo coinsInfo;
private boolean editing = false;
private final CoinsInfoAdapterListener listener;
public ViewHolder(CoinsInfoAdapterListener listener, View view) {
super(view); super(view);
this.listener = listener;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
} }
public void bind(CoinsInfoAdapterListener listener, CoinsInfo coinsInfo, List<CoinsInfo> selectedUtxos) { public void bind(boolean editing, CoinsInfo coinsInfo, HashMap<String, CoinsInfo> selectedUtxos) {
boolean selected = false; this.editing = editing;
for(CoinsInfo selectedUtxo : selectedUtxos) { this.coinsInfo = coinsInfo;
if (Objects.equals(selectedUtxo.getKeyImage(), coinsInfo.getKeyImage())) { boolean selected = selectedUtxos.containsKey(coinsInfo.getPubKey());
selected = true;
break;
}
}
TextView pubKeyTextView = itemView.findViewById(R.id.utxo_pub_key_textview); TextView pubKeyTextView = itemView.findViewById(R.id.utxo_pub_key_textview);
TextView amountTextView = itemView.findViewById(R.id.utxo_amount_textview); TextView amountTextView = itemView.findViewById(R.id.utxo_amount_textview);
@ -133,15 +146,6 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
pubKeyTextView.setText(coinsInfo.getPubKey()); pubKeyTextView.setText(coinsInfo.getPubKey());
globalIdxTextView.setText(itemView.getResources().getString(R.string.global_index_text, coinsInfo.getGlobalOutputIndex())); globalIdxTextView.setText(itemView.getResources().getString(R.string.global_index_text, coinsInfo.getGlobalOutputIndex()));
outpointTextView.setText(itemView.getResources().getString(R.string.outpoint_text, coinsInfo.getHash() + ":" + coinsInfo.getLocalOutputIndex())); outpointTextView.setText(itemView.getResources().getString(R.string.outpoint_text, coinsInfo.getHash() + ":" + coinsInfo.getLocalOutputIndex()));
itemView.setOnLongClickListener(view -> {
boolean unlocked = coinsInfo.isUnlocked();
if (unlocked) {
listener.onUtxoSelected(coinsInfo);
}
return unlocked;
});
if (selected) { if (selected) {
itemView.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), R.color.oled_colorSecondary)); itemView.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), R.color.oled_colorSecondary));
} else if(coinsInfo.isFrozen()) { } else if(coinsInfo.isFrozen()) {
@ -152,6 +156,30 @@ public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.View
itemView.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), android.R.color.transparent)); itemView.setBackgroundColor(ContextCompat.getColor(itemView.getContext(), android.R.color.transparent));
} }
} }
@Override
public void onClick(View view) {
if(!editing) return;
boolean unlocked = coinsInfo.isUnlocked();
if (unlocked) {
listener.onUtxoSelected(coinsInfo);
}
}
@Override
public boolean onLongClick(View view) {
if(editing) return false;
boolean unlocked = coinsInfo.isUnlocked();
if (unlocked) {
listener.onUtxoSelected(coinsInfo);
}
return unlocked;
}
@Override
public boolean onLongClickUseDefaultHapticFeedback(@NonNull View v) {
return View.OnLongClickListener.super.onLongClickUseDefaultHapticFeedback(v);
}
} }
} }

View file

@ -25,6 +25,7 @@ import net.mynero.wallet.util.UriData;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInfoAdapterListener, SendBottomSheetDialog.Listener { public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInfoAdapterListener, SendBottomSheetDialog.Listener {
@ -70,7 +71,7 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
}); });
sendUtxosButton.setOnClickListener(view1 -> { sendUtxosButton.setOnClickListener(view1 -> {
ArrayList<String> selectedKeyImages = new ArrayList<>(); ArrayList<String> selectedKeyImages = new ArrayList<>();
for(CoinsInfo coinsInfo : adapter.getSelectedUtxos()) { for(CoinsInfo coinsInfo : adapter.getSelectedUtxos().values()) {
selectedKeyImages.add(coinsInfo.getKeyImage()); selectedKeyImages.add(coinsInfo.getKeyImage());
} }
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog(); SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
@ -80,7 +81,7 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
}); });
churnUtxosButton.setOnClickListener(view1 -> { churnUtxosButton.setOnClickListener(view1 -> {
ArrayList<String> selectedKeyImages = new ArrayList<>(); ArrayList<String> selectedKeyImages = new ArrayList<>();
for(CoinsInfo coinsInfo : adapter.getSelectedUtxos()) { for(CoinsInfo coinsInfo : adapter.getSelectedUtxos().values()) {
selectedKeyImages.add(coinsInfo.getKeyImage()); selectedKeyImages.add(coinsInfo.getKeyImage());
} }
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog(); SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
@ -99,13 +100,12 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
utxosRecyclerView.setAdapter(adapter); utxosRecyclerView.setAdapter(adapter);
if (utxoService != null) { if (utxoService != null) {
utxoService.utxos.observe(getViewLifecycleOwner(), utxos -> { utxoService.utxos.observe(getViewLifecycleOwner(), utxos -> {
ArrayList<CoinsInfo> filteredUtxos = new ArrayList<>(); HashMap<String, CoinsInfo> filteredUtxos = new HashMap<>();
for (CoinsInfo coinsInfo : utxos) { for (CoinsInfo coinsInfo : utxos) {
if (!coinsInfo.isSpent()) { if (!coinsInfo.isSpent()) {
filteredUtxos.add(coinsInfo); filteredUtxos.put(coinsInfo.getPubKey(), coinsInfo);
} }
} }
Collections.sort(filteredUtxos);
if (filteredUtxos.isEmpty()) { if (filteredUtxos.isEmpty()) {
utxosRecyclerView.setVisibility(View.GONE); utxosRecyclerView.setVisibility(View.GONE);
} else { } else {
@ -126,7 +126,7 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
} }
boolean frozenExists = false, unfrozenExists = false, bothExist = false; boolean frozenExists = false, unfrozenExists = false, bothExist = false;
for(CoinsInfo selectedUtxo : adapter.getSelectedUtxos()) { for(CoinsInfo selectedUtxo : adapter.getSelectedUtxos().values()) {
if(selectedUtxo.isFrozen()) if(selectedUtxo.isFrozen())
frozenExists = true; frozenExists = true;
else { else {

View file

@ -13,6 +13,7 @@ import net.mynero.wallet.model.WalletManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
public class UTXOService extends ServiceBase { public class UTXOService extends ServiceBase {
@ -37,9 +38,9 @@ public class UTXOService extends ServiceBase {
return WalletManager.getInstance().getWallet().getCoins().getAll(); return WalletManager.getInstance().getWallet().getCoins().getAll();
} }
public void toggleFrozen(List<CoinsInfo> selectedCoins) { public void toggleFrozen(HashMap<String, CoinsInfo> selectedCoins) {
Coins coins = WalletManager.getInstance().getWallet().getCoins(); Coins coins = WalletManager.getInstance().getWallet().getCoins();
for(CoinsInfo coin : selectedCoins) { for(CoinsInfo coin : selectedCoins.values()) {
coins.setFrozen(coin.getPubKey(), !coin.isFrozen()); coins.setFrozen(coin.getPubKey(), !coin.isFrozen());
} }
refreshUtxos(); refreshUtxos();