- Modified the Asset entity model by adding a method 'toString()', so that it can be used in the adapter for the ReceiveTransactionFragment's Asset AutoCompleteTextView.
- Created AssetViewModel to obtain the the elements from the assetd db table using the AssetRepository and serving the obtained assets to the ReceiveTransactionFragment. - Fire an event to update the QR code when the user selects an asset from the AutoCompleteTextView.
This commit is contained in:
parent
b9a765e682
commit
28561d55f1
7 changed files with 108 additions and 44 deletions
|
@ -10,7 +10,7 @@ import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail
|
|||
|
||||
|
||||
|
||||
class AssetsAdapter(context: Context, resource: Int, data: List<BalanceDetail>) :
|
||||
class BalancesDetailsAdapter(context: Context, resource: Int, data: List<BalanceDetail>) :
|
||||
ArrayAdapter<BalanceDetail>(context, resource, data) {
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
|
@ -16,5 +16,5 @@ interface AssetDao {
|
|||
fun insertAll(assets: List<Asset>)
|
||||
|
||||
@Query("SELECT * FROM assets")
|
||||
fun getAllAssets(): LiveData<List<Asset>>
|
||||
fun getAll(): LiveData<List<Asset>>
|
||||
}
|
||||
|
|
|
@ -12,4 +12,8 @@ data class Asset(
|
|||
@ColumnInfo(name = "precision") val precision: Int,
|
||||
@ColumnInfo(name = "description") val description: String,
|
||||
@ColumnInfo(name = "bit_asset_id") val bitAssetId: String
|
||||
)
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return symbol
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.util.Log
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
|
@ -17,21 +18,30 @@ import com.google.zxing.EncodeHintType
|
|||
import com.google.zxing.MultiFormatWriter
|
||||
import com.google.zxing.WriterException
|
||||
import com.google.zxing.common.BitMatrix
|
||||
import com.jakewharton.rxbinding2.widget.RxTextView
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import cy.agorise.bitsybitshareswallet.viewmodels.AssetViewModel
|
||||
import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel
|
||||
import cy.agorise.graphenej.*
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.fragment_receive_transaction.*
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ReceiveTransactionFragment : Fragment() {
|
||||
private val TAG = this.javaClass.simpleName
|
||||
|
||||
private lateinit var mUserAccountViewModel: UserAccountViewModel
|
||||
private lateinit var mAssetViewModel: AssetViewModel
|
||||
|
||||
/** Current user account */
|
||||
private var mUserAccount: UserAccount? = null
|
||||
|
||||
private var mDisposables = CompositeDisposable()
|
||||
|
||||
private var mAsset: Asset? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.fragment_receive_transaction, container, false)
|
||||
}
|
||||
|
@ -48,16 +58,41 @@ class ReceiveTransactionFragment : Fragment() {
|
|||
mUserAccountViewModel.getUserAccount(userId!!).observe(this,
|
||||
Observer<cy.agorise.bitsybitshareswallet.database.entities.UserAccount>{ user ->
|
||||
mUserAccount = UserAccount(user.id, user.name)
|
||||
updateQR()
|
||||
})
|
||||
|
||||
mAssetViewModel = ViewModelProviders.of(this).get(AssetViewModel::class.java)
|
||||
|
||||
mAssetViewModel.getAll().observe(this,
|
||||
Observer<List<cy.agorise.bitsybitshareswallet.database.entities.Asset>> { assets ->
|
||||
val adapter = ArrayAdapter<cy.agorise.bitsybitshareswallet.database.entities.Asset>(context!!,
|
||||
android.R.layout.simple_dropdown_item_1line, assets)
|
||||
actvAsset.setAdapter(adapter)
|
||||
})
|
||||
|
||||
actvAsset.setOnItemClickListener { parent, _, position, _ ->
|
||||
val asset = parent.adapter.getItem(position) as cy.agorise.bitsybitshareswallet.database.entities.Asset
|
||||
mAsset = Asset(asset.id, asset.symbol, asset.precision)
|
||||
updateQR()
|
||||
}
|
||||
|
||||
// Use RxJava Debounce to avoid making calls to the NetworkService on every text change event
|
||||
// mDisposables.add(
|
||||
// RxTextView.textChanges(tietAmount)
|
||||
// .debounce(500, TimeUnit.MILLISECONDS)
|
||||
// .map { it.toString().trim() }
|
||||
// .filter { it.length > 1 }
|
||||
// .subscribe {
|
||||
//
|
||||
// }
|
||||
// )
|
||||
}
|
||||
|
||||
private fun updateQR() {
|
||||
val inputCoinType = "bts"
|
||||
val amount: Long = 10
|
||||
|
||||
val total = Util.fromBase(AssetAmount(UnsignedLong.valueOf(10), Asset("1.3.0", "bts", 5)))
|
||||
val total = Util.fromBase(AssetAmount(UnsignedLong.valueOf(amount), mAsset!!))
|
||||
val items = arrayOf(LineItem("transfer", 1, total))
|
||||
val invoice = Invoice(mUserAccount!!.name, "", "#bitsy", inputCoinType, items, "", "")
|
||||
val invoice = Invoice(mUserAccount!!.name, "", "#bitsy", mAsset!!.symbol, items, "", "")
|
||||
Log.d(TAG, "invoice: " + invoice.toJsonString())
|
||||
try {
|
||||
val bitmap = encodeAsBitmap(Invoice.toQrCode(invoice), "#139657") // PalmPay green
|
||||
|
|
|
@ -24,7 +24,7 @@ import com.google.zxing.BarcodeFormat
|
|||
import com.google.zxing.Result
|
||||
import com.jakewharton.rxbinding2.widget.RxTextView
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.adapters.AssetsAdapter
|
||||
import cy.agorise.bitsybitshareswallet.adapters.BalancesDetailsAdapter
|
||||
import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail
|
||||
import cy.agorise.bitsybitshareswallet.repositories.AuthorityRepository
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
|
@ -75,7 +75,7 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
|
||||
private lateinit var mBalanceDetailViewModel: BalanceDetailViewModel
|
||||
|
||||
private var mAssetsAdapter: AssetsAdapter? = null
|
||||
private var mBalancesDetailsAdapter: BalancesDetailsAdapter? = null
|
||||
|
||||
private var selectedAssetSymbol = ""
|
||||
|
||||
|
@ -129,12 +129,12 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
|
||||
mBalanceDetailViewModel.getAll().observe(this, Observer<List<BalanceDetail>> { balancesDetails ->
|
||||
mBalancesDetails = balancesDetails
|
||||
mAssetsAdapter = AssetsAdapter(context!!, android.R.layout.simple_spinner_item, mBalancesDetails!!)
|
||||
spAsset.adapter = mAssetsAdapter
|
||||
mBalancesDetailsAdapter = BalancesDetailsAdapter(context!!, android.R.layout.simple_spinner_item, mBalancesDetails!!)
|
||||
spAsset.adapter = mBalancesDetailsAdapter
|
||||
|
||||
// Try to select the selectedAssetSymbol
|
||||
for (i in 0 until mAssetsAdapter!!.count) {
|
||||
if (mAssetsAdapter!!.getItem(i)!!.symbol == selectedAssetSymbol) {
|
||||
for (i in 0 until mBalancesDetailsAdapter!!.count) {
|
||||
if (mBalancesDetailsAdapter!!.getItem(i)!!.symbol == selectedAssetSymbol) {
|
||||
spAsset.setSelection(i)
|
||||
break
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
override fun onNothingSelected(parent: AdapterView<*>?) { }
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
val balance = mAssetsAdapter!!.getItem(position)!!
|
||||
val balance = mBalancesDetailsAdapter!!.getItem(position)!!
|
||||
selectedAssetSymbol = balance.symbol
|
||||
|
||||
val amount = balance.amount.toDouble() / Math.pow(10.0, balance.precision.toDouble())
|
||||
|
@ -160,40 +160,45 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
|
||||
authorityRepository = AuthorityRepository(context!!)
|
||||
|
||||
mDisposables.add(authorityRepository!!.getWIF(userId!!, AuthorityType.ACTIVE.ordinal)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { encryptedWIF ->
|
||||
try {
|
||||
wifKey = CryptoUtils.decrypt(context!!, encryptedWIF)
|
||||
} catch (e: AEADBadTagException) {
|
||||
Log.e(TAG, "AEADBadTagException. Class: " + e.javaClass + ", Msg: " + e.message)
|
||||
}
|
||||
mDisposables.add(
|
||||
authorityRepository!!.getWIF(userId!!, AuthorityType.ACTIVE.ordinal)
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { encryptedWIF ->
|
||||
try {
|
||||
wifKey = CryptoUtils.decrypt(context!!, encryptedWIF)
|
||||
} catch (e: AEADBadTagException) {
|
||||
Log.e(TAG, "AEADBadTagException. Class: " + e.javaClass + ", Msg: " + e.message)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
// Use RxJava Debounce to avoid making calls to the NetworkService on every text change event
|
||||
mDisposables.add(RxTextView.textChanges(tietTo)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.map { it.toString().trim() }
|
||||
.filter { it.length > 1 }
|
||||
.subscribe {
|
||||
val id = mNetworkService!!.sendMessage(GetAccountByName(it!!), GetAccountByName.REQUIRED_API)
|
||||
responseMap[id] = RESPONSE_GET_ACCOUNT_BY_NAME
|
||||
}
|
||||
mDisposables.add(
|
||||
RxTextView.textChanges(tietTo)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.map { it.toString().trim() }
|
||||
.filter { it.length > 1 }
|
||||
.subscribe {
|
||||
val id = mNetworkService!!.sendMessage(GetAccountByName(it!!), GetAccountByName.REQUIRED_API)
|
||||
responseMap[id] = RESPONSE_GET_ACCOUNT_BY_NAME
|
||||
}
|
||||
)
|
||||
|
||||
// Use RxJava Debounce to update the Amount error only after the user stops writing for > 500 ms
|
||||
mDisposables.add(RxTextView.textChanges(tietAmount)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.filter { it.isNotEmpty() }
|
||||
.map { it.toString().trim().toDouble() }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { validateAmount(it!!) }
|
||||
mDisposables.add(
|
||||
RxTextView.textChanges(tietAmount)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.filter { it.isNotEmpty() }
|
||||
.map { it.toString().trim().toDouble() }
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { validateAmount(it!!) }
|
||||
)
|
||||
|
||||
// Connect to the RxBus, which receives events from the NetworkService
|
||||
mDisposables.add(RxBus.getBusInstance()
|
||||
mDisposables.add(
|
||||
RxBus.getBusInstance()
|
||||
.asFlowable()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { handleIncomingMessage(it) }
|
||||
|
@ -244,7 +249,7 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
|
||||
transaction!!.blockData = BlockData(headBlockNumber, headBlockId, expirationTime)
|
||||
|
||||
val asset = Asset(mAssetsAdapter!!.getItem(spAsset.selectedItemPosition)!!.id)
|
||||
val asset = Asset(mBalancesDetailsAdapter!!.getItem(spAsset.selectedItemPosition)!!.id)
|
||||
|
||||
val id = mNetworkService!!.sendMessage(GetRequiredFees(transaction!!, asset), GetRequiredFees.REQUIRED_API)
|
||||
responseMap[id] = RESPONSE_GET_REQUIRED_FEES
|
||||
|
@ -317,8 +322,8 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
|
||||
tietTo.setText(invoice.to)
|
||||
|
||||
for (i in 0 until mAssetsAdapter!!.count) {
|
||||
if (mAssetsAdapter!!.getItem(i)!!.symbol == invoice.currency.toUpperCase()) {
|
||||
for (i in 0 until mBalancesDetailsAdapter!!.count) {
|
||||
if (mBalancesDetailsAdapter!!.getItem(i)!!.symbol == invoice.currency.toUpperCase()) {
|
||||
spAsset.setSelection(i)
|
||||
break
|
||||
}
|
||||
|
@ -341,7 +346,7 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
}
|
||||
|
||||
private fun validateAmount(amount: Double) {
|
||||
val balance = mAssetsAdapter!!.getItem(spAsset.selectedItemPosition)!!
|
||||
val balance = mBalancesDetailsAdapter!!.getItem(spAsset.selectedItemPosition)!!
|
||||
val currentAmount = balance.amount.toDouble() / Math.pow(10.0, balance.precision.toDouble())
|
||||
|
||||
if (currentAmount < amount) {
|
||||
|
@ -365,7 +370,7 @@ class SendTransactionFragment : Fragment(), ZXingScannerView.ResultHandler, Serv
|
|||
private fun startSendTransferOperation() {
|
||||
// Create TransferOperation
|
||||
if (mNetworkService!!.isConnected) {
|
||||
val balance = mAssetsAdapter!!.getItem(spAsset.selectedItemPosition)!!
|
||||
val balance = mBalancesDetailsAdapter!!.getItem(spAsset.selectedItemPosition)!!
|
||||
val amount = (tietAmount.text.toString().toDouble() * Math.pow(10.0, balance.precision.toDouble())).toLong()
|
||||
|
||||
val transferAmount = AssetAmount(UnsignedLong.valueOf(amount), Asset(balance.id))
|
||||
|
|
|
@ -2,6 +2,7 @@ package cy.agorise.bitsybitshareswallet.repositories
|
|||
|
||||
import android.app.Application
|
||||
import android.os.AsyncTask
|
||||
import androidx.lifecycle.LiveData
|
||||
import cy.agorise.bitsybitshareswallet.database.daos.AssetDao
|
||||
import cy.agorise.bitsybitshareswallet.database.BitsyDatabase
|
||||
import cy.agorise.bitsybitshareswallet.database.entities.Asset
|
||||
|
@ -15,6 +16,10 @@ class AssetRepository internal constructor(application: Application) {
|
|||
mAssetDao = db!!.assetDao()
|
||||
}
|
||||
|
||||
fun getAll(): LiveData<List<Asset>> {
|
||||
return mAssetDao.getAll()
|
||||
}
|
||||
|
||||
fun insertAll(assets: List<Asset>) {
|
||||
insertAllAsyncTask(mAssetDao).execute(assets)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package cy.agorise.bitsybitshareswallet.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import cy.agorise.bitsybitshareswallet.database.entities.Asset
|
||||
import cy.agorise.bitsybitshareswallet.repositories.AssetRepository
|
||||
|
||||
class AssetViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private var mRepository = AssetRepository(application)
|
||||
|
||||
internal fun getAll(): LiveData<List<Asset>> {
|
||||
return mRepository.getAll()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue