Make ReceiveTransactionFragment extend from ConnectedFragment to reduce boilerplate and repeated code. Change the method used to obtain the Assets list from the db in ReceiveTransactionFragment, it now retrieved only those Assets for which the user has a Balance > 0. Improve ReceiveTransactionFragment's function that obtains the suggestions for the AutoCompleteTextView when the user wants to receive a different Asset, to avoid crashes if the information received does not have the expected format.
This commit is contained in:
parent
ec57bea829
commit
9a8af1b918
4 changed files with 53 additions and 102 deletions
|
@ -15,6 +15,6 @@ interface AssetDao {
|
||||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
fun insertAll(assets: List<Asset>)
|
fun insertAll(assets: List<Asset>)
|
||||||
|
|
||||||
@Query("SELECT * FROM assets")
|
@Query("SELECT id, symbol, precision, description, bit_asset_id FROM assets INNER JOIN balances WHERE assets.id = balances.asset_id AND balances.asset_amount > 0")
|
||||||
fun getAll(): LiveData<List<Asset>>
|
fun getAllNonZero(): LiveData<List<Asset>>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package cy.agorise.bitsybitshareswallet.fragments
|
package cy.agorise.bitsybitshareswallet.fragments
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.ServiceConnection
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.IBinder
|
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
@ -17,7 +13,6 @@ import android.widget.AdapterView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
import com.google.common.primitives.UnsignedLong
|
import com.google.common.primitives.UnsignedLong
|
||||||
|
@ -36,12 +31,9 @@ import cy.agorise.bitsybitshareswallet.viewmodels.AssetViewModel
|
||||||
import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel
|
import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel
|
||||||
import cy.agorise.graphenej.*
|
import cy.agorise.graphenej.*
|
||||||
import cy.agorise.graphenej.api.ConnectionStatusUpdate
|
import cy.agorise.graphenej.api.ConnectionStatusUpdate
|
||||||
import cy.agorise.graphenej.api.android.NetworkService
|
|
||||||
import cy.agorise.graphenej.api.android.RxBus
|
|
||||||
import cy.agorise.graphenej.api.calls.ListAssets
|
import cy.agorise.graphenej.api.calls.ListAssets
|
||||||
import cy.agorise.graphenej.models.JsonRpcResponse
|
import cy.agorise.graphenej.models.JsonRpcResponse
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
|
||||||
import kotlinx.android.synthetic.main.fragment_receive_transaction.*
|
import kotlinx.android.synthetic.main.fragment_receive_transaction.*
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.math.RoundingMode
|
import java.math.RoundingMode
|
||||||
|
@ -51,16 +43,19 @@ import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
class ReceiveTransactionFragment : ConnectedFragment() {
|
||||||
private val TAG = this.javaClass.simpleName
|
|
||||||
|
|
||||||
private val RESPONSE_LIST_ASSETS = 1
|
companion object {
|
||||||
private val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 100
|
private const val TAG = "ReceiveTransactionFrag"
|
||||||
|
|
||||||
/** Number of assets to request from the NetworkService to show as suggestions in the AutoCompleteTextView */
|
private const val RESPONSE_LIST_ASSETS = 1
|
||||||
private val AUTO_SUGGEST_ASSET_LIMIT = 5
|
private const val REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION = 100
|
||||||
|
|
||||||
private val OTHER_ASSET = "other_asset"
|
/** Number of assets to request from the NetworkService to show as suggestions in the AutoCompleteTextView */
|
||||||
|
private const val AUTO_SUGGEST_ASSET_LIMIT = 5
|
||||||
|
|
||||||
|
private const val OTHER_ASSET = "other_asset"
|
||||||
|
}
|
||||||
|
|
||||||
private lateinit var mUserAccountViewModel: UserAccountViewModel
|
private lateinit var mUserAccountViewModel: UserAccountViewModel
|
||||||
private lateinit var mAssetViewModel: AssetViewModel
|
private lateinit var mAssetViewModel: AssetViewModel
|
||||||
|
@ -68,8 +63,6 @@ class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
||||||
/** Current user account */
|
/** Current user account */
|
||||||
private var mUserAccount: UserAccount? = null
|
private var mUserAccount: UserAccount? = null
|
||||||
|
|
||||||
private var mDisposables = CompositeDisposable()
|
|
||||||
|
|
||||||
private var mAsset: Asset? = null
|
private var mAsset: Asset? = null
|
||||||
|
|
||||||
private var mAssetsAdapter: AssetsAdapter? = null
|
private var mAssetsAdapter: AssetsAdapter? = null
|
||||||
|
@ -86,12 +79,6 @@ class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
||||||
// Map used to keep track of request and response id pairs
|
// Map used to keep track of request and response id pairs
|
||||||
private val responseMap = HashMap<Long, Int>()
|
private val responseMap = HashMap<Long, Int>()
|
||||||
|
|
||||||
/* Network service connection */
|
|
||||||
private var mNetworkService: NetworkService? = null
|
|
||||||
|
|
||||||
/** Flag used to keep track of the NetworkService binding state */
|
|
||||||
private var mShouldUnbindNetwork: Boolean = false
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
|
||||||
|
@ -127,7 +114,7 @@ class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
||||||
// Configure Assets spinner to show Assets already saved into the db
|
// Configure Assets spinner to show Assets already saved into the db
|
||||||
mAssetViewModel = ViewModelProviders.of(this).get(AssetViewModel::class.java)
|
mAssetViewModel = ViewModelProviders.of(this).get(AssetViewModel::class.java)
|
||||||
|
|
||||||
mAssetViewModel.getAll().observe(this,
|
mAssetViewModel.getAllNonZero().observe(this,
|
||||||
Observer<List<cy.agorise.bitsybitshareswallet.database.entities.Asset>> { assets ->
|
Observer<List<cy.agorise.bitsybitshareswallet.database.entities.Asset>> { assets ->
|
||||||
mAssets.clear()
|
mAssets.clear()
|
||||||
mAssets.addAll(assets)
|
mAssets.addAll(assets)
|
||||||
|
@ -211,50 +198,49 @@ class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
||||||
selectedInAutoCompleteTextView = true
|
selectedInAutoCompleteTextView = true
|
||||||
updateQR()
|
updateQR()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to the RxBus, which receives events from the NetworkService
|
|
||||||
mDisposables.add(
|
|
||||||
RxBus.getBusInstance()
|
|
||||||
.asFlowable()
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe { handleIncomingMessage(it) }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleIncomingMessage(message: Any?) {
|
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
|
||||||
if (message is JsonRpcResponse<*>) {
|
if (responseMap.containsKey(response.id)) {
|
||||||
if (responseMap.containsKey(message.id)) {
|
val responseType = responseMap[response.id]
|
||||||
val responseType = responseMap[message.id]
|
when (responseType) {
|
||||||
when (responseType) {
|
RESPONSE_LIST_ASSETS -> handleListAssets(response.result)
|
||||||
RESPONSE_LIST_ASSETS -> handleListAssets(message.result as List<Asset>)
|
|
||||||
}
|
|
||||||
responseMap.remove(message.id)
|
|
||||||
}
|
|
||||||
} else if (message is ConnectionStatusUpdate) {
|
|
||||||
if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) {
|
|
||||||
// If we got a disconnection notification, we should clear our response map, since
|
|
||||||
// all its stored request ids will now be reset
|
|
||||||
responseMap.clear()
|
|
||||||
}
|
}
|
||||||
|
responseMap.remove(response.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleListAssets(assetList: List<Asset>) {
|
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
|
||||||
Log.d(TAG, "handleListAssets")
|
if (connectionStatusUpdate.updateCode == ConnectionStatusUpdate.DISCONNECTED) {
|
||||||
val assets = ArrayList<cy.agorise.bitsybitshareswallet.database.entities.Asset>()
|
// If we got a disconnection notification, we should clear our response map, since
|
||||||
for (_asset in assetList) {
|
// all its stored request ids will now be reset
|
||||||
val asset = cy.agorise.bitsybitshareswallet.database.entities.Asset(
|
responseMap.clear()
|
||||||
_asset.objectId,
|
}
|
||||||
_asset.symbol,
|
}
|
||||||
_asset.precision,
|
|
||||||
_asset.description ?: "",
|
/**
|
||||||
_asset.bitassetId ?: ""
|
* Handles the list of assets returned from the node that correspond to what the user has typed in the Asset
|
||||||
)
|
* AutoCompleteTextView and adds them to its adapter to show as suggestions.
|
||||||
|
*/
|
||||||
assets.add(asset)
|
private fun handleListAssets(result: Any?) {
|
||||||
|
if (result is List<*> && result.isNotEmpty() && result[0] is Asset) {
|
||||||
|
val assetList = result as List<Asset>
|
||||||
|
Log.d(TAG, "handleListAssets")
|
||||||
|
val assets = ArrayList<cy.agorise.bitsybitshareswallet.database.entities.Asset>()
|
||||||
|
for (_asset in assetList) {
|
||||||
|
val asset = cy.agorise.bitsybitshareswallet.database.entities.Asset(
|
||||||
|
_asset.objectId,
|
||||||
|
_asset.symbol,
|
||||||
|
_asset.precision,
|
||||||
|
_asset.description ?: "",
|
||||||
|
_asset.bitassetId ?: ""
|
||||||
|
)
|
||||||
|
|
||||||
|
assets.add(asset)
|
||||||
|
}
|
||||||
|
mAutoSuggestAssetAdapter.setData(assets)
|
||||||
|
mAutoSuggestAssetAdapter.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
mAutoSuggestAssetAdapter.setData(assets)
|
|
||||||
mAutoSuggestAssetAdapter.notifyDataSetChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateQR() {
|
private fun updateQR() {
|
||||||
|
@ -422,39 +408,4 @@ class ReceiveTransactionFragment : Fragment(), ServiceConnection {
|
||||||
shareIntent.type = "*/*"
|
shareIntent.type = "*/*"
|
||||||
startActivity(Intent.createChooser(shareIntent, getString(R.string.text__share_with)))
|
startActivity(Intent.createChooser(shareIntent, getString(R.string.text__share_with)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
|
|
||||||
val intent = Intent(context, NetworkService::class.java)
|
|
||||||
if (context?.bindService(intent, this, Context.BIND_AUTO_CREATE) == true) {
|
|
||||||
mShouldUnbindNetwork = true
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Binding to the network service failed.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPause() {
|
|
||||||
super.onPause()
|
|
||||||
|
|
||||||
// Unbinding from network service
|
|
||||||
if (mShouldUnbindNetwork) {
|
|
||||||
context?.unbindService(this)
|
|
||||||
mShouldUnbindNetwork = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
|
|
||||||
if (!mDisposables.isDisposed) mDisposables.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName?) { }
|
|
||||||
|
|
||||||
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
|
|
||||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
|
||||||
val binder = service as NetworkService.LocalBinder
|
|
||||||
mNetworkService = binder.service
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -16,8 +16,8 @@ class AssetRepository internal constructor(context: Context) {
|
||||||
mAssetDao = db!!.assetDao()
|
mAssetDao = db!!.assetDao()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAll(): LiveData<List<Asset>> {
|
fun getAllNonZero(): LiveData<List<Asset>> {
|
||||||
return mAssetDao.getAll()
|
return mAssetDao.getAllNonZero()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun insertAll(assets: List<Asset>) {
|
fun insertAll(assets: List<Asset>) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import cy.agorise.bitsybitshareswallet.repositories.AssetRepository
|
||||||
class AssetViewModel(application: Application) : AndroidViewModel(application) {
|
class AssetViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private var mRepository = AssetRepository(application)
|
private var mRepository = AssetRepository(application)
|
||||||
|
|
||||||
internal fun getAll(): LiveData<List<Asset>> {
|
internal fun getAllNonZero(): LiveData<List<Asset>> {
|
||||||
return mRepository.getAll()
|
return mRepository.getAllNonZero()
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue