Create MerchantViewModel and MerchantRepository, the first to hold the merchants data and deliver it to the MerchantsFragment and the second to serve as a single source to fetch the Merchants list. When it gets a request for the merchants it retrieves and serves the list from the database and meanwhile refreshes the list from the WebService.
This commit is contained in:
parent
6aad0ca624
commit
4bb53de009
5 changed files with 100 additions and 33 deletions
|
@ -1,8 +1,10 @@
|
|||
package cy.agorise.bitsybitshareswallet.database.daos
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||
|
||||
@Dao
|
||||
|
@ -12,4 +14,7 @@ interface MerchantDao {
|
|||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAll(merchants: List<Merchant>)
|
||||
|
||||
@Query("SELECT * FROM merchants")
|
||||
fun getAll(): LiveData<List<Merchant>>
|
||||
}
|
|
@ -12,17 +12,12 @@ import android.view.ViewGroup
|
|||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.gson.GsonBuilder
|
||||
|
||||
import cy.agorise.bitsybitshareswallet.R
|
||||
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
||||
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.model.*
|
||||
import com.google.maps.android.clustering.Cluster
|
||||
|
@ -31,10 +26,11 @@ import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
|||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import cy.agorise.bitsybitshareswallet.utils.MerchantMarkerRenderer
|
||||
import cy.agorise.bitsybitshareswallet.utils.toast
|
||||
import cy.agorise.bitsybitshareswallet.viewmodels.MerchantViewModel
|
||||
import java.lang.Exception
|
||||
|
||||
|
||||
class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<FeathersResponse<Merchant>>,
|
||||
class MerchantsFragment : Fragment(), OnMapReadyCallback,
|
||||
ClusterManager.OnClusterClickListener<Merchant>,
|
||||
ClusterManager.OnClusterItemClickListener<Merchant>,
|
||||
ClusterManager.OnClusterItemInfoWindowClickListener<Merchant>{
|
||||
|
@ -48,6 +44,8 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
|
|||
|
||||
private lateinit var mMap: GoogleMap
|
||||
|
||||
private lateinit var mMerchantViewModel: MerchantViewModel
|
||||
|
||||
private var mClusterManager: ClusterManager<Merchant>? = null
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -63,6 +61,8 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
|
|||
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
|
||||
val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
|
||||
mapFragment.getMapAsync(this)
|
||||
|
||||
mMerchantViewModel = ViewModelProviders.of(this).get(MerchantViewModel::class.java)
|
||||
}
|
||||
|
||||
private fun verifyLocationPermission() {
|
||||
|
@ -123,17 +123,11 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
|
|||
mClusterManager?.setOnClusterItemClickListener(this)
|
||||
mClusterManager?.setOnClusterItemInfoWindowClickListener(this)
|
||||
|
||||
val gson = GsonBuilder()
|
||||
.setLenient()
|
||||
.create()
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl(Constants.MERCHANTS_WEBSERVICE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.build()
|
||||
|
||||
val ambassadorService = retrofit.create<MerchantsWebservice>(MerchantsWebservice::class.java)
|
||||
val call = ambassadorService.getMerchants(0)
|
||||
call.enqueue(this)
|
||||
mMerchantViewModel.getAllMerchants().observe(this, Observer<List<Merchant>> {merchants ->
|
||||
mClusterManager?.clearItems()
|
||||
mClusterManager?.addItems(merchants)
|
||||
mClusterManager?.cluster()
|
||||
})
|
||||
}
|
||||
|
||||
private fun applyMapTheme() {
|
||||
|
@ -155,19 +149,6 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, retrofit2.Callback<Fea
|
|||
}
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call<FeathersResponse<Merchant>>, response: Response<FeathersResponse<Merchant>>) {
|
||||
if (response.isSuccessful) {
|
||||
val res: FeathersResponse<Merchant>? = response.body()
|
||||
val merchants = res?.data ?: return
|
||||
mClusterManager?.addItems(merchants)
|
||||
mClusterManager?.cluster()
|
||||
} else {
|
||||
Log.e("error_bitsy", response.errorBody()?.string())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<FeathersResponse<Merchant>>, t: Throwable) { /* Do nothing */ }
|
||||
|
||||
/**
|
||||
* Animates the camera update to focus on an area that shows all the items from the cluster that was tapped.
|
||||
*/
|
||||
|
|
|
@ -9,7 +9,9 @@ import retrofit2.http.Query
|
|||
interface MerchantsWebservice {
|
||||
|
||||
@GET("/api/v1/merchants")
|
||||
fun getMerchants(@Query(value = "\$skip") skip: Int): Call<FeathersResponse<Merchant>>
|
||||
fun getMerchants(@Query(value = "\$skip") skip: Int,
|
||||
@Query(value = "\$limit") limit: Int = 50):
|
||||
Call<FeathersResponse<Merchant>>
|
||||
|
||||
@GET("api/v2/tellers")
|
||||
fun getTellers(@Query(value = "\$skip") skip: Int): Call<FeathersResponse<Teller>>
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package cy.agorise.bitsybitshareswallet.repositories
|
||||
|
||||
import android.content.Context
|
||||
import android.os.AsyncTask
|
||||
import androidx.lifecycle.LiveData
|
||||
import cy.agorise.bitsybitshareswallet.database.BitsyDatabase
|
||||
import cy.agorise.bitsybitshareswallet.database.daos.MerchantDao
|
||||
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
||||
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||
import retrofit2.Call
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
|
||||
class MerchantRepository internal constructor(context: Context) : retrofit2.Callback<FeathersResponse<Merchant>> {
|
||||
|
||||
private val mMerchantDao: MerchantDao
|
||||
|
||||
init {
|
||||
val db = BitsyDatabase.getDatabase(context)
|
||||
mMerchantDao = db!!.merchantDao()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a LiveData object directly from the database while the response from the WebService is obtained.
|
||||
*/
|
||||
fun getAll(): LiveData<List<Merchant>> {
|
||||
refreshMerchants()
|
||||
return mMerchantDao.getAll()
|
||||
}
|
||||
|
||||
private fun refreshMerchants() {
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl(Constants.MERCHANTS_WEBSERVICE_URL)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
|
||||
val ambassadorService = retrofit.create<MerchantsWebservice>(MerchantsWebservice::class.java)
|
||||
val call = ambassadorService.getMerchants(0)
|
||||
call.enqueue(this)
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call<FeathersResponse<Merchant>>, response: Response<FeathersResponse<Merchant>>) {
|
||||
if (response.isSuccessful) {
|
||||
val res: FeathersResponse<Merchant>? = response.body()
|
||||
val merchants = res?.data ?: return
|
||||
insertAllAsyncTask(mMerchantDao).execute(merchants)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<FeathersResponse<Merchant>>, t: Throwable) { /* Do nothing */ }
|
||||
|
||||
private class insertAllAsyncTask internal constructor(private val mAsyncTaskDao: MerchantDao) :
|
||||
AsyncTask<List<Merchant>, Void, Void>() {
|
||||
|
||||
override fun doInBackground(vararg merchants: List<Merchant>): Void? {
|
||||
// TODO Delete all first
|
||||
mAsyncTaskDao.insertAll(merchants[0])
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.Merchant
|
||||
import cy.agorise.bitsybitshareswallet.repositories.MerchantRepository
|
||||
|
||||
class MerchantViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private var mMerchantRepository = MerchantRepository(application)
|
||||
|
||||
internal fun getAllMerchants(): LiveData<List<Merchant>> {
|
||||
return mMerchantRepository.getAll()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue