Convert adapters to Kotlin

This commit is contained in:
pokkst 2023-12-06 10:57:54 -06:00
parent 19b5a55932
commit 68dfd3797c
No known key found for this signature in database
GPG key ID: EC4FAAA66859FAA4
5 changed files with 371 additions and 422 deletions

View file

@ -13,176 +13,170 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.mynero.wallet.adapter
package net.mynero.wallet.adapter; import android.view.LayoutInflater
import android.view.View
import android.view.View.OnLongClickListener
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import net.mynero.wallet.R
import net.mynero.wallet.model.CoinsInfo
import net.mynero.wallet.model.Wallet
import net.mynero.wallet.service.PrefService
import net.mynero.wallet.service.UTXOService
import net.mynero.wallet.util.Constants
import android.view.LayoutInflater; class CoinsInfoAdapter(val listener: CoinsInfoAdapterListener?) :
import android.view.View; RecyclerView.Adapter<CoinsInfoAdapter.ViewHolder>() {
import android.view.ViewGroup; private var localDataSet // <public-key, coinsinfo>
import android.widget.TextView; : List<CoinsInfo>
@JvmField
import androidx.annotation.NonNull; val selectedUtxos // <public-key, coinsinfo>
import androidx.core.content.ContextCompat; : HashMap<String?, CoinsInfo>
import androidx.recyclerview.widget.RecyclerView; private var editing = false
import net.mynero.wallet.R;
import net.mynero.wallet.model.CoinsInfo;
import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.service.UTXOService;
import net.mynero.wallet.util.Constants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class CoinsInfoAdapter extends RecyclerView.Adapter<CoinsInfoAdapter.ViewHolder> {
private List<CoinsInfo> localDataSet; // <public-key, coinsinfo>
private final HashMap<String, CoinsInfo> selectedUtxos; // <public-key, coinsinfo>
private CoinsInfoAdapterListener listener = null;
private boolean editing = false;
/** /**
* Initialize the dataset of the Adapter. * Initialize the dataset of the Adapter.
*/ */
public CoinsInfoAdapter(CoinsInfoAdapterListener listener) { init {
this.listener = listener; localDataSet = ArrayList()
this.localDataSet = new ArrayList<>(); selectedUtxos = HashMap()
this.selectedUtxos = new HashMap<>();
} }
public void submitList(HashMap<String, CoinsInfo> dataSet) { fun submitList(dataSet: HashMap<String?, CoinsInfo>) {
this.localDataSet = new ArrayList<>(dataSet.values()); localDataSet = ArrayList(dataSet.values)
notifyDataSetChanged(); notifyDataSetChanged()
} }
public void deselectUtxo(CoinsInfo coinsInfo) { fun deselectUtxo(coinsInfo: CoinsInfo) {
this.selectedUtxos.remove(coinsInfo.pubKey); selectedUtxos.remove(coinsInfo.pubKey)
if (selectedUtxos.size == 0) {
if(this.selectedUtxos.size() == 0) { editing = false
editing = false; }
notifyDataSetChanged()
} }
notifyDataSetChanged(); fun selectUtxo(coinsInfo: CoinsInfo) {
editing = true
selectedUtxos[coinsInfo.pubKey] = coinsInfo
notifyDataSetChanged()
} }
public void selectUtxo(CoinsInfo coinsInfo) { operator fun contains(coinsInfo: CoinsInfo): Boolean {
editing = true; return selectedUtxos.containsKey(coinsInfo.pubKey)
this.selectedUtxos.put(coinsInfo.pubKey, coinsInfo);
notifyDataSetChanged();
} }
public boolean contains(CoinsInfo coinsInfo) { fun clear() {
return selectedUtxos.containsKey(coinsInfo.pubKey); selectedUtxos.clear()
} editing = false
notifyDataSetChanged()
public void clear() {
this.selectedUtxos.clear();
editing = false;
notifyDataSetChanged();
}
public HashMap<String, CoinsInfo> getSelectedUtxos() {
return selectedUtxos;
} }
// Create new views (invoked by the layout manager) // Create new views (invoked by the layout manager)
@Override override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item // Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext()) val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.utxo_selection_item, viewGroup, false); .inflate(R.layout.utxo_selection_item, viewGroup, false)
return ViewHolder(listener, 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 fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
public void onBindViewHolder(ViewHolder viewHolder, final int position) { val tx = localDataSet[position]
CoinsInfo tx = localDataSet.get(position); viewHolder.bind(editing, tx, 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)
@Override override fun getItemCount(): Int {
public int getItemCount() { return localDataSet.size
return localDataSet.size();
} }
public interface CoinsInfoAdapterListener { interface CoinsInfoAdapterListener {
void onUtxoSelected(CoinsInfo coinsInfo); fun onUtxoSelected(coinsInfo: CoinsInfo?)
} }
/** /**
* 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 implements View.OnClickListener, View.OnLongClickListener { class ViewHolder(private val listener: CoinsInfoAdapterListener?, view: View) :
private CoinsInfo coinsInfo; RecyclerView.ViewHolder(view), View.OnClickListener, OnLongClickListener {
private boolean editing = false; private var coinsInfo: CoinsInfo? = null
private final CoinsInfoAdapterListener listener; private var editing = false
public ViewHolder(CoinsInfoAdapterListener listener, View view) { init {
super(view); view.setOnClickListener(this)
this.listener = listener; view.setOnLongClickListener(this)
view.setOnClickListener(this);
view.setOnLongClickListener(this);
} }
public void bind(boolean editing, CoinsInfo coinsInfo, HashMap<String, CoinsInfo> selectedUtxos) { fun bind(
this.editing = editing; editing: Boolean,
this.coinsInfo = coinsInfo; coinsInfo: CoinsInfo,
boolean selected = selectedUtxos.containsKey(coinsInfo.pubKey); selectedUtxos: HashMap<String?, CoinsInfo>
) {
TextView pubKeyTextView = itemView.findViewById(R.id.utxo_pub_key_textview); this.editing = editing
TextView amountTextView = itemView.findViewById(R.id.utxo_amount_textview); this.coinsInfo = coinsInfo
TextView addressTextView = itemView.findViewById(R.id.utxo_address_textview); val selected = selectedUtxos.containsKey(coinsInfo.pubKey)
TextView globalIdxTextView = itemView.findViewById(R.id.utxo_global_index_textview); val pubKeyTextView = itemView.findViewById<TextView>(R.id.utxo_pub_key_textview)
TextView outpointTextView = itemView.findViewById(R.id.utxo_outpoint_textview); val amountTextView = itemView.findViewById<TextView>(R.id.utxo_amount_textview)
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false); val addressTextView = itemView.findViewById<TextView>(R.id.utxo_address_textview)
String balanceString = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Wallet.getDisplayAmount(coinsInfo.amount); val globalIdxTextView = itemView.findViewById<TextView>(R.id.utxo_global_index_textview)
amountTextView.setText(itemView.getResources().getString(R.string.tx_amount_no_prefix, balanceString)); val outpointTextView = itemView.findViewById<TextView>(R.id.utxo_outpoint_textview)
pubKeyTextView.setText(coinsInfo.pubKey); val streetModeEnabled =
addressTextView.setText(coinsInfo.address); PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false)
globalIdxTextView.setText(itemView.getResources().getString(R.string.global_index_text, coinsInfo.globalOutputIndex)); val balanceString =
outpointTextView.setText(itemView.getResources().getString(R.string.outpoint_text, coinsInfo.hash + ":" + coinsInfo.localOutputIndex)); if (streetModeEnabled) Constants.STREET_MODE_BALANCE else Wallet.getDisplayAmount(
coinsInfo.amount
)
amountTextView.text =
itemView.resources.getString(R.string.tx_amount_no_prefix, balanceString)
pubKeyTextView.text = coinsInfo.pubKey
addressTextView.text = coinsInfo.address
globalIdxTextView.text =
itemView.resources.getString(
R.string.global_index_text,
coinsInfo.globalOutputIndex
)
outpointTextView.text = itemView.resources.getString(
R.string.outpoint_text,
coinsInfo.hash + ":" + coinsInfo.localOutputIndex
)
if (selected) { if (selected) {
itemView.setBackgroundTintList(ContextCompat.getColorStateList(itemView.getContext(), R.color.oled_colorSecondary)); itemView.backgroundTintList =
} else if(coinsInfo.isFrozen() || UTXOService.instance.isCoinFrozen(coinsInfo)) { ContextCompat.getColorStateList(itemView.context, R.color.oled_colorSecondary)
itemView.setBackgroundTintList(ContextCompat.getColorStateList(itemView.getContext(), R.color.oled_frozen_utxo)); } else if (coinsInfo.isFrozen || UTXOService.instance.isCoinFrozen(coinsInfo)) {
} else if (!coinsInfo.isUnlocked()) { itemView.backgroundTintList =
itemView.setBackgroundTintList(ContextCompat.getColorStateList(itemView.getContext(), R.color.oled_locked_utxo)); ContextCompat.getColorStateList(itemView.context, R.color.oled_frozen_utxo)
} else if (!coinsInfo.isUnlocked) {
itemView.backgroundTintList =
ContextCompat.getColorStateList(itemView.context, R.color.oled_locked_utxo)
} else { } else {
itemView.setBackgroundTintList(ContextCompat.getColorStateList(itemView.getContext(), R.color.oled_dialogBackgroundColor)); itemView.backgroundTintList =
ContextCompat.getColorStateList(
itemView.context,
R.color.oled_dialogBackgroundColor
)
} }
} }
@Override override fun onClick(view: View) {
public void onClick(View view) { if (!editing) return
if(!editing) return; val unlocked = coinsInfo?.isUnlocked == true
boolean unlocked = coinsInfo.isUnlocked();
if (unlocked) { if (unlocked) {
listener.onUtxoSelected(coinsInfo); listener?.onUtxoSelected(coinsInfo)
} }
} }
@Override override fun onLongClick(view: View): Boolean {
public boolean onLongClick(View view) { if (editing) return false
if(editing) return false; val unlocked = coinsInfo?.isUnlocked == true
boolean unlocked = coinsInfo.isUnlocked();
if (unlocked) { if (unlocked) {
listener.onUtxoSelected(coinsInfo); listener?.onUtxoSelected(coinsInfo)
} }
return unlocked; return unlocked
}
@Override
public boolean onLongClickUseDefaultHapticFeedback(@NonNull View v) {
return View.OnLongClickListener.super.onLongClickUseDefaultHapticFeedback(v);
} }
} }
} }

View file

@ -13,140 +13,127 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.mynero.wallet.adapter
package net.mynero.wallet.adapter; import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import net.mynero.wallet.R
import net.mynero.wallet.data.DefaultNodes
import net.mynero.wallet.data.Node
import net.mynero.wallet.service.PrefService
import android.view.LayoutInflater; class NodeSelectionAdapter(val listener: NodeSelectionAdapterListener?) :
import android.view.View; RecyclerView.Adapter<NodeSelectionAdapter.ViewHolder>() {
import android.view.ViewGroup; private var localDataSet: List<Node>
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import net.mynero.wallet.R;
import net.mynero.wallet.data.DefaultNodes;
import net.mynero.wallet.data.Node;
import net.mynero.wallet.service.PrefService;
import java.util.ArrayList;
import java.util.List;
public class NodeSelectionAdapter extends RecyclerView.Adapter<NodeSelectionAdapter.ViewHolder> {
private List<Node> localDataSet;
private NodeSelectionAdapterListener listener = null;
/** /**
* Initialize the dataset of the Adapter. * Initialize the dataset of the Adapter.
*/ */
public NodeSelectionAdapter(NodeSelectionAdapterListener listener) { init {
this.listener = listener; localDataSet = ArrayList()
this.localDataSet = new ArrayList<>();
} }
public void submitList(List<Node> dataSet) { fun submitList(dataSet: List<Node>) {
this.localDataSet = dataSet; localDataSet = dataSet
notifyDataSetChanged(); notifyDataSetChanged()
} }
public void updateSelectedNode() { fun updateSelectedNode() {
notifyDataSetChanged(); notifyDataSetChanged()
} }
// Create new views (invoked by the layout manager) // Create new views (invoked by the layout manager)
@Override override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item // Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext()) val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.node_selection_item, viewGroup, false); .inflate(R.layout.node_selection_item, viewGroup, false)
return ViewHolder(listener, 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 fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
public void onBindViewHolder(ViewHolder viewHolder, final int position) { val node = localDataSet[position]
Node node = localDataSet.get(position); viewHolder.bind(node)
viewHolder.bind(node);
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@Override override fun getItemCount(): Int {
public int getItemCount() { return localDataSet.size
return localDataSet.size();
} }
public interface NodeSelectionAdapterListener { interface NodeSelectionAdapterListener {
void onSelectNode(Node node); fun onSelectNode(node: Node?)
boolean onSelectEditNode(Node node); fun onSelectEditNode(node: Node?): Boolean
} }
/** /**
* 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 { class ViewHolder(private val listener: NodeSelectionAdapterListener?, view: View) :
private final NodeSelectionAdapterListener listener; RecyclerView.ViewHolder(
view
public ViewHolder(NodeSelectionAdapterListener listener, View view) { ) {
super(view); fun bind(node: Node) {
this.listener = listener; val currentNode = PrefService.getInstance().node
} val match = node == currentNode
public void bind(Node node) {
Node currentNode = PrefService.getInstance().getNode();
boolean match = node.equals(currentNode);
if (match) { if (match) {
itemView.setBackgroundColor(itemView.getResources().getColor(R.color.oled_colorSecondary)); itemView.setBackgroundColor(itemView.resources.getColor(R.color.oled_colorSecondary))
} else { } else {
itemView.setBackgroundColor(itemView.getResources().getColor(android.R.color.transparent)); itemView.setBackgroundColor(itemView.resources.getColor(android.R.color.transparent))
} }
TextView nodeNameTextView = itemView.findViewById(R.id.node_name_textview); val nodeNameTextView = itemView.findViewById<TextView>(R.id.node_name_textview)
TextView nodeAddressTextView = itemView.findViewById(R.id.node_uri_textview); val nodeAddressTextView = itemView.findViewById<TextView>(R.id.node_uri_textview)
TextView authTextView = itemView.findViewById(R.id.authenticated_textview); val authTextView = itemView.findViewById<TextView>(R.id.authenticated_textview)
nodeNameTextView.setText(node.getName()); nodeNameTextView.text = node.name
nodeAddressTextView.setText(node.getAddress()); nodeAddressTextView.text = node.address
if(!node.getPassword().isEmpty()) { if (node.password.isNotEmpty()) {
authTextView.setVisibility(View.VISIBLE); authTextView.visibility = View.VISIBLE
} }
ImageView nodeAnonymityNetworkImageView = itemView.findViewById(R.id.anonymity_network_imageview); val nodeAnonymityNetworkImageView =
itemView.findViewById<ImageView>(R.id.anonymity_network_imageview)
if(node.isOnion()) { if (node.isOnion) {
nodeAnonymityNetworkImageView.setVisibility(View.VISIBLE); nodeAnonymityNetworkImageView.visibility = View.VISIBLE
nodeAnonymityNetworkImageView.setImageResource(R.drawable.tor); nodeAnonymityNetworkImageView.setImageResource(R.drawable.tor)
} else if(node.isI2P()) { } else if (node.isI2P) {
nodeAnonymityNetworkImageView.setVisibility(View.VISIBLE); nodeAnonymityNetworkImageView.visibility = View.VISIBLE
nodeAnonymityNetworkImageView.setImageResource(R.drawable.i2p); nodeAnonymityNetworkImageView.setImageResource(R.drawable.i2p)
} else { } else {
nodeAnonymityNetworkImageView.setVisibility(View.GONE); nodeAnonymityNetworkImageView.visibility = View.GONE
} }
itemView.setOnLongClickListener {
itemView.setOnLongClickListener(view -> {
if (match) { if (match) {
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_current_node), Toast.LENGTH_SHORT).show(); Toast.makeText(
return true; itemView.context,
itemView.resources.getString(R.string.cant_edit_current_node),
Toast.LENGTH_SHORT
).show()
return@setOnLongClickListener true
} else if (isDefaultNode(node)) { } else if (isDefaultNode(node)) {
Toast.makeText(itemView.getContext(), itemView.getResources().getString(R.string.cant_edit_default_nodes), Toast.LENGTH_SHORT).show(); Toast.makeText(
return true; itemView.context,
itemView.resources.getString(R.string.cant_edit_default_nodes),
Toast.LENGTH_SHORT
).show()
return@setOnLongClickListener true
} else { } else {
return listener.onSelectEditNode(node); return@setOnLongClickListener listener?.onSelectEditNode(node) == true
} }
}); }
itemView.setOnClickListener(view -> listener.onSelectNode(node)); itemView.setOnClickListener { listener?.onSelectNode(node) }
} }
private boolean isDefaultNode(Node currentNode) { private fun isDefaultNode(currentNode: Node): Boolean {
boolean isDefault = false; var isDefault = false
for(DefaultNodes defaultNode : DefaultNodes.values()) { for (defaultNode in DefaultNodes.values()) {
if(currentNode.toNodeString().equals(defaultNode.getNodeString())) if (currentNode.toNodeString() == defaultNode.nodeString) isDefault = true
isDefault = true;
} }
return isDefault
return isDefault;
} }
} }
} }

View file

@ -13,119 +13,102 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.mynero.wallet.adapter
package net.mynero.wallet.adapter; import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import net.mynero.wallet.R
import net.mynero.wallet.data.Subaddress
import net.mynero.wallet.service.PrefService
import net.mynero.wallet.util.Constants
import net.mynero.wallet.util.Helper
import net.mynero.wallet.util.Helper.getDisplayAmount
import android.view.LayoutInflater; class SubaddressAdapter(val listener: SubaddressAdapterListener?) :
import android.view.View; RecyclerView.Adapter<SubaddressAdapter.ViewHolder>() {
import android.view.ViewGroup; private var localDataSet: List<Subaddress>
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import net.mynero.wallet.R;
import net.mynero.wallet.data.Subaddress;
import net.mynero.wallet.model.CoinsInfo;
import net.mynero.wallet.model.Wallet;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants;
import net.mynero.wallet.util.Helper;
import java.util.ArrayList;
import java.util.List;
public class SubaddressAdapter extends RecyclerView.Adapter<SubaddressAdapter.ViewHolder> {
private List<Subaddress> localDataSet;
private SubaddressAdapterListener listener = null;
/** /**
* Initialize the dataset of the Adapter. * Initialize the dataset of the Adapter.
*/ */
public SubaddressAdapter(SubaddressAdapterListener listener) { init {
this.localDataSet = new ArrayList<>(); localDataSet = ArrayList()
this.listener = listener;
} }
public void submitList(List<Subaddress> dataSet) { fun submitList(dataSet: List<Subaddress>) {
this.localDataSet = dataSet; localDataSet = dataSet
notifyDataSetChanged(); notifyDataSetChanged()
} }
// Create new views (invoked by the layout manager) // Create new views (invoked by the layout manager)
@Override override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item // Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext()) val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.address_item, viewGroup, false); .inflate(R.layout.address_item, viewGroup, false)
return ViewHolder(view, listener)
return new ViewHolder(view, listener);
} }
// Replace the contents of a view (invoked by the layout manager) // Replace the contents of a view (invoked by the layout manager)
@Override override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
public void onBindViewHolder(ViewHolder viewHolder, final int position) { val subaddress = localDataSet[position]
Subaddress subaddress = localDataSet.get(position); viewHolder.bind(subaddress)
viewHolder.bind(subaddress);
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@Override override fun getItemCount(): Int {
public int getItemCount() { return localDataSet.size
return localDataSet.size();
} }
public interface SubaddressAdapterListener { interface SubaddressAdapterListener {
void onSubaddressSelected(Subaddress subaddress); fun onSubaddressSelected(subaddress: Subaddress?)
fun onSubaddressEditLabel(subaddress: Subaddress?)
void onSubaddressEditLabel(Subaddress subaddress);
} }
/** /**
* 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 { class ViewHolder(view: View, val listener: SubaddressAdapterListener?) : RecyclerView.ViewHolder(
private SubaddressAdapterListener listener = null; view
) {
public ViewHolder(View view, SubaddressAdapterListener listener) { fun bind(subaddress: Subaddress) {
super(view); val addressTextView =
this.listener = listener; itemView.findViewById<TextView>(R.id.address_item_address_textview)
} val addressLabelTextView = itemView.findViewById<TextView>(R.id.address_label_textview)
val addressAmountTextView =
public void bind(Subaddress subaddress) { itemView.findViewById<TextView>(R.id.address_amount_textview)
TextView addressTextView = itemView.findViewById(R.id.address_item_address_textview); addressTextView.text = subaddress.address
TextView addressLabelTextView = itemView.findViewById(R.id.address_label_textview); val label = subaddress.displayLabel
TextView addressAmountTextView = itemView.findViewById(R.id.address_amount_textview); val address = itemView.context.getString(
R.string.subbaddress_info_subtitle,
addressTextView.setText(subaddress.address); subaddress.addressIndex, subaddress.squashedAddress
)
final String label = subaddress.getDisplayLabel(); addressLabelTextView.text = label.ifEmpty { address }
final String address = itemView.getContext().getString(R.string.subbaddress_info_subtitle, val amount = subaddress.amount
subaddress.addressIndex, subaddress.getSquashedAddress());
addressLabelTextView.setText(label.isEmpty() ? address : label);
final long amount = subaddress.amount;
if (amount > 0) { if (amount > 0) {
boolean streetMode = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false); val streetMode =
PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false)
if (streetMode) { if (streetMode) {
addressAmountTextView.setText(itemView.getContext().getString(R.string.tx_list_amount_positive, addressAmountTextView.text = itemView.context.getString(
Constants.STREET_MODE_BALANCE)); R.string.tx_list_amount_positive,
Constants.STREET_MODE_BALANCE
)
} else { } else {
addressAmountTextView.setText(itemView.getContext().getString(R.string.tx_list_amount_positive, addressAmountTextView.text = itemView.context.getString(
Helper.getDisplayAmount(amount, Helper.DISPLAY_DIGITS_INFO))); R.string.tx_list_amount_positive,
getDisplayAmount(amount, Helper.DISPLAY_DIGITS_INFO)
)
}
} else addressAmountTextView.text = ""
itemView.setOnClickListener { listener?.onSubaddressSelected(subaddress) }
itemView.setOnLongClickListener { _: View? ->
listener?.onSubaddressEditLabel(subaddress)
true
} }
}
else
addressAmountTextView.setText("");
itemView.setOnClickListener(view -> listener.onSubaddressSelected(subaddress));
itemView.setOnLongClickListener(v -> {
listener.onSubaddressEditLabel(subaddress);
return true;
});
} }
} }
} }

View file

@ -13,164 +13,149 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package net.mynero.wallet.adapter
package net.mynero.wallet.adapter; import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.progressindicator.CircularProgressIndicator
import net.mynero.wallet.R
import net.mynero.wallet.model.TransactionInfo
import net.mynero.wallet.service.PrefService
import net.mynero.wallet.util.Constants
import net.mynero.wallet.util.DateHelper.DATETIME_FORMATTER
import net.mynero.wallet.util.Helper
import net.mynero.wallet.util.Helper.getDisplayAmount
import net.mynero.wallet.util.ThemeHelper.getThemedColor
import java.util.Calendar
import java.util.Date
import static net.mynero.wallet.util.DateHelper.DATETIME_FORMATTER; class TransactionInfoAdapter(val listener: TxInfoAdapterListener?) :
RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder>() {
import android.text.Html; private var localDataSet: List<TransactionInfo>
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.progressindicator.CircularProgressIndicator;
import net.mynero.wallet.R;
import net.mynero.wallet.model.TransactionInfo;
import net.mynero.wallet.service.PrefService;
import net.mynero.wallet.util.Constants;
import net.mynero.wallet.util.Helper;
import net.mynero.wallet.util.ThemeHelper;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfoAdapter.ViewHolder> {
private List<TransactionInfo> localDataSet;
private TxInfoAdapterListener listener = null;
/** /**
* Initialize the dataset of the Adapter. * Initialize the dataset of the Adapter.
*/ */
public TransactionInfoAdapter(TxInfoAdapterListener listener) { init {
this.listener = listener; localDataSet = ArrayList()
this.localDataSet = new ArrayList<>();
} }
public void submitList(List<TransactionInfo> dataSet) { fun submitList(dataSet: List<TransactionInfo>) {
this.localDataSet = dataSet; localDataSet = dataSet
notifyDataSetChanged(); notifyDataSetChanged()
} }
// Create new views (invoked by the layout manager) // Create new views (invoked by the layout manager)
@Override override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item // Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext()) val view = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.transaction_history_item, viewGroup, false); .inflate(R.layout.transaction_history_item, viewGroup, false)
return ViewHolder(listener, 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 fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
public void onBindViewHolder(ViewHolder viewHolder, final int position) { val tx = localDataSet[position]
TransactionInfo tx = localDataSet.get(position); viewHolder.bind(tx)
viewHolder.bind(tx);
} }
// Return the size of your dataset (invoked by the layout manager) // Return the size of your dataset (invoked by the layout manager)
@Override override fun getItemCount(): Int {
public int getItemCount() { return localDataSet.size
return localDataSet.size();
} }
public interface TxInfoAdapterListener { interface TxInfoAdapterListener {
void onClickTransaction(TransactionInfo txInfo); fun onClickTransaction(txInfo: TransactionInfo?)
} }
/** /**
* 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 { class ViewHolder(val listener: TxInfoAdapterListener?, view: View) : RecyclerView.ViewHolder(view) {
private final int outboundColour; private val outboundColour: Int
private final int inboundColour; private val inboundColour: Int
private final int pendingColour; private val pendingColour: Int
private final int failedColour; private val failedColour: Int
private TxInfoAdapterListener listener = null; private var amountTextView: TextView? = null
private TextView amountTextView = null;
public ViewHolder(TxInfoAdapterListener listener, View view) { init {
super(view); inboundColour = getThemedColor(view.context, R.attr.positiveColor)
inboundColour = ThemeHelper.getThemedColor(view.getContext(), R.attr.positiveColor); outboundColour = getThemedColor(view.context, R.attr.negativeColor)
outboundColour = ThemeHelper.getThemedColor(view.getContext(), R.attr.negativeColor); pendingColour = getThemedColor(view.context, R.attr.neutralColor)
pendingColour = ThemeHelper.getThemedColor(view.getContext(), R.attr.neutralColor); failedColour = getThemedColor(view.context, R.attr.neutralColor)
failedColour = ThemeHelper.getThemedColor(view.getContext(), R.attr.neutralColor); val cal = Calendar.getInstance()
this.listener = listener; val tz = cal.timeZone //get the local time zone.
Calendar cal = Calendar.getInstance(); DATETIME_FORMATTER.timeZone = tz
TimeZone tz = cal.getTimeZone(); //get the local time zone.
DATETIME_FORMATTER.setTimeZone(tz);
} }
public void bind(TransactionInfo txInfo) { fun bind(txInfo: TransactionInfo) {
boolean streetModeEnabled = PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false); val streetModeEnabled =
String displayAmount = streetModeEnabled ? Constants.STREET_MODE_BALANCE : Helper.getDisplayAmount(txInfo.amount, Helper.DISPLAY_DIGITS_INFO); PrefService.getInstance().getBoolean(Constants.PREF_STREET_MODE, false)
TextView confirmationsTextView = itemView.findViewById(R.id.tvConfirmations); val displayAmount =
CircularProgressIndicator confirmationsProgressBar = itemView.findViewById(R.id.pbConfirmations); if (streetModeEnabled) Constants.STREET_MODE_BALANCE else getDisplayAmount(
confirmationsProgressBar.setMax(TransactionInfo.CONFIRMATION); txInfo.amount,
this.amountTextView = itemView.findViewById(R.id.tx_amount); Helper.DISPLAY_DIGITS_INFO
itemView.findViewById(R.id.tx_failed).setVisibility(View.GONE); )
val confirmationsTextView = itemView.findViewById<TextView>(R.id.tvConfirmations)
val confirmationsProgressBar =
itemView.findViewById<CircularProgressIndicator>(R.id.pbConfirmations)
confirmationsProgressBar.max = TransactionInfo.CONFIRMATION
amountTextView = itemView.findViewById(R.id.tx_amount)
itemView.findViewById<View>(R.id.tx_failed).visibility = View.GONE
if (txInfo.isFailed) { if (txInfo.isFailed) {
((TextView) itemView.findViewById(R.id.tx_amount)).setText(itemView.getContext().getString(R.string.tx_list_amount_negative, displayAmount)); (itemView.findViewById<View>(R.id.tx_amount) as TextView).text =
itemView.findViewById(R.id.tx_failed).setVisibility(View.VISIBLE); itemView.context.getString(R.string.tx_list_amount_negative, displayAmount)
setTxColour(failedColour); itemView.findViewById<View>(R.id.tx_failed).visibility = View.VISIBLE
confirmationsTextView.setVisibility(View.GONE); setTxColour(failedColour)
confirmationsProgressBar.setVisibility(View.GONE); confirmationsTextView.visibility = View.GONE
confirmationsProgressBar.visibility = View.GONE
} else if (txInfo.isPending) { } else if (txInfo.isPending) {
setTxColour(pendingColour); setTxColour(pendingColour)
confirmationsProgressBar.setIndeterminate(true); confirmationsProgressBar.isIndeterminate = true
confirmationsProgressBar.setVisibility(View.VISIBLE); confirmationsProgressBar.visibility = View.VISIBLE
confirmationsTextView.setVisibility(View.GONE); confirmationsTextView.visibility = View.GONE
} else if (txInfo.direction == TransactionInfo.Direction.Direction_In) { } else if (txInfo.direction == TransactionInfo.Direction.Direction_In) {
setTxColour(inboundColour); setTxColour(inboundColour)
if (!txInfo.isConfirmed()) { if (!txInfo.isConfirmed) {
confirmationsProgressBar.setVisibility(View.VISIBLE); confirmationsProgressBar.visibility = View.VISIBLE
final int confirmations = (int) txInfo.confirmations; val confirmations = txInfo.confirmations.toInt()
confirmationsProgressBar.setProgressCompat(confirmations, true); confirmationsProgressBar.setProgressCompat(confirmations, true)
final String confCount = Integer.toString(confirmations); val confCount = confirmations.toString()
confirmationsTextView.setText(confCount); confirmationsTextView.text = confCount
if (confCount.length() == 1) // we only have space for character in the progress circle if (confCount.length == 1) // we only have space for character in the progress circle
confirmationsTextView.setVisibility(View.VISIBLE); confirmationsTextView.visibility =
else View.VISIBLE else confirmationsTextView.visibility = View.GONE
confirmationsTextView.setVisibility(View.GONE);
} else { } else {
confirmationsProgressBar.setVisibility(View.GONE); confirmationsProgressBar.visibility = View.GONE
confirmationsTextView.setVisibility(View.GONE); confirmationsTextView.visibility = View.GONE
} }
} else { } else {
setTxColour(outboundColour); setTxColour(outboundColour)
confirmationsProgressBar.setVisibility(View.GONE); confirmationsProgressBar.visibility = View.GONE
confirmationsTextView.setVisibility(View.GONE); confirmationsTextView.visibility = View.GONE
} }
if (txInfo.direction == TransactionInfo.Direction.Direction_Out) { if (txInfo.direction == TransactionInfo.Direction.Direction_Out) {
((TextView) itemView.findViewById(R.id.tx_amount)).setText(itemView.getContext().getString(R.string.tx_list_amount_negative, displayAmount)); (itemView.findViewById<View>(R.id.tx_amount) as TextView).text =
itemView.context.getString(R.string.tx_list_amount_negative, displayAmount)
} else { } else {
((TextView) itemView.findViewById(R.id.tx_amount)).setText(itemView.getContext().getString(R.string.tx_list_amount_positive, displayAmount)); (itemView.findViewById<View>(R.id.tx_amount) as TextView).text =
itemView.context.getString(R.string.tx_list_amount_positive, displayAmount)
}
(itemView.findViewById<View>(R.id.tx_datetime) as TextView).text =
getDateTime(txInfo.timestamp)
itemView.setOnClickListener { _: View? -> listener?.onClickTransaction(txInfo) }
} }
((TextView) itemView.findViewById(R.id.tx_datetime)).setText(getDateTime(txInfo.timestamp)); private fun setTxColour(clr: Int) {
itemView.setOnClickListener(view -> { amountTextView?.setTextColor(clr)
listener.onClickTransaction(txInfo);
});
} }
private void setTxColour(int clr) { private fun getDateTime(time: Long): String {
amountTextView.setTextColor(clr); return DATETIME_FORMATTER.format(Date(time * 1000))
}
private String getDateTime(long time) {
return DATETIME_FORMATTER.format(new Date(time * 1000));
} }
} }
} }

View file

@ -60,7 +60,7 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
freezeUtxosButton.setOnClickListener(view1 -> { freezeUtxosButton.setOnClickListener(view1 -> {
Toast.makeText(getContext(), "Toggling freeze status, please wait.", Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), "Toggling freeze status, please wait.", Toast.LENGTH_SHORT).show();
MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR.execute(() -> { MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR.execute(() -> {
UTXOService.getInstance().toggleFrozen(adapter.getSelectedUtxos()); UTXOService.getInstance().toggleFrozen(adapter.selectedUtxos);
getActivity().runOnUiThread(() -> { getActivity().runOnUiThread(() -> {
adapter.clear(); adapter.clear();
sendUtxosButton.setVisibility(View.GONE); sendUtxosButton.setVisibility(View.GONE);
@ -71,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().values()) { for(CoinsInfo coinsInfo : adapter.selectedUtxos.values()) {
selectedKeyImages.add(coinsInfo.keyImage); selectedKeyImages.add(coinsInfo.keyImage);
} }
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog(); SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
@ -81,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().values()) { for(CoinsInfo coinsInfo : adapter.selectedUtxos.values()) {
selectedKeyImages.add(coinsInfo.keyImage); selectedKeyImages.add(coinsInfo.keyImage);
} }
SendBottomSheetDialog sendDialog = new SendBottomSheetDialog(); SendBottomSheetDialog sendDialog = new SendBottomSheetDialog();
@ -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().values()) { for(CoinsInfo selectedUtxo : adapter.selectedUtxos.values()) {
if(selectedUtxo.isFrozen() || UTXOService.getInstance().isCoinFrozen(selectedUtxo)) if(selectedUtxo.isFrozen() || UTXOService.getInstance().isCoinFrozen(selectedUtxo))
frozenExists = true; frozenExists = true;
else { else {
@ -135,7 +135,7 @@ public class UtxosFragment extends Fragment implements CoinsInfoAdapter.CoinsInf
} }
bothExist = frozenExists && unfrozenExists; bothExist = frozenExists && unfrozenExists;
if (adapter.getSelectedUtxos().isEmpty()) { if (adapter.selectedUtxos.isEmpty()) {
sendUtxosButton.setVisibility(View.GONE); sendUtxosButton.setVisibility(View.GONE);
churnUtxosButton.setVisibility(View.GONE); churnUtxosButton.setVisibility(View.GONE);
freezeUtxosButton.setVisibility(View.GONE); freezeUtxosButton.setVisibility(View.GONE);