Create method to update the Transactions list when new operations are detected for the current user account. When new transactions are fetched and saved into the database they automatically appear on the Transactions list.

This commit is contained in:
Severiano Jaramillo 2018-12-08 22:15:06 -06:00
parent 2b168180c6
commit 0f96c48135
3 changed files with 64 additions and 50 deletions

View file

@ -7,11 +7,13 @@ import android.content.ServiceConnection
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.IBinder import android.os.IBinder
import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import cy.agorise.bitsybitshareswallet.processors.TransfersLoader
import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel
import cy.agorise.graphenej.UserAccount import cy.agorise.graphenej.UserAccount
@ -19,12 +21,13 @@ import cy.agorise.graphenej.api.ConnectionStatusUpdate
import cy.agorise.graphenej.api.android.NetworkService import cy.agorise.graphenej.api.android.NetworkService
import cy.agorise.graphenej.api.android.RxBus import cy.agorise.graphenej.api.android.RxBus
import cy.agorise.graphenej.api.calls.GetAccounts import cy.agorise.graphenej.api.calls.GetAccounts
import cy.agorise.graphenej.api.calls.GetFullAccounts
import cy.agorise.graphenej.models.AccountProperties import cy.agorise.graphenej.models.AccountProperties
import cy.agorise.graphenej.models.FullAccountDetails import cy.agorise.graphenej.models.FullAccountDetails
import cy.agorise.graphenej.models.HistoryOperationDetail
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.Disposable import io.reactivex.disposables.Disposable
import java.util.*
/** /**
* Class in charge of managing the connection to graphenej's NetworkService * Class in charge of managing the connection to graphenej's NetworkService
@ -34,6 +37,9 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
private lateinit var mUserAccountViewModel: UserAccountViewModel private lateinit var mUserAccountViewModel: UserAccountViewModel
/* Current user account */
protected var mCurrentAccount: UserAccount? = null
private val mHandler = Handler() private val mHandler = Handler()
// Disposable returned at the bus subscription // Disposable returned at the bus subscription
@ -53,6 +59,12 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val userId = PreferenceManager.getDefaultSharedPreferences(this)
.getString(Constants.KEY_CURRENT_ACCOUNT_ID, "")
if (userId != "")
mCurrentAccount = UserAccount(userId)
mDisposable = RxBus.getBusInstance() mDisposable = RxBus.getBusInstance()
.asFlowable() .asFlowable()
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
@ -63,18 +75,11 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
// Payment detection focused responses // Payment detection focused responses
if (message.error == null) { if (message.error == null) {
if (message.result is List<*> && (message.result as List<*>).size > 0) { if (message.result is List<*> && (message.result as List<*>).size > 0) {
if ((message.result as List<*>)[0] is AccountProperties) { if ((message.result as List<*>)[0] is FullAccountDetails) {
handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails)
} else if ((message.result as List<*>)[0] is AccountProperties) {
handleAccountProperties(message.result as List<AccountProperties>) handleAccountProperties(message.result as List<AccountProperties>)
} }
// if ((message.result as List<*>)[0] is FullAccountDetails) {
// if (message.id == recurrentAccountUpdateId) {
// handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails)
// } else if (message.id == postProcessingAccountUpdateId) {
// handleAccountUpdate((message.result as List<*>)[0] as FullAccountDetails)
// }
// }
// } else if (message.result is HistoryOperationDetail && message.id == accountOpRequestId) {
// handleNewOperations(message.result as HistoryOperationDetail)
} }
} else { } else {
// In case of error // In case of error
@ -90,7 +95,6 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) { if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) {
// recurrentAccountUpdateId = -1 // recurrentAccountUpdateId = -1
// accountOpRequestId = -1 // accountOpRequestId = -1
// isProcessingTx = false
} }
} }
} }
@ -108,6 +112,29 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
}) })
} }
/**
* Method called whenever a response to the 'get_full_accounts' API call has been detected.
* @param accountDetails De-serialized account details object
*/
private fun handleAccountDetails(accountDetails: FullAccountDetails) {
val latestOpCount = accountDetails.statistics.total_ops
Log.d(TAG, "handleAccountDetails. prev count: $storedOpCount, current count: $latestOpCount")
if (latestOpCount == 0L) {
Log.d(TAG, "The node returned 0 total_ops for current account and may not have installed the history plugin. " +
"\nAsk the NetworkService to remove the node from the list and connect to another one.")
mNetworkService!!.removeCurrentNodeAndReconnect()
} else if (storedOpCount == -1L) {
// Initial case
storedOpCount = latestOpCount
PreferenceManager.getDefaultSharedPreferences(this)
.edit().putLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, latestOpCount).apply()
} else if (latestOpCount > storedOpCount) {
storedOpCount = latestOpCount
TransfersLoader(this, lifecycle)
}
}
private fun handleAccountProperties(accountPropertiesList: List<AccountProperties>) { private fun handleAccountProperties(accountPropertiesList: List<AccountProperties>) {
val userAccounts = ArrayList<cy.agorise.bitsybitshareswallet.database.entities.UserAccount>() val userAccounts = ArrayList<cy.agorise.bitsybitshareswallet.database.entities.UserAccount>()
@ -141,29 +168,22 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
/** /**
* Task used to perform a redundant payment check. * Task used to perform a redundant payment check.
*/ */
// private val mCheckMissingPaymentsTask = object : Runnable { private val mCheckMissingPaymentsTask = object : Runnable {
// override fun run() { override fun run() {
// if (mNetworkService != null && mNetworkService.isConnected()) { if (mNetworkService != null && mNetworkService!!.isConnected) {
// val userId = PreferenceManager // Checking that we actually have a user id registered in the shared preferences
// .getDefaultSharedPreferences(this@ConnectedActivity) val userAccounts = ArrayList<String>()
// .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") userAccounts.add(mCurrentAccount!!.objectId)
// if (userId != "") { mNetworkService!!.sendMessage(
// // Checking that we actually have a user id registered in the shared preferences GetFullAccounts(userAccounts, false),
// val userAccounts = ArrayList<String>() GetFullAccounts.REQUIRED_API
// userAccounts.add(userId) )
// recurrentAccountUpdateId = mNetworkService.sendMessage( } else {
// GetFullAccounts(userAccounts, false), Log.w(TAG, "NetworkService is null or is not connected. mNetworkService: $mNetworkService")
// GetFullAccounts.REQUIRED_API }
// ) mHandler.postDelayed(this, Constants.MISSING_PAYMENT_CHECK_PERIOD)
// } else { }
// Log.w(TAG, "User id is empty") }
// }
// } else {
// Log.w(TAG, "NetworkService is null or is not connected. mNetworkService: $mNetworkService")
// }
// mHandler.postDelayed(this, Constants.MISSING_PAYMENT_CHECK_PERIOD)
// }
// }
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// We've bound to LocalService, cast the IBinder and get LocalService instance // We've bound to LocalService, cast the IBinder and get LocalService instance
@ -180,7 +200,7 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
unbindService(this) unbindService(this)
mShouldUnbindNetwork = false mShouldUnbindNetwork = false
} }
// mHandler.removeCallbacks(mCheckMissingPaymentsTask) mHandler.removeCallbacks(mCheckMissingPaymentsTask)
mHandler.removeCallbacks(mRequestMissingUserAccountsTask) mHandler.removeCallbacks(mRequestMissingUserAccountsTask)
} }
@ -193,10 +213,10 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
} else { } else {
Log.e(TAG, "Binding to the network service failed.") Log.e(TAG, "Binding to the network service failed.")
} }
// mHandler.postDelayed(mCheckMissingPaymentsTask, Constants.MISSING_PAYMENT_CHECK_PERIOD) mHandler.postDelayed(mCheckMissingPaymentsTask, Constants.MISSING_PAYMENT_CHECK_PERIOD)
// storedOpCount = PreferenceManager.getDefaultSharedPreferences(this) storedOpCount = PreferenceManager.getDefaultSharedPreferences(this)
// .getLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, -1) .getLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, -1)
} }
override fun onDestroy() { override fun onDestroy() {

View file

@ -2,7 +2,6 @@ package cy.agorise.bitsybitshareswallet.activities
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
@ -17,10 +16,8 @@ import cy.agorise.bitsybitshareswallet.fragments.ReceiveTransactionFragment
import cy.agorise.bitsybitshareswallet.fragments.SendTransactionFragment import cy.agorise.bitsybitshareswallet.fragments.SendTransactionFragment
import cy.agorise.bitsybitshareswallet.processors.TransfersLoader import cy.agorise.bitsybitshareswallet.processors.TransfersLoader
import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository
import cy.agorise.bitsybitshareswallet.utils.Constants
import cy.agorise.graphenej.AssetAmount import cy.agorise.graphenej.AssetAmount
import cy.agorise.graphenej.RPC import cy.agorise.graphenej.RPC
import cy.agorise.graphenej.UserAccount
import cy.agorise.graphenej.api.ApiAccess import cy.agorise.graphenej.api.ApiAccess
import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.api.ConnectionStatusUpdate
import cy.agorise.graphenej.api.calls.GetAccountBalances import cy.agorise.graphenej.api.calls.GetAccountBalances
@ -33,9 +30,6 @@ class MainActivity : ConnectedActivity() {
private val requestMap = LongSparseArray<String>() private val requestMap = LongSparseArray<String>()
/* Current user account */
private var mCurrentAccount: UserAccount? = null
private var mBalanceRepository: BalanceRepository? = null private var mBalanceRepository: BalanceRepository? = null
private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
@ -67,11 +61,6 @@ class MainActivity : ConnectedActivity() {
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
navigation.selectedItemId = R.id.navigation_balances navigation.selectedItemId = R.id.navigation_balances
val userId = PreferenceManager.getDefaultSharedPreferences(this)
.getString(Constants.KEY_CURRENT_ACCOUNT_ID, "")
if (userId != "")
mCurrentAccount = UserAccount(userId)
mBalanceRepository = BalanceRepository(this) mBalanceRepository = BalanceRepository(this)
} }

View file

@ -49,6 +49,11 @@ object Constants {
*/ */
const val NETWORK_SERVICE_RETRY_PERIOD: Long = 5000 const val NETWORK_SERVICE_RETRY_PERIOD: Long = 5000
/**
* Key used to store the number of operations that the currently selected account had last time we checked
*/
const val KEY_ACCOUNT_OPERATION_COUNT = "key_account_operation_count"
/** Key used to store the night mode setting into the shared preferences */ /** Key used to store the night mode setting into the shared preferences */
const val KEY_NIGHT_MODE_ACTIVATED = "key_night_mode_activated" const val KEY_NIGHT_MODE_ACTIVATED = "key_night_mode_activated"
} }