Update: Search query, section & order logic in MainNavVM. Remove: PagedList usage in MainNavVM.

This commit is contained in:
machiav3lli 2022-02-17 23:59:23 +01:00
parent cfa68524f3
commit 1fdc74731e
2 changed files with 48 additions and 75 deletions

View File

@ -87,6 +87,16 @@ interface ProductDao : BaseDao<Product> {
buildProductQuery(installed, updates, searchQuery, section, order, numberOfItems) buildProductQuery(installed, updates, searchQuery, section, order, numberOfItems)
) )
@RawQuery(observedEntities = [Product::class])
fun queryLiveList(query: SupportSQLiteQuery): LiveData<List<Product>>
fun queryLiveList(
installed: Boolean, updates: Boolean, searchQuery: String,
section: Section, order: Order, numberOfItems: Int = 0
): LiveData<List<Product>> = queryLiveList(
buildProductQuery(installed, updates, searchQuery, section, order, numberOfItems)
)
@RawQuery(observedEntities = [Product::class]) @RawQuery(observedEntities = [Product::class])
fun queryList( fun queryList(
query: SupportSQLiteQuery query: SupportSQLiteQuery

View File

@ -1,8 +1,6 @@
package com.looker.droidify.ui.viewmodels package com.looker.droidify.ui.viewmodels
import androidx.lifecycle.* import androidx.lifecycle.*
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import com.looker.droidify.content.Preferences import com.looker.droidify.content.Preferences
import com.looker.droidify.database.DatabaseX import com.looker.droidify.database.DatabaseX
import com.looker.droidify.database.entity.Product import com.looker.droidify.database.entity.Product
@ -11,46 +9,26 @@ import com.looker.droidify.entity.Order
import com.looker.droidify.entity.Section import com.looker.droidify.entity.Section
import com.looker.droidify.ui.fragments.Request import com.looker.droidify.ui.fragments.Request
import com.looker.droidify.ui.fragments.Source import com.looker.droidify.ui.fragments.Source
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class MainNavFragmentViewModelX(val db: DatabaseX, primarySource: Source, secondarySource: Source) : class MainNavFragmentViewModelX(
val db: DatabaseX,
primarySource: Source,
secondarySource: Source
) :
ViewModel() { ViewModel() {
private val _order = MutableStateFlow(Order.LAST_UPDATE) private val order = MutableLiveData(Order.LAST_UPDATE)
private val _sections = MutableStateFlow<Section>(Section.All) private val sections = MutableLiveData<Section>(Section.All)
private val _searchQuery = MutableStateFlow("") private val searchQuery = MutableLiveData("")
val order: StateFlow<Order> = _order.stateIn(
initialValue = Order.LAST_UPDATE,
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000)
)
val sections: StateFlow<Section> = _sections.stateIn(
initialValue = Section.All,
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000)
)
val searchQuery: StateFlow<String> = _searchQuery.stateIn(
initialValue = "",
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000)
)
fun request(source: Source): Request { fun request(source: Source): Request {
var mSearchQuery = "" var mSearchQuery = ""
var mSections: Section = Section.All var mSections: Section = Section.All
var mOrder: Order = Order.NAME var mOrder: Order = Order.NAME
viewModelScope.launch { sections.value?.let { if (source.sections) mSections = it }
launch { searchQuery.collect { if (source.sections) mSearchQuery = it } } order.value?.let { if (source.order) mOrder = it }
launch { sections.collect { if (source.sections) mSections = it } } searchQuery.value?.let { if (source.sections) mSearchQuery = it }
launch { order.collect { if (source.order) mOrder = it } }
}
return when (source) { return when (source) {
Source.AVAILABLE -> Request.ProductsAll( Source.AVAILABLE -> Request.ProductsAll(
mSearchQuery, mSearchQuery,
@ -83,73 +61,58 @@ class MainNavFragmentViewModelX(val db: DatabaseX, primarySource: Source, second
} }
} }
private val pagedListConfig by lazy { private var primaryRequest = request(primarySource)
PagedList.Config.Builder() val primaryProducts = MediatorLiveData<List<Product>>()
.setPageSize(30) private var secondaryRequest = request(secondarySource)
.setPrefetchDistance(30) val secondaryProducts = MediatorLiveData<List<Product>>()
.setEnablePlaceholders(false)
.build()
}
private val primaryRequest = request(primarySource)
val primaryProducts: LiveData<PagedList<Product>> by lazy {
LivePagedListBuilder(
db.productDao.queryList(
installed = primaryRequest.installed,
updates = primaryRequest.updates,
searchQuery = primaryRequest.searchQuery,
section = primaryRequest.section,
order = primaryRequest.order,
numberOfItems = primaryRequest.numberOfItems
), pagedListConfig
).build()
}
private val secondaryRequest = request(secondarySource)
val secondaryProducts: LiveData<PagedList<Product>> by lazy {
LivePagedListBuilder(
db.productDao.queryList(
installed = secondaryRequest.installed,
updates = secondaryRequest.updates,
searchQuery = secondaryRequest.searchQuery,
section = secondaryRequest.section,
order = secondaryRequest.order,
numberOfItems = secondaryRequest.numberOfItems
), pagedListConfig
).build()
}
val repositories = MediatorLiveData<List<Repository>>() val repositories = MediatorLiveData<List<Repository>>()
init { init {
primaryProducts.addSource(
productsListMediator(primaryRequest),
primaryProducts::setValue
)
secondaryProducts.addSource(
productsListMediator(secondaryRequest),
secondaryProducts::setValue
)
repositories.addSource(db.repositoryDao.allLive, repositories::setValue) repositories.addSource(db.repositoryDao.allLive, repositories::setValue)
} }
fun setSection(newSection: Section, perform: () -> Unit) { fun setSection(newSection: Section) {
viewModelScope.launch { viewModelScope.launch {
if (newSection != sections.value) { if (newSection != sections.value) {
_sections.emit(newSection) sections.value = newSection
launch(Dispatchers.Main) { perform() }
} }
} }
} }
fun setOrder(newOrder: Order, perform: () -> Unit) { fun setSection(newOrder: Order) {
viewModelScope.launch { viewModelScope.launch {
if (newOrder != order.value) { if (newOrder != order.value) {
_order.emit(newOrder) order.value = newOrder
launch(Dispatchers.Main) { perform() }
} }
} }
} }
fun setSearchQuery(newSearchQuery: String, perform: () -> Unit) { fun setSection(newSearchQuery: String) {
viewModelScope.launch { viewModelScope.launch {
if (newSearchQuery != searchQuery.value) { if (newSearchQuery != searchQuery.value) {
_searchQuery.emit(newSearchQuery) searchQuery.value = newSearchQuery
launch(Dispatchers.Main) { perform() }
} }
} }
} }
private fun productsListMediator(request: Request) = db.productDao.queryLiveList(
installed = request.installed,
updates = request.updates,
searchQuery = request.searchQuery,
section = request.section,
order = request.order,
numberOfItems = request.numberOfItems
)
class Factory( class Factory(
val db: DatabaseX, val db: DatabaseX,
private val primarySource: Source, private val primarySource: Source,