From 28561d55f1e429663af74205c38c39324330dc81 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Fri, 7 Dec 2018 13:50:31 -0600 Subject: [PATCH] - 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. --- ...tsAdapter.kt => BalancesDetailsAdapter.kt} | 2 +- .../database/daos/AssetDao.kt | 2 +- .../database/entities/Asset.kt | 6 +- .../fragments/ReceiveTransactionFragment.kt | 43 +++++++++- .../fragments/SendTransactionFragment.kt | 79 ++++++++++--------- .../repositories/AssetRepository.kt | 5 ++ .../viewmodels/AssetViewModel.kt | 15 ++++ 7 files changed, 108 insertions(+), 44 deletions(-) rename app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/{AssetsAdapter.kt => BalancesDetailsAdapter.kt} (93%) create mode 100644 app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/AssetViewModel.kt diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesDetailsAdapter.kt similarity index 93% rename from app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt rename to app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesDetailsAdapter.kt index 3911159..c939027 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/AssetsAdapter.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/adapters/BalancesDetailsAdapter.kt @@ -10,7 +10,7 @@ import cy.agorise.bitsybitshareswallet.database.joins.BalanceDetail -class AssetsAdapter(context: Context, resource: Int, data: List) : +class BalancesDetailsAdapter(context: Context, resource: Int, data: List) : ArrayAdapter(context, resource, data) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt index 03a0eaa..b966ae2 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/daos/AssetDao.kt @@ -16,5 +16,5 @@ interface AssetDao { fun insertAll(assets: List) @Query("SELECT * FROM assets") - fun getAllAssets(): LiveData> + fun getAll(): LiveData> } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt index 80af4de..e065ac6 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/database/entities/Asset.kt @@ -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 + } +} diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt index 340c06f..f2ff4be 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/ReceiveTransactionFragment.kt @@ -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{ user -> mUserAccount = UserAccount(user.id, user.name) - updateQR() }) + + mAssetViewModel = ViewModelProviders.of(this).get(AssetViewModel::class.java) + + mAssetViewModel.getAll().observe(this, + Observer> { assets -> + val adapter = ArrayAdapter(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 diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt index 691bdc5..84aa3ce 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/fragments/SendTransactionFragment.kt @@ -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> { 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)) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt index a3cdc1a..f69eb5a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/repositories/AssetRepository.kt @@ -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> { + return mAssetDao.getAll() + } + fun insertAll(assets: List) { insertAllAsyncTask(mAssetDao).execute(assets) } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/AssetViewModel.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/AssetViewModel.kt new file mode 100644 index 0000000..26fb10f --- /dev/null +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/viewmodels/AssetViewModel.kt @@ -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> { + return mRepository.getAll() + } +} \ No newline at end of file