Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: [ANDROAPP-6131] Add progress when event list is loading
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo <[email protected]>
Balcan committed Jun 13, 2024
1 parent e202ed5 commit 670944f
Showing 24 changed files with 363 additions and 391 deletions.
Original file line number Diff line number Diff line change
@@ -36,6 +36,9 @@ class DatasetCardMapper(
onCardCLick: () -> Unit,
): ListCardUiModel {
return ListCardUiModel(
id = with(dataset) {
"${datasetUid()}_${periodId()}_${orgUnitUid()}_${catOptionComboUid()}"
},
title = dataset.namePeriod(),
lastUpdated = dataset.lastUpdated().toDateSpan(context),
additionalInfo = getAdditionalInfoList(dataset, editable),
Original file line number Diff line number Diff line change
@@ -248,10 +248,6 @@ class ProgramEventDetailActivity :
binding.name = programModel.displayName()
}

override fun showFilterProgress() {
programEventsViewModel.setProgress(true)
}

override fun renderError(message: String) {
if (activity != null) {
MaterialAlertDialogBuilder(activity, R.style.MaterialDialog)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -94,7 +94,6 @@ class ProgramEventDetailPresenter(
)
compositeDisposable.add(
filterManager.asFlowable().onBackpressureLatest()
.doOnNext { view.showFilterProgress() }
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.subscribe(
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
package org.dhis2.usescases.programEventDetail

import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import androidx.paging.PagingData
import io.reactivex.Flowable
import io.reactivex.Single
import org.dhis2.commons.data.EventViewModel
import kotlinx.coroutines.flow.Flow
import org.dhis2.commons.data.ProgramEventViewModel
import org.hisp.dhis.android.core.category.CategoryOptionCombo
import org.hisp.dhis.android.core.common.FeatureType
import org.hisp.dhis.android.core.event.Event
import org.hisp.dhis.android.core.event.EventFilter
import org.hisp.dhis.android.core.program.Program
import org.hisp.dhis.android.core.program.ProgramStage

interface ProgramEventDetailRepository {
fun filteredProgramEvents(): LiveData<PagedList<EventViewModel>>
fun filteredProgramEvents(): Flow<PagingData<Event>>
fun filteredEventsForMap(): Flowable<ProgramEventMapData>
fun program(): Single<Program?>
fun getAccessDataWrite(): Boolean
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package org.dhis2.usescases.programEventDetail

import androidx.lifecycle.LiveData
import androidx.paging.DataSource
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import androidx.paging.PagingData
import com.mapbox.geojson.FeatureCollection
import dhis2.org.analytics.charts.Charts
import io.reactivex.Flowable
import io.reactivex.Single
import org.dhis2.commons.data.EventViewModel
import kotlinx.coroutines.flow.Flow
import org.dhis2.commons.data.ProgramEventViewModel
import org.dhis2.commons.filters.data.FilterPresenter
import org.dhis2.maps.geometry.mapper.featurecollection.MapCoordinateFieldToFeatureCollection
@@ -41,22 +38,11 @@ class ProgramEventDetailRepositoryImpl internal constructor(
filterPresenter.filteredEventProgram(it)
}

override fun filteredProgramEvents(): LiveData<PagedList<EventViewModel>> {
override fun filteredProgramEvents(): Flow<PagingData<Event>> {
val program = program().blockingGet() ?: throw NullPointerException()
val dataSource = filterPresenter
return filterPresenter
.filteredEventProgram(program)
.dataSource
.map { event ->
mapper.eventToEventViewModel(event)
}
return LivePagedListBuilder(
object : DataSource.Factory<Event, EventViewModel>() {
override fun create(): DataSource<Event, EventViewModel> {
return dataSource
}
},
20,
).build()
.getPagingData(10)
}

override fun filteredEventsForMap(): Flowable<ProgramEventMapData> {
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ interface ProgramEventDetailView : AbstractActivityContracts.View {
fun renderError(message: String)
fun showHideFilter()
fun setWritePermission(canWrite: Boolean)
fun showFilterProgress()
fun updateFilters(totalFilters: Int)
fun openOrgUnitTreeSelector()
fun showPeriodRequest(periodRequest: PeriodRequest)
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ class ProgramEventDetailViewModel(
val dispatcher: DispatcherProvider,
val createEventUseCase: CreateEventUseCase,
) : ViewModel() {
private val progress = MutableLiveData(true)
private val progress = MutableLiveData(false)
val writePermission = MutableLiveData(false)
val eventSyncClicked = MutableLiveData<String?>(null)
val eventClicked = MutableLiveData<Pair<String, String>?>(null)
Original file line number Diff line number Diff line change
@@ -4,126 +4,64 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Modifier
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.test.espresso.idling.concurrent.IdlingThreadPoolExecutor
import org.dhis2.R
import org.dhis2.commons.data.EventViewModel
import org.dhis2.commons.filters.workingLists.WorkingListChipGroup
import org.dhis2.commons.filters.workingLists.WorkingListViewModel
import org.dhis2.commons.filters.workingLists.WorkingListViewModelFactory
import org.dhis2.commons.resources.ColorUtils
import org.dhis2.databinding.FragmentProgramEventDetailListBinding
import org.dhis2.usescases.general.FragmentGlobalAbstract
import org.dhis2.usescases.programEventDetail.ProgramEventDetailActivity
import org.dhis2.usescases.programEventDetail.ProgramEventDetailLiveAdapter
import org.dhis2.usescases.programEventDetail.ProgramEventDetailViewModel
import org.dhis2.usescases.programEventDetail.eventList.ui.mapper.EventCardMapper
import org.hisp.dhis.mobile.ui.designsystem.theme.Spacing
import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit
import javax.inject.Inject

class EventListFragment : FragmentGlobalAbstract(), EventListFragmentView {

lateinit var binding: FragmentProgramEventDetailListBinding
private var liveAdapter: ProgramEventDetailLiveAdapter? = null
private val programEventsViewModel: ProgramEventDetailViewModel by activityViewModels()
private var liveDataList: LiveData<PagedList<EventViewModel>>? = null
class EventListFragment : FragmentGlobalAbstract() {

@Inject
lateinit var presenter: EventListPresenter
lateinit var eventListViewModelFactory: EventListPresenterFactory

@Inject
lateinit var colorUtils: ColorUtils
lateinit var workingListViewModelFactory: WorkingListViewModelFactory

@Inject
lateinit var cardMapper: EventCardMapper

@Inject
lateinit var workingListViewModelFactory: WorkingListViewModelFactory

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
(activity as ProgramEventDetailActivity).component
?.plus(EventListModule(this))
?.plus(EventListModule())
?.inject(this)
programEventsViewModel.setProgress(true)

val bgThreadPoolExecutor = IdlingThreadPoolExecutor(
"DiffExecutor",
2,
2,
0L,
TimeUnit.MILLISECONDS,
LinkedBlockingQueue(),
Executors.defaultThreadFactory(),
)

val config = AsyncDifferConfig.Builder(ProgramEventDetailLiveAdapter.diffCallback)
.setBackgroundThreadExecutor(bgThreadPoolExecutor)
.build()

val program = presenter.program() ?: throw NullPointerException()
liveAdapter =
ProgramEventDetailLiveAdapter(
program,
programEventsViewModel,
colorUtils,
cardMapper,
config,
)
return FragmentProgramEventDetailListBinding.inflate(inflater, container, false)
.apply {
binding = this
recycler.adapter = liveAdapter
configureWorkingList()
}.root
}
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val workingListViewModel by viewModels<WorkingListViewModel> { workingListViewModelFactory }
val eventListViewModel by viewModels<EventListViewModel> { eventListViewModelFactory }
val programEventsViewModel by activityViewModels<ProgramEventDetailViewModel>()
val cardClicked by eventListViewModel.onEventCardClick.collectAsState(null)
val syncClicked by eventListViewModel.onSyncClick.collectAsState(null)

override fun onResume() {
super.onResume()
programEventsViewModel.setProgress(true)
presenter.init()
}
LaunchedEffect(key1 = cardClicked) {
cardClicked?.let {
programEventsViewModel.eventClicked.value = it
}
}

override fun setLiveData(pagedListLiveData: LiveData<PagedList<EventViewModel>>) {
liveDataList?.removeObservers(viewLifecycleOwner)
this.liveDataList = pagedListLiveData
liveDataList?.observe(viewLifecycleOwner) { pagedList: PagedList<EventViewModel> ->
programEventsViewModel.setProgress(false)
liveAdapter?.submitList(pagedList) {
if ((binding.recycler.adapter?.itemCount ?: 0) == 0) {
binding.emptyTeis.text = getString(R.string.empty_tei_add)
binding.emptyTeis.visibility = View.VISIBLE
binding.recycler.visibility = View.GONE
} else {
binding.emptyTeis.visibility = View.GONE
binding.recycler.visibility = View.VISIBLE
LaunchedEffect(key1 = syncClicked) {
programEventsViewModel.eventSyncClicked.value = syncClicked
}
EventListIdlingResourceSingleton.decrement()
}
}
}

private fun configureWorkingList() {
binding.filterLayout.apply {
setViewCompositionStrategy(
ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed,
)
setContent {
val workingListViewModel by viewModels<WorkingListViewModel> { workingListViewModelFactory }
WorkingListChipGroup(Modifier.padding(top = Spacing.Spacing16), workingListViewModel)
EventListScreen(
eventListViewModel,
workingListViewModel,
)
}
}
}
Loading

0 comments on commit 670944f

Please sign in to comment.