diff --git a/src/main/kotlin/com/looker/droidify/screen/ProductsFragment.kt b/src/main/kotlin/com/looker/droidify/screen/ProductsFragment.kt index 70a5dc63..2e8c4013 100644 --- a/src/main/kotlin/com/looker/droidify/screen/ProductsFragment.kt +++ b/src/main/kotlin/com/looker/droidify/screen/ProductsFragment.kt @@ -6,26 +6,29 @@ import android.os.Parcelable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.looker.droidify.R import com.looker.droidify.database.CursorOwner import com.looker.droidify.database.Database import com.looker.droidify.entity.ProductItem +import com.looker.droidify.ui.ProductsViewModel import com.looker.droidify.utility.RxUtils import com.looker.droidify.widget.RecyclerFastScroller import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.disposables.Disposable import io.reactivex.rxjava3.schedulers.Schedulers +import kotlinx.coroutines.flow.collect class ProductsFragment() : BaseFragment(), CursorOwner.Callback { + + private val viewModel: ProductsViewModel by viewModels() + companion object { private const val EXTRA_SOURCE = "source" - - private const val STATE_CURRENT_SEARCH_QUERY = "currentSearchQuery" - private const val STATE_CURRENT_SECTION = "currentSection" - private const val STATE_CURRENT_ORDER = "currentOrder" private const val STATE_LAYOUT_MANAGER = "layoutManager" } @@ -44,13 +47,25 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { val source: Source get() = requireArguments().getString(EXTRA_SOURCE)!!.let(Source::valueOf) - private var searchQuery = "" - private var section: ProductItem.Section = ProductItem.Section.All - private var order = ProductItem.Order.NAME + private val searchQuery: String + get() { + var _searchQuery = "" + lifecycleScope.launchWhenStarted { viewModel.searchQuery.collect { _searchQuery = it } } + return _searchQuery + } + private val section: ProductItem.Section + get() { + var _section: ProductItem.Section = ProductItem.Section.All + lifecycleScope.launchWhenStarted { viewModel.sections.collect { _section = it } } + return _section + } + private val order: ProductItem.Order + get() { + var _order: ProductItem.Order = ProductItem.Order.LAST_UPDATE + lifecycleScope.launchWhenStarted { viewModel.order.collect { _order = it } } + return _order + } - private var currentSearchQuery = "" - private var currentSection: ProductItem.Section = ProductItem.Section.All - private var currentOrder = ProductItem.Order.NAME private var layoutManagerState: Parcelable? = null private var recyclerView: RecyclerView? = null @@ -98,12 +113,6 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - - currentSearchQuery = savedInstanceState?.getString(STATE_CURRENT_SEARCH_QUERY).orEmpty() - currentSection = - savedInstanceState?.getParcelable(STATE_CURRENT_SECTION) ?: ProductItem.Section.All - currentOrder = savedInstanceState?.getString(STATE_CURRENT_ORDER) - ?.let(ProductItem.Order::valueOf) ?: ProductItem.Order.NAME layoutManagerState = savedInstanceState?.getParcelable(STATE_LAYOUT_MANAGER) screenActivity.cursorOwner.attach(this, request) @@ -128,10 +137,6 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - - outState.putString(STATE_CURRENT_SEARCH_QUERY, currentSearchQuery) - outState.putParcelable(STATE_CURRENT_SECTION, currentSection) - outState.putString(STATE_CURRENT_ORDER, currentOrder.name) (layoutManagerState ?: recyclerView?.layoutManager?.onSaveInstanceState()) ?.let { outState.putParcelable(STATE_LAYOUT_MANAGER, it) } } @@ -149,23 +154,14 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { } } } - layoutManagerState?.let { layoutManagerState = null recyclerView?.layoutManager?.onRestoreInstanceState(it) } - - if (currentSearchQuery != searchQuery || currentSection != section || currentOrder != order) { - currentSearchQuery = searchQuery - currentSection = section - currentOrder = order - recyclerView?.scrollToPosition(0) - } } internal fun setSearchQuery(searchQuery: String) { - if (this.searchQuery != searchQuery) { - this.searchQuery = searchQuery + viewModel.setSearchQuery(searchQuery) { if (view != null) { screenActivity.cursorOwner.attach(this, request) } @@ -173,8 +169,7 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { } internal fun setSection(section: ProductItem.Section) { - if (this.section != section) { - this.section = section + viewModel.setSection(section) { if (view != null) { screenActivity.cursorOwner.attach(this, request) } @@ -182,8 +177,7 @@ class ProductsFragment() : BaseFragment(), CursorOwner.Callback { } internal fun setOrder(order: ProductItem.Order) { - if (this.order != order) { - this.order = order + viewModel.setOrder(order) { if (view != null) { screenActivity.cursorOwner.attach(this, request) } diff --git a/src/main/kotlin/com/looker/droidify/ui/ProductsViewModel.kt b/src/main/kotlin/com/looker/droidify/ui/ProductsViewModel.kt new file mode 100644 index 00000000..562ab35a --- /dev/null +++ b/src/main/kotlin/com/looker/droidify/ui/ProductsViewModel.kt @@ -0,0 +1,47 @@ +package com.looker.droidify.ui + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.looker.droidify.entity.ProductItem +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch + +class ProductsViewModel : ViewModel() { + + private val _order = MutableStateFlow(ProductItem.Order.LAST_UPDATE) + private val _sections = MutableStateFlow(ProductItem.Section.All) + private val _searchQuery = MutableStateFlow("") + + val order: StateFlow = _order + val sections: StateFlow = _sections + val searchQuery: StateFlow = _searchQuery + + fun setSection(newSection: ProductItem.Section, perform: () -> Unit) { + viewModelScope.launch(Dispatchers.Main) { + if (newSection != sections.value) { + _sections.emit(newSection) + perform() + } + } + } + + fun setOrder(newOrder: ProductItem.Order, perform: () -> Unit) { + viewModelScope.launch(Dispatchers.Main) { + if (newOrder != order.value) { + _order.emit(newOrder) + perform() + } + } + } + + fun setSearchQuery(newSearchQuery: String, perform: () -> Unit) { + viewModelScope.launch(Dispatchers.Main) { + if (newSearchQuery != searchQuery.value) { + _searchQuery.emit(newSearchQuery) + perform() + } + } + } +} \ No newline at end of file