mirror of
https://codeberg.org/anoncontributorxmr/mysu.git
synced 2024-11-21 23:12:26 +00:00
feat: refactor receive fragment
It's now possible to rename latest address without generating a new one
This commit is contained in:
parent
8a769d0e23
commit
f0ba6f5ce5
8 changed files with 44 additions and 57 deletions
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package net.mynero.wallet.adapter
|
package net.mynero.wallet.adapter
|
||||||
|
|
||||||
|
import android.graphics.Typeface
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -26,19 +27,19 @@ import net.mynero.wallet.service.PrefService
|
||||||
import net.mynero.wallet.util.Constants
|
import net.mynero.wallet.util.Constants
|
||||||
import net.mynero.wallet.util.Helper
|
import net.mynero.wallet.util.Helper
|
||||||
|
|
||||||
class SubaddressAdapter(val listener: SubaddressAdapterListener?) :
|
class SubaddressAdapter(
|
||||||
RecyclerView.Adapter<SubaddressAdapter.ViewHolder>() {
|
private var addresses: List<Subaddress>,
|
||||||
private var localDataSet: List<Subaddress>
|
private var selectedAddress: Subaddress?,
|
||||||
|
val listener: SubaddressAdapterListener?
|
||||||
|
): RecyclerView.Adapter<SubaddressAdapter.ViewHolder>() {
|
||||||
|
|
||||||
/**
|
fun submitAddresses(addresses: List<Subaddress>) {
|
||||||
* Initialize the dataset of the Adapter.
|
this.addresses = addresses
|
||||||
*/
|
notifyDataSetChanged()
|
||||||
init {
|
|
||||||
localDataSet = ArrayList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun submitList(dataSet: List<Subaddress>) {
|
fun submitSelectedAddress(selectedAddress: Subaddress?) {
|
||||||
localDataSet = dataSet
|
this.selectedAddress = selectedAddress
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,13 +53,13 @@ class SubaddressAdapter(val listener: SubaddressAdapterListener?) :
|
||||||
|
|
||||||
// Replace the contents of a view (invoked by the layout manager)
|
// Replace the contents of a view (invoked by the layout manager)
|
||||||
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
|
||||||
val subaddress = localDataSet[position]
|
val address = addresses[position]
|
||||||
viewHolder.bind(subaddress)
|
viewHolder.bind(address, selectedAddress != null && address == selectedAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the size of your dataset (invoked by the layout manager)
|
// Return the size of your dataset (invoked by the layout manager)
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return localDataSet.size
|
return addresses.size
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SubaddressAdapterListener {
|
interface SubaddressAdapterListener {
|
||||||
|
@ -71,17 +72,20 @@ class SubaddressAdapter(val listener: SubaddressAdapterListener?) :
|
||||||
* (custom ViewHolder).
|
* (custom ViewHolder).
|
||||||
*/
|
*/
|
||||||
class ViewHolder(view: View, val listener: SubaddressAdapterListener?) :
|
class ViewHolder(view: View, val listener: SubaddressAdapterListener?) :
|
||||||
RecyclerView.ViewHolder(
|
RecyclerView.ViewHolder(view) {
|
||||||
view
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun bind(subaddress: Subaddress) {
|
fun bind(subaddress: Subaddress, isSelected: Boolean) {
|
||||||
val addressTextView =
|
val addressTextView =
|
||||||
itemView.findViewById<TextView>(R.id.address_item_address_textview)
|
itemView.findViewById<TextView>(R.id.address_item_address_textview)
|
||||||
val addressLabelTextView = itemView.findViewById<TextView>(R.id.address_label_textview)
|
val addressLabelTextView = itemView.findViewById<TextView>(R.id.address_label_textview)
|
||||||
val addressAmountTextView =
|
val addressAmountTextView =
|
||||||
itemView.findViewById<TextView>(R.id.address_amount_textview)
|
itemView.findViewById<TextView>(R.id.address_amount_textview)
|
||||||
addressTextView.text = subaddress.address
|
addressTextView.text = subaddress.address
|
||||||
|
if (isSelected) {
|
||||||
|
addressTextView.setTypeface(null, Typeface.BOLD)
|
||||||
|
} else {
|
||||||
|
addressTextView.setTypeface(null, Typeface.NORMAL)
|
||||||
|
}
|
||||||
val label = subaddress.displayLabel
|
val label = subaddress.displayLabel
|
||||||
val address = itemView.context.getString(
|
val address = itemView.context.getString(
|
||||||
R.string.subbaddress_info_subtitle,
|
R.string.subbaddress_info_subtitle,
|
||||||
|
|
|
@ -10,7 +10,6 @@ import android.widget.ImageButton
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
import net.mynero.wallet.R
|
import net.mynero.wallet.R
|
||||||
import net.mynero.wallet.model.WalletManager
|
import net.mynero.wallet.model.WalletManager
|
||||||
import net.mynero.wallet.service.AddressService
|
|
||||||
import net.mynero.wallet.util.Helper.getClipBoardText
|
import net.mynero.wallet.util.Helper.getClipBoardText
|
||||||
import java.text.ParseException
|
import java.text.ParseException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
@ -30,7 +29,6 @@ class EditAddressLabelBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val wallet = WalletManager.instance?.wallet
|
val wallet = WalletManager.instance?.wallet
|
||||||
val addressService = AddressService.instance
|
|
||||||
val pasteButton = view.findViewById<ImageButton>(R.id.paste_password_imagebutton)
|
val pasteButton = view.findViewById<ImageButton>(R.id.paste_password_imagebutton)
|
||||||
val labelEditText = view.findViewById<EditText>(R.id.wallet_password_edittext)
|
val labelEditText = view.findViewById<EditText>(R.id.wallet_password_edittext)
|
||||||
val saveLabelButton = view.findViewById<Button>(R.id.unlock_wallet_button)
|
val saveLabelButton = view.findViewById<Button>(R.id.unlock_wallet_button)
|
||||||
|
@ -50,9 +48,6 @@ class EditAddressLabelBottomSheetDialog : BottomSheetDialogFragment() {
|
||||||
pasteButton.setOnClickListener { labelEditText.setText(getClipBoardText(view.context)) }
|
pasteButton.setOnClickListener { labelEditText.setText(getClipBoardText(view.context)) }
|
||||||
saveLabelButton.setOnClickListener {
|
saveLabelButton.setOnClickListener {
|
||||||
val label = labelEditText.text.toString()
|
val label = labelEditText.text.toString()
|
||||||
if (addressService?.latestAddressIndex == addressIndex) {
|
|
||||||
addressService.freshSubaddress()
|
|
||||||
}
|
|
||||||
wallet?.setSubaddressLabel(addressIndex, label)
|
wallet?.setSubaddressLabel(addressIndex, label)
|
||||||
wallet?.store()
|
wallet?.store()
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
|
|
|
@ -17,7 +17,6 @@ import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.zxing.BarcodeFormat
|
import com.google.zxing.BarcodeFormat
|
||||||
import com.google.zxing.EncodeHintType
|
import com.google.zxing.EncodeHintType
|
||||||
import com.google.zxing.WriterException
|
import com.google.zxing.WriterException
|
||||||
import com.google.zxing.qrcode.QRCodeWriter
|
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||||
import com.journeyapps.barcodescanner.BarcodeEncoder
|
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||||
import net.mynero.wallet.R
|
import net.mynero.wallet.R
|
||||||
|
@ -36,6 +35,7 @@ class ReceiveFragment : Fragment() {
|
||||||
private var addressImageView: ImageView? = null
|
private var addressImageView: ImageView? = null
|
||||||
private var copyAddressImageButton: ImageButton? = null
|
private var copyAddressImageButton: ImageButton? = null
|
||||||
private var mViewModel: ReceiveViewModel? = null
|
private var mViewModel: ReceiveViewModel? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
|
@ -61,7 +61,7 @@ class ReceiveFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindObservers(view: View) {
|
private fun bindObservers(view: View) {
|
||||||
val adapter = SubaddressAdapter(object : SubaddressAdapterListener {
|
val subaddressAdapterListener = object : SubaddressAdapterListener {
|
||||||
override fun onSubaddressSelected(subaddress: Subaddress?) {
|
override fun onSubaddressSelected(subaddress: Subaddress?) {
|
||||||
mViewModel?.selectAddress(subaddress)
|
mViewModel?.selectAddress(subaddress)
|
||||||
}
|
}
|
||||||
|
@ -69,19 +69,18 @@ class ReceiveFragment : Fragment() {
|
||||||
override fun onSubaddressEditLabel(subaddress: Subaddress?) {
|
override fun onSubaddressEditLabel(subaddress: Subaddress?) {
|
||||||
editAddressLabel(subaddress)
|
editAddressLabel(subaddress)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
val adapter = SubaddressAdapter(emptyList(), null, subaddressAdapterListener)
|
||||||
val recyclerView = view.findViewById<RecyclerView>(R.id.address_list_recyclerview)
|
val recyclerView = view.findViewById<RecyclerView>(R.id.address_list_recyclerview)
|
||||||
recyclerView.layoutManager = LinearLayoutManager(activity)
|
recyclerView.layoutManager = LinearLayoutManager(activity)
|
||||||
recyclerView.adapter = adapter
|
recyclerView.adapter = adapter
|
||||||
mViewModel?.address?.observe(viewLifecycleOwner) { subaddress: Subaddress? ->
|
mViewModel?.address?.observe(viewLifecycleOwner) { address: Subaddress? ->
|
||||||
setAddress(
|
setAddress(address)
|
||||||
subaddress
|
adapter.submitSelectedAddress(address)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
mViewModel?.addresses?.observe(viewLifecycleOwner) { dataSet: List<Subaddress> ->
|
mViewModel?.addresses?.observe(viewLifecycleOwner) { addresses: List<Subaddress> ->
|
||||||
adapter.submitList(
|
// We want newer addresses addresses to be shown first
|
||||||
dataSet
|
adapter.submitAddresses(addresses.reversed())
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,23 +11,25 @@ import java.util.Collections
|
||||||
class ReceiveViewModel : ViewModel() {
|
class ReceiveViewModel : ViewModel() {
|
||||||
private val _address = MutableLiveData<Subaddress?>()
|
private val _address = MutableLiveData<Subaddress?>()
|
||||||
private val _addresses = MutableLiveData<List<Subaddress>>()
|
private val _addresses = MutableLiveData<List<Subaddress>>()
|
||||||
var address: LiveData<Subaddress?> = _address
|
val address: LiveData<Subaddress?> = _address
|
||||||
var addresses: LiveData<List<Subaddress>> = _addresses
|
val addresses: LiveData<List<Subaddress>> = _addresses
|
||||||
|
|
||||||
fun init() {
|
fun init() {
|
||||||
_address.value = AddressService.instance?.currentSubaddress()
|
|
||||||
_addresses.value = subaddresses
|
_addresses.value = subaddresses
|
||||||
|
_address.value = addresses.value?.lastOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val subaddresses: List<Subaddress>
|
private val subaddresses: List<Subaddress>
|
||||||
get() {
|
get() {
|
||||||
val wallet = WalletManager.instance?.wallet
|
val wallet = WalletManager.instance?.wallet
|
||||||
val subaddresses = ArrayList<Subaddress>()
|
val subaddresses = ArrayList<Subaddress>()
|
||||||
val addressesSize = AddressService.instance?.latestAddressIndex ?: 0
|
val numAddresses = AddressService.instance?.numAddresses ?: 1
|
||||||
for (i in addressesSize - 1 downTo 0) {
|
for (i in 0 until numAddresses) {
|
||||||
wallet?.getSubaddressObject(i)?.let { subaddresses.add(it) }
|
wallet?.getSubaddressObject(i)?.let { subaddresses.add(it) }
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableList(subaddresses)
|
return Collections.unmodifiableList(subaddresses)
|
||||||
}
|
}
|
||||||
|
|
||||||
val freshSubaddress: Unit
|
val freshSubaddress: Unit
|
||||||
get() {
|
get() {
|
||||||
_address.value = AddressService.instance?.freshSubaddress()
|
_address.value = AddressService.instance?.freshSubaddress()
|
||||||
|
|
|
@ -19,9 +19,6 @@ import android.util.Log
|
||||||
import android.util.Pair
|
import android.util.Pair
|
||||||
import net.mynero.wallet.data.Subaddress
|
import net.mynero.wallet.data.Subaddress
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Date
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class Wallet {
|
class Wallet {
|
||||||
var isSynchronized = false
|
var isSynchronized = false
|
||||||
|
@ -418,16 +415,6 @@ class Wallet {
|
||||||
get() = getNumSubaddresses(accountIndex)
|
get() = getNumSubaddresses(accountIndex)
|
||||||
|
|
||||||
private external fun getNumSubaddresses(accountIndex: Int): Int
|
private external fun getNumSubaddresses(accountIndex: Int): Int
|
||||||
val newSubaddress: String
|
|
||||||
get() = getNewSubaddress(accountIndex)
|
|
||||||
|
|
||||||
private fun getNewSubaddress(accountIndex: Int): String {
|
|
||||||
val timeStamp = SimpleDateFormat("yyyy-MM-dd-HH:mm:ss", Locale.US).format(Date())
|
|
||||||
addSubaddress(accountIndex, timeStamp)
|
|
||||||
val subaddress = getLastSubaddress(accountIndex)
|
|
||||||
Log.d("Wallet.kt", "${(getNumSubaddresses(accountIndex) - 1)}: $subaddress")
|
|
||||||
return subaddress
|
|
||||||
}
|
|
||||||
|
|
||||||
external fun addSubaddress(accountIndex: Int, label: String?)
|
external fun addSubaddress(accountIndex: Int, label: String?)
|
||||||
private fun getLastSubaddress(accountIndex: Int): String {
|
private fun getLastSubaddress(accountIndex: Int): String {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class AddressService(thread: MoneroHandlerThread) : ServiceBase(thread) {
|
class AddressService(thread: MoneroHandlerThread) : ServiceBase(thread) {
|
||||||
var latestAddressIndex = 1
|
var numAddresses = 1
|
||||||
private set
|
private set
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -15,7 +15,7 @@ class AddressService(thread: MoneroHandlerThread) : ServiceBase(thread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshAddresses() {
|
fun refreshAddresses() {
|
||||||
WalletManager.instance?.wallet?.numSubaddresses?.let { latestAddressIndex = it }
|
WalletManager.instance?.wallet?.numSubaddresses?.let { numAddresses = it }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun freshSubaddress(): Subaddress? {
|
fun freshSubaddress(): Subaddress? {
|
||||||
|
@ -24,12 +24,12 @@ class AddressService(thread: MoneroHandlerThread) : ServiceBase(thread) {
|
||||||
wallet?.addSubaddress(wallet.getAccountIndex(), timeStamp)
|
wallet?.addSubaddress(wallet.getAccountIndex(), timeStamp)
|
||||||
refreshAddresses()
|
refreshAddresses()
|
||||||
wallet?.store()
|
wallet?.store()
|
||||||
return wallet?.getSubaddressObject(latestAddressIndex)
|
return wallet?.getSubaddressObject(numAddresses - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun currentSubaddress(): Subaddress? {
|
fun currentSubaddress(): Subaddress? {
|
||||||
val wallet = WalletManager.instance?.wallet
|
val wallet = WalletManager.instance?.wallet
|
||||||
return wallet?.getSubaddressObject(latestAddressIndex)
|
return wallet?.getSubaddressObject(numAddresses - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:ellipsize="middle"
|
android:ellipsize="middle"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/previous_addresses"
|
android:text="@string/all_addresses"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toTopOf="@id/address_list_recyclerview"
|
app:layout_constraintBottom_toTopOf="@id/address_list_recyclerview"
|
||||||
|
|
|
@ -127,7 +127,7 @@
|
||||||
<string name="trusted_daemon">Trusted daemon</string>
|
<string name="trusted_daemon">Trusted daemon</string>
|
||||||
<string name="use_bundled_tor">Let Mysu start and manage a Tor daemon</string>
|
<string name="use_bundled_tor">Let Mysu start and manage a Tor daemon</string>
|
||||||
<string name="subbaddress_info_subtitle" translatable="false">#%1$d: %2$s</string>
|
<string name="subbaddress_info_subtitle" translatable="false">#%1$d: %2$s</string>
|
||||||
<string name="previous_addresses">Previous addresses</string>
|
<string name="all_addresses">All addresses</string>
|
||||||
<string name="donate_label">Donate to Mysu</string>
|
<string name="donate_label">Donate to Mysu</string>
|
||||||
<string name="donating_label">Donating to Mysu. Thank you!</string>
|
<string name="donating_label">Donating to Mysu. Thank you!</string>
|
||||||
<string name="transactions">Transactions</string>
|
<string name="transactions">Transactions</string>
|
||||||
|
|
Loading…
Reference in a new issue