@@ -7,7 +7,10 @@ import android.view.LayoutInflater
77import android.view.View
88import android.view.ViewGroup
99import androidx.appcompat.app.AppCompatActivity
10- import androidx.recyclerview.widget.LinearLayoutManager
10+ import androidx.compose.runtime.getValue
11+ import androidx.compose.runtime.mutableStateOf
12+ import androidx.compose.runtime.setValue
13+ import androidx.compose.ui.platform.ViewCompositionStrategy
1114import com.f2prateek.rx.preferences2.Preference
1215import com.google.android.material.dialog.MaterialAlertDialogBuilder
1316import com.jakewharton.rxbinding3.view.clicks
@@ -17,25 +20,23 @@ import io.reactivex.Observable
1720import io.reactivex.disposables.CompositeDisposable
1821import io.reactivex.rxkotlin.cast
1922import io.reactivex.rxkotlin.ofType
23+ import io.reactivex.subjects.PublishSubject
2024import kotlinx.parcelize.Parcelize
2125import org.simple.clinic.R
2226import org.simple.clinic.ReportAnalyticsEvents
2327import org.simple.clinic.activity.permissions.RequestPermissions
2428import org.simple.clinic.activity.permissions.RuntimePermissions
2529import org.simple.clinic.appconfig.Country
2630import org.simple.clinic.contactpatient.ContactPatientBottomSheet
27- import org.simple.clinic.databinding.ListItemDividerBinding
28- import org.simple.clinic.databinding.ListItemNoPendingPatientsBinding
29- import org.simple.clinic.databinding.ListItemOverdueListSectionHeaderBinding
30- import org.simple.clinic.databinding.ListItemOverduePatientBinding
31- import org.simple.clinic.databinding.ListItemOverduePendingListFooterBinding
32- import org.simple.clinic.databinding.ListItemSearchOverduePatientButtonBinding
3331import org.simple.clinic.databinding.ScreenOverdueBinding
3432import org.simple.clinic.di.injector
3533import org.simple.clinic.feature.Feature.OverdueInstantSearch
3634import org.simple.clinic.feature.Feature.PatientReassignment
3735import org.simple.clinic.feature.Features
3836import org.simple.clinic.home.HomeScreen
37+ import org.simple.clinic.home.overdue.compose.OverdueAppointmentListItem
38+ import org.simple.clinic.home.overdue.compose.OverdueUiModel
39+ import org.simple.clinic.home.overdue.compose.OverdueUiModelMapper
3940import org.simple.clinic.home.overdue.search.OverdueSearchScreen
4041import org.simple.clinic.navigation.v2.Router
4142import org.simple.clinic.navigation.v2.ScreenKey
@@ -54,7 +55,6 @@ import org.simple.clinic.util.UserClock
5455import org.simple.clinic.util.UtcClock
5556import org.simple.clinic.util.applyInsetsBottomPadding
5657import org.simple.clinic.util.unsafeLazy
57- import org.simple.clinic.widgets.ItemAdapter
5858import org.simple.clinic.widgets.UiEvent
5959import java.time.Instant
6060import java.time.LocalDate
@@ -115,37 +115,13 @@ class OverdueScreen : BaseScreen<
115115 @Inject
116116 lateinit var locale: Locale
117117
118- private val overdueListAdapter = ItemAdapter (
119- diffCallback = OverdueAppointmentListItem .DiffCallback (),
120- bindings = mapOf (
121- R .layout.list_item_overdue_patient to { layoutInflater, parent ->
122- ListItemOverduePatientBinding .inflate(layoutInflater, parent, false )
123- },
124- R .layout.list_item_overdue_list_section_header to { layoutInflater, parent ->
125- ListItemOverdueListSectionHeaderBinding .inflate(layoutInflater, parent, false )
126- },
127- R .layout.list_item_overdue_pending_list_footer to { layoutInflater, parent ->
128- ListItemOverduePendingListFooterBinding .inflate(layoutInflater, parent, false )
129- },
130- R .layout.list_item_no_pending_patients to { layoutInflater, parent ->
131- ListItemNoPendingPatientsBinding .inflate(layoutInflater, parent, false )
132- },
133- R .layout.list_item_divider to { layoutInflater, parent ->
134- ListItemDividerBinding .inflate(layoutInflater, parent, false )
135- },
136- R .layout.list_item_search_overdue_patient_button to { layoutInflater, parent ->
137- ListItemSearchOverduePatientButtonBinding .inflate(layoutInflater, parent, false )
138- }
139- )
140- )
141-
142118 private val disposable = CompositeDisposable ()
143119
144120 private val viewForEmptyList
145121 get() = binding.viewForEmptyList
146122
147- private val overdueRecyclerView
148- get() = binding.overdueRecyclerView
123+ private val composeView
124+ get() = binding.composeView
149125
150126 private val overdueProgressBar
151127 get() = binding.overdueProgressBar
@@ -172,18 +148,22 @@ class OverdueScreen : BaseScreen<
172148 country.isoCountryCode == Country .INDIA
173149 }
174150
151+ private var uiModelsState by mutableStateOf<List <OverdueUiModel >>(emptyList())
152+
175153 override fun defaultModel () = OverdueModel .create()
176154
177155 override fun bindView (layoutInflater : LayoutInflater , container : ViewGroup ? ) =
178156 ScreenOverdueBinding .inflate(layoutInflater, container, false )
179157
180158 override fun uiRenderer () = OverdueUiRenderer (ui = this )
181159
160+ private val composeUiEvents = PublishSubject .create<OverdueEvent >()
161+
182162 override fun events () = Observable .mergeArray(
183- overdueListAdapter.itemEvents,
184163 downloadOverdueListClicks(),
185164 shareOverdueListClicks(),
186- clearSelectedOverdueAppointmentClicks()
165+ clearSelectedOverdueAppointmentClicks(),
166+ composeUiEvents,
187167 )
188168 .compose(RequestPermissions (runtimePermissions, screenResults.streamResults().ofType()))
189169 .compose(runtimeNetworkStatus::apply)
@@ -218,12 +198,38 @@ class OverdueScreen : BaseScreen<
218198
219199 buttonsFrame.applyInsetsBottomPadding()
220200
221- overdueRecyclerView.adapter = overdueListAdapter
222- overdueRecyclerView.layoutManager = LinearLayoutManager (context)
201+ composeView.apply {
202+ setViewCompositionStrategy(
203+ ViewCompositionStrategy .DisposeOnViewTreeLifecycleDestroyed
204+ )
205+ setContent {
206+ OverdueAppointmentListItem (
207+ uiModels = uiModelsState,
208+ onCallClicked = { patientId ->
209+ composeUiEvents.onNext(CallPatientClicked (patientId))
210+ },
211+ onRowClicked = { patientId ->
212+ composeUiEvents.onNext(OverduePatientClicked (patientId))
213+ },
214+ onCheckboxClicked = { appointmentUuid ->
215+ composeUiEvents.onNext(OverdueAppointmentCheckBoxClicked (appointmentUuid))
216+ },
217+ onSearch = {
218+ composeUiEvents.onNext(OverdueSearchButtonClicked )
219+ },
220+ onSectionHeaderClick = { overdueAppointmentSectionTitle ->
221+ composeUiEvents.onNext(ChevronClicked (overdueAppointmentSectionTitle))
222+ },
223+ onSectionFooterClick = {
224+ composeUiEvents.onNext(PendingListFooterClicked )
225+ }
226+ )
227+ }
228+ }
223229 }
224230
231+
225232 override fun onDestroyView () {
226- overdueRecyclerView.adapter = null
227233 disposable.clear()
228234 super .onDestroyView()
229235 }
@@ -267,7 +273,7 @@ class OverdueScreen : BaseScreen<
267273 selectedOverdueAppointments : Set <UUID >,
268274 overdueListSectionStates : OverdueListSectionStates
269275 ) {
270- overdueListAdapter.submitList( OverdueAppointmentListItem .from(
276+ uiModelsState = OverdueUiModelMapper .from(
271277 overdueAppointmentSections = overdueAppointmentSections,
272278 clock = userClock,
273279 pendingListDefaultStateSize = pendingAppointmentsConfig.pendingListDefaultStateSize,
@@ -277,7 +283,8 @@ class OverdueScreen : BaseScreen<
277283 selectedOverdueAppointments = selectedOverdueAppointments,
278284 isPatientReassignmentFeatureEnabled = features.isEnabled(PatientReassignment ),
279285 locale = locale,
280- ))
286+ )
287+
281288 if (isOverdueListDownloadAndShareEnabled) {
282289 buttonsFrame.visibility = View .VISIBLE
283290 }
@@ -316,11 +323,11 @@ class OverdueScreen : BaseScreen<
316323 }
317324
318325 override fun showOverdueRecyclerView () {
319- overdueRecyclerView .visibility = View .VISIBLE
326+ composeView .visibility = View .VISIBLE
320327 }
321328
322329 override fun hideOverdueRecyclerView () {
323- overdueRecyclerView .visibility = View .GONE
330+ composeView .visibility = View .GONE
324331 }
325332
326333 override fun openOverdueSearch () {
0 commit comments