Skip to content

Commit

Permalink
Fix statistics UI logic components
Browse files Browse the repository at this point in the history
  • Loading branch information
forceporquillo committed Dec 2, 2021
1 parent f129e9d commit 3959e69
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ package dev.forcecodes.truckme.ui.statistics
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentOnAttachListener
import androidx.fragment.app.viewModels
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint
import dev.forcecodes.truckme.R
import dev.forcecodes.truckme.R.string
import dev.forcecodes.truckme.core.domain.statistics.DAILY
import dev.forcecodes.truckme.core.domain.statistics.DRIVER
import dev.forcecodes.truckme.databinding.FragmentStatisticsBinding
import dev.forcecodes.truckme.extensions.observeOnLifecycleStarted
import dev.forcecodes.truckme.extensions.repeatOnLifecycleParallel
import dev.forcecodes.truckme.extensions.viewBinding
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber

@AndroidEntryPoint
Expand All @@ -22,7 +23,6 @@ class StatisticsFragment : Fragment(R.layout.fragment_statistics) {
private val binding by viewBinding(FragmentStatisticsBinding::bind)
private val viewModel by viewModels<StatisticsViewModel>()


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

Expand All @@ -31,23 +31,11 @@ class StatisticsFragment : Fragment(R.layout.fragment_statistics) {

binding.viewPager.adapter = StatisticsStatePagerAdapter(this)

viewModel.loadStatistics()

observeOnLifecycleStarted {
viewModel.dateList.collect {
if (it.isNotEmpty()) {
binding.datePicker.hint = it.first()
viewModel.executeQuery(it.first())
setUiState(it.distinct())
}
}
}

observeOnLifecycleStarted {
viewModel.copyDeliveryInfo.collect { list ->
childFragmentManager.fragments.forEach { fragment ->
if (fragment is StatsPagerFragment) {
fragment.onChangeSearch(list)
repeatOnLifecycleParallel {
launch {
viewModel.filterType.collect {
if (it.isNotEmpty()) {
setUiState(it)
}
}
}
Expand All @@ -60,20 +48,24 @@ class StatisticsFragment : Fragment(R.layout.fragment_statistics) {
}
}.attach()

binding.datePicker.setOnSpinnerItemSelectedListener<String> { _, _, _, newItem ->
viewModel.executeQuery(newItem)
binding.datePicker.setOnSpinnerItemSelectedListener<String> { _, _, _, itemSelected ->
viewModel.filterStatsBy(itemSelected)
}

binding.daySpinner.setOnSpinnerItemSelectedListener<String> { _, _, _, newItem ->
viewModel.type = newItem
viewModel.reOrder()
binding.daySpinner.setOnSpinnerItemSelectedListener<String> { _, _, _, itemSelected ->
val filter = when (itemSelected) {
getString(string.driver) -> DRIVER
else -> DAILY
}

viewModel.filterTypeBy(filter)

val hintType = if (newItem == getString(string.driver)) {
val hintType = if (itemSelected == getString(string.driver)) {
getString(string.select_driver_type)
} else {
getString(string.select_date_type)
}
setUiState(viewModel.itemDelivered.value)

binding.searchType.text = hintType
}
}
Expand All @@ -82,11 +74,11 @@ class StatisticsFragment : Fragment(R.layout.fragment_statistics) {
binding.datePicker.apply {
clearSelectedItem()
if (items.isNotEmpty()) {
viewModel.filterStatsBy(items[0])
hint = items[0]
}
}
Timber.e("items $items")

binding.datePicker.setItems(items)
binding.datePicker.spinnerPopupHeight
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,115 +4,86 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.forcecodes.truckme.core.data.delivery.ItemDeliveredStats
import dev.forcecodes.truckme.core.data.fleets.FleetUiModel.DriverUri
import dev.forcecodes.truckme.core.domain.fleets.DeliveredItemStatsUseCase
import dev.forcecodes.truckme.core.domain.fleets.ObserveDriverFleetsUseCase
import dev.forcecodes.truckme.core.domain.statistics.DAILY
import dev.forcecodes.truckme.core.domain.statistics.FilteredDailyStatisticsUseCase
import dev.forcecodes.truckme.core.domain.statistics.DeliveredItemStatsUseCase
import dev.forcecodes.truckme.core.domain.statistics.ForceRefreshUseCase
import dev.forcecodes.truckme.core.domain.statistics.QueryParams
import dev.forcecodes.truckme.core.domain.statistics.StatisticsSortType
import dev.forcecodes.truckme.core.util.Result
import dev.forcecodes.truckme.core.util.successOr
import dev.forcecodes.truckme.core.util.tryOffer
import dev.forcecodes.truckme.ui.auth.signin.SignInViewModelDelegate
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import timber.log.Timber
import timber.log.Timber.Forest
import javax.inject.Inject

@HiltViewModel
class StatisticsViewModel @Inject constructor(
private val observeDriverFleetsUseCase: ObserveDriverFleetsUseCase,
private val filteredDailyStatisticsUseCase: FilteredDailyStatisticsUseCase,
private val deliveredItemStatsUseCase: DeliveredItemStatsUseCase,
private val forceRefreshUseCase: ForceRefreshUseCase,
signInViewModelDelegate: SignInViewModelDelegate,
) : ViewModel(), SignInViewModelDelegate by signInViewModelDelegate {

var type: String = DAY
private val _filterType = MutableStateFlow<List<String>>(emptyList())
val filterType = _filterType.asStateFlow()

private val _driverList = MutableStateFlow<List<String>>(emptyList())
val driverList = _driverList.asStateFlow()
private val _itemDeliveredStats = MutableStateFlow<List<ItemDeliveredStats>>(emptyList())
val itemDeliveredStats = _itemDeliveredStats.asStateFlow()

private val _dateList = MutableStateFlow<List<String>>(emptyList())
val dateList = _dateList.asStateFlow()

private val _itemDelivered = MutableStateFlow<List<String>>(emptyList())
val itemDelivered = _itemDelivered.asStateFlow()

private val _deliveryInfo = MutableStateFlow<List<ItemDeliveredStats>>(emptyList())

private val _copyDeliveryInfo = MutableStateFlow<List<ItemDeliveredStats>>(emptyList())
val copyDeliveryInfo = _copyDeliveryInfo.asStateFlow()
@StatisticsSortType
private var sortFilterType: String = DAILY

init {
loadStatistics()
refresh()
filterStatsBy(null)
filterTypeBy()
}

fun loadStatistics() {
type = DAY
fun filterTypeBy(@StatisticsSortType type: String = DAILY) {
if (sortFilterType != type){
sortFilterType = type
}

viewModelScope.launch {
launch source@{
deliveredItemStatsUseCase(
userIdValue ?: return@source
).map { value: Result<List<ItemDeliveredStats>> ->
val list = value.successOr(emptyList())
_dateList.value = list.sortedByDescending {
it.metadata.date
}.map {
it.metadata.date.orEmpty()
}
list
}.collect {
_deliveryInfo.value = it
if (it.isNotEmpty()) {
executeQuery(it[0].dateAccomplish ?: "")
} else {
_copyDeliveryInfo.value = emptyList()
filteredDailyStatisticsUseCase(type).collect { result ->
_filterType.value = result.successOr(emptyList()).also { list ->
if (list.isNotEmpty()) {
filterStatsBy(list.first())
}
}
}
launch fleets@{
observeDriverFleetsUseCase(userIdValue ?: return@fleets).collect {
_driverList.mapFleetList(it)
}
}
}
}

fun reOrder() {
_itemDelivered.value = emptyList()

if (type == DAY) {
_itemDelivered.value =
_deliveryInfo.value.map { it.metadata.date ?: "" }.distinct()
}

if (type == DRIVER) {
_itemDelivered.value = driverList.value
private fun refresh() {
viewModelScope.launch {
forceRefreshUseCase(userIdValue ?: return@launch)
.collect()
}

Timber.e("items ${_itemDelivered.value}")
}

private fun MutableStateFlow<List<String>>.mapFleetList(result: Result<List<DriverUri>>) {
value = if (result is Result.Success) result.data.map { it.fullName } else emptyList()
}

fun executeQuery(newItem: String) {
if (type == DAY) {
_copyDeliveryInfo.value = _deliveryInfo.value.filter { it.dateAccomplish == newItem }
}
var previousFilter: String? = ""

if (type == DRIVER) {
_copyDeliveryInfo.value = _deliveryInfo.value.filter { it.metadata.driverName == newItem }
fun filterStatsBy(field: String?) {
if (previousFilter != field) {
previousFilter = field
}
Timber.e("items ${_copyDeliveryInfo.value}")
}

companion object {
private const val DAY = "Day"
private const val DRIVER = "Driver"
}
viewModelScope.launch {
val userIdOrIgnore = userIdValue ?: return@launch
val params = QueryParams(userIdOrIgnore, sortFilterType, field)

override fun onCleared() {
super.onCleared()
Timber.e("onCleared()")
deliveredItemStatsUseCase(params).collect { list ->
_itemDeliveredStats.value = list.successOr(emptyList())
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import dev.forcecodes.truckme.core.data.delivery.ItemDeliveredStats
class StatsDeliveredItemsFragment : StatsPagerFragment() {

override fun onChangeSearch(items: List<ItemDeliveredStats>) {
// space for rent
}

override fun onStatsPage(items: List<ItemDeliveredStats>) {
adapter.setItems(items.filter { !it.metadata.bound })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,33 @@ package dev.forcecodes.truckme.ui.statistics
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import dagger.hilt.android.AndroidEntryPoint
import dev.forcecodes.truckme.R
import dev.forcecodes.truckme.core.data.delivery.ItemDeliveredStats
import dev.forcecodes.truckme.databinding.FragmentStatsPagerBinding
import dev.forcecodes.truckme.extensions.observeOnLifecycleStarted
import kotlinx.coroutines.flow.collect

@AndroidEntryPoint
abstract class StatsPagerFragment : Fragment(R.layout.fragment_stats_pager),
StatisticsFragmentListener {

protected val viewModel by viewModels<StatisticsViewModel>({ requireParentFragment() })
protected val adapter by lazy { StatisticsItemAdapter() }

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val binding = FragmentStatsPagerBinding.bind(view)
binding.statsListView.adapter = adapter

observeOnLifecycleStarted {
viewModel.itemDeliveredStats.collect {
onStatsPage(it)
}
}
}

abstract fun onStatsPage(items: List<ItemDeliveredStats>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import dev.forcecodes.truckme.core.data.delivery.ItemDeliveredStats
class StatsReceivedItemsFragment : StatsPagerFragment() {

override fun onChangeSearch(items: List<ItemDeliveredStats>) {
// space for rent
}

override fun onStatsPage(items: List<ItemDeliveredStats>) {
adapter.setItems(items.filter { it.metadata.bound })
}
}

0 comments on commit 3959e69

Please sign in to comment.