Stash categories + code improvements

This commit is contained in:
Rahul Patel
2024-06-29 04:36:13 +05:30
committed by Aayush Gupta
parent 8a12ffcd96
commit c16ae15540
5 changed files with 71 additions and 29 deletions

View File

@@ -1,9 +1,11 @@
package com.aurora.store package com.aurora.store
import com.aurora.gplayapi.data.models.Category
import com.aurora.gplayapi.data.models.StreamBundle import com.aurora.gplayapi.data.models.StreamBundle
import com.aurora.gplayapi.data.models.StreamCluster import com.aurora.gplayapi.data.models.StreamCluster
import com.aurora.gplayapi.helpers.contracts.StreamContract import com.aurora.gplayapi.helpers.contracts.StreamContract
import com.aurora.gplayapi.helpers.contracts.TopChartsContract import com.aurora.gplayapi.helpers.contracts.TopChartsContract
typealias TopChartStash = Map<TopChartsContract.Type, Map<TopChartsContract.Chart, StreamCluster>> typealias TopChartStash = MutableMap<TopChartsContract.Type, MutableMap<TopChartsContract.Chart, StreamCluster>>
typealias HomeStash = MutableMap<StreamContract.Category, StreamBundle> typealias HomeStash = MutableMap<StreamContract.Category, StreamBundle>
typealias CategoryStash = MutableMap<Category.Type, List<Category>>

View File

@@ -24,9 +24,13 @@ import android.view.View
import androidx.fragment.app.viewModels import androidx.fragment.app.viewModels
import com.aurora.Constants import com.aurora.Constants
import com.aurora.gplayapi.data.models.Category import com.aurora.gplayapi.data.models.Category
import com.aurora.store.CategoryStash
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.ViewState
import com.aurora.store.data.ViewState.Empty.getDataAs
import com.aurora.store.databinding.FragmentGenericRecyclerBinding import com.aurora.store.databinding.FragmentGenericRecyclerBinding
import com.aurora.store.view.epoxy.views.CategoryViewModel_ import com.aurora.store.view.epoxy.views.CategoryViewModel_
import com.aurora.store.view.epoxy.views.shimmer.AppListViewShimmerModel_
import com.aurora.store.viewmodel.category.CategoryViewModel import com.aurora.store.viewmodel.category.CategoryViewModel
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -64,10 +68,37 @@ class CategoryFragment : BaseFragment(R.layout.fragment_generic_recycler) {
1 -> viewModel.getCategoryList(Category.Type.GAME) 1 -> viewModel.getCategoryList(Category.Type.GAME)
} }
viewModel.liveData.observe(viewLifecycleOwner) { categoryList -> val categoryType = when (pageType) {
binding.recycler.withModels { 1 -> Category.Type.GAME
else -> Category.Type.APPLICATION
}
viewModel.liveData.observe(viewLifecycleOwner) {
when (it) {
is ViewState.Success<*> -> {
val stash = it.getDataAs<CategoryStash>()
updateController(stash[categoryType])
}
else -> {
updateController(emptyList())
}
}
}
}
fun updateController(categories: List<Category>?) {
binding.recycler.withModels {
if (categories == null) {
for (i in 1..10) {
add(
AppListViewShimmerModel_()
.id(i)
)
}
} else {
setFilterDuplicates(true) setFilterDuplicates(true)
categoryList.forEach { categories.forEach {
add( add(
CategoryViewModel_() CategoryViewModel_()
.id(it.title) .id(it.title)

View File

@@ -29,13 +29,15 @@ import com.aurora.gplayapi.data.models.Category
import com.aurora.gplayapi.helpers.CategoryHelper import com.aurora.gplayapi.helpers.CategoryHelper
import com.aurora.gplayapi.helpers.contracts.CategoryContract import com.aurora.gplayapi.helpers.contracts.CategoryContract
import com.aurora.gplayapi.helpers.web.WebCategoryHelper import com.aurora.gplayapi.helpers.web.WebCategoryHelper
import com.aurora.store.CategoryStash
import com.aurora.store.data.ViewState
import com.aurora.store.data.network.HttpClient import com.aurora.store.data.network.HttpClient
import com.aurora.store.data.providers.AuthProvider import com.aurora.store.data.providers.AuthProvider
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel @HiltViewModel
@SuppressLint("StaticFieldLeak") // false positive, see https://github.com/google/dagger/issues/3253 @SuppressLint("StaticFieldLeak") // false positive, see https://github.com/google/dagger/issues/3253
@@ -43,7 +45,6 @@ class CategoryViewModel @Inject constructor(
@ApplicationContext private val context: Context, @ApplicationContext private val context: Context,
private val authProvider: AuthProvider private val authProvider: AuthProvider
) : ViewModel() { ) : ViewModel() {
private val TAG = CategoryViewModel::class.java.simpleName private val TAG = CategoryViewModel::class.java.simpleName
private val categoryHelper: CategoryHelper = CategoryHelper(authProvider.authData) private val categoryHelper: CategoryHelper = CategoryHelper(authProvider.authData)
@@ -52,22 +53,41 @@ class CategoryViewModel @Inject constructor(
private val webCategoryHelper: CategoryContract = WebCategoryHelper() private val webCategoryHelper: CategoryContract = WebCategoryHelper()
.using(HttpClient.getPreferredClient(context)) .using(HttpClient.getPreferredClient(context))
val liveData: MutableLiveData<List<Category>> = MutableLiveData() private var stash: CategoryStash = mutableMapOf(
Category.Type.APPLICATION to emptyList(),
Category.Type.GAME to emptyList()
)
val liveData = MutableLiveData<ViewState>()
private fun contract(): CategoryContract { private fun contract(): CategoryContract {
return if(authProvider.isAnonymous){ return if (authProvider.isAnonymous) {
webCategoryHelper webCategoryHelper
} else { } else {
categoryHelper categoryHelper
} }
} }
fun getCategoryList(type: Category.Type) { fun getCategoryList(type: Category.Type) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
val categories = getCategories(type)
if (categories.isNotEmpty()) {
liveData.postValue(ViewState.Success(stash))
}
try { try {
liveData.postValue(contract().getAllCategoriesList(type)) stash[type] = contract().getAllCategoriesList(type)
liveData.postValue(ViewState.Success(stash))
} catch (exception: Exception) { } catch (exception: Exception) {
Log.e(TAG, "Failed fetching list of categories", exception) Log.e(TAG, "Failed fetching list of categories", exception)
} }
} }
} }
private fun getCategories(type: Category.Type): List<Category> {
return stash.getOrPut(type) {
mutableListOf()
}
}
} }

View File

@@ -56,10 +56,7 @@ class StreamViewModel @Inject constructor(
val liveData: MutableLiveData<ViewState> = MutableLiveData() val liveData: MutableLiveData<ViewState> = MutableLiveData()
private var stash: HomeStash = mutableMapOf( private var stash: HomeStash = mutableMapOf()
StreamContract.Category.APPLICATION to StreamBundle(),
StreamContract.Category.GAME to StreamBundle()
)
fun contract(): StreamContract { fun contract(): StreamContract {
return if (authProvider.isAnonymous) { return if (authProvider.isAnonymous) {
@@ -145,8 +142,9 @@ class StreamViewModel @Inject constructor(
} }
private fun targetBundle(category: StreamContract.Category): StreamBundle { private fun targetBundle(category: StreamContract.Category): StreamBundle {
// stash is initialized with empty StreamBundle so this will never return null or throw an exception val streamBundle = stash.getOrPut(category){
val streamBundle = stash.getValue(category) StreamBundle()
}
return streamBundle return streamBundle
} }

View File

@@ -52,17 +52,7 @@ class TopChartViewModel @Inject constructor(
private val webTopChartsHelper: TopChartsContract = WebTopChartsHelper() private val webTopChartsHelper: TopChartsContract = WebTopChartsHelper()
.using(HttpClient.getPreferredClient(context)) .using(HttpClient.getPreferredClient(context))
private val dummyChart = mapOf( private var stash: TopChartStash = mutableMapOf()
TopChartsContract.Chart.TOP_GROSSING to StreamCluster(),
TopChartsContract.Chart.TOP_SELLING_FREE to StreamCluster(),
TopChartsContract.Chart.TOP_SELLING_PAID to StreamCluster(),
TopChartsContract.Chart.MOVERS_SHAKERS to StreamCluster(),
)
private var stash: TopChartStash = mapOf(
TopChartsContract.Type.APPLICATION to dummyChart,
TopChartsContract.Type.GAME to dummyChart
)
val liveData: MutableLiveData<ViewState> = MutableLiveData() val liveData: MutableLiveData<ViewState> = MutableLiveData()
@@ -124,8 +114,9 @@ class TopChartViewModel @Inject constructor(
type: TopChartsContract.Type, type: TopChartsContract.Type,
chart: TopChartsContract.Chart chart: TopChartsContract.Chart
): StreamCluster { ): StreamCluster {
// Stash is initialized with empty clusters so this will never return null or throw an exception val cluster = stash
val cluster = stash.getValue(type).getValue(chart) .getOrPut(type) { mutableMapOf() }
.getOrPut(chart) { StreamCluster() }
return cluster return cluster
} }
} }