Skip to content

Commit ee0686d

Browse files
author
sagarwal
committed
Refactor RecentPatientItem
1 parent 1970614 commit ee0686d

File tree

3 files changed

+128
-119
lines changed

3 files changed

+128
-119
lines changed

app/src/main/java/org/simple/clinic/recentpatient/RecentPatientItem.kt

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,17 @@ import androidx.paging.PagingData
44
import androidx.paging.map
55
import androidx.recyclerview.widget.DiffUtil
66
import io.reactivex.subjects.Subject
7-
import org.simple.clinic.R
8-
import org.simple.clinic.databinding.RecentPatientItemViewBinding
9-
import org.simple.clinic.medicalhistory.Answer.Suspected
10-
import org.simple.clinic.patient.Gender
117
import org.simple.clinic.patient.RecentPatient
12-
import org.simple.clinic.patient.displayIconRes
138
import org.simple.clinic.util.UserClock
14-
import org.simple.clinic.util.toLocalDateAtZone
159
import org.simple.clinic.widgets.PagingItemAdapter
1610
import org.simple.clinic.widgets.UiEvent
1711
import org.simple.clinic.widgets.recyclerview.BindingViewHolder
18-
import org.simple.clinic.widgets.visibleOrGone
19-
import java.time.Instant
2012
import java.time.LocalDate
2113
import java.time.format.DateTimeFormatter
2214
import java.util.UUID
2315

2416
data class RecentPatientItem(
25-
val uuid: UUID,
26-
val name: String,
27-
val age: Int,
28-
val gender: Gender,
29-
val updatedAt: Instant,
30-
val dateFormatter: DateTimeFormatter,
31-
val clock: UserClock,
32-
val isNewRegistration: Boolean,
33-
val isSuspectedForHypertension: Boolean,
34-
val isSuspectedForDiabetes: Boolean,
17+
private val model: RecentPatientUiModel
3518
) : PagingItemAdapter.Item<UiEvent> {
3619

3720
companion object {
@@ -41,7 +24,6 @@ data class RecentPatientItem(
4124
dateFormatter: DateTimeFormatter
4225
): PagingData<RecentPatientItem> {
4326
val today = LocalDate.now(userClock)
44-
4527
return recentPatients.map { recentPatientItem(it, today, userClock, dateFormatter) }
4628
}
4729

@@ -51,56 +33,26 @@ data class RecentPatientItem(
5133
userClock: UserClock,
5234
dateFormatter: DateTimeFormatter
5335
): RecentPatientItem {
54-
val patientRegisteredOnDate = recentPatient.patientRecordedAt.toLocalDateAtZone(userClock.zone)
55-
val isNewRegistration = today == patientRegisteredOnDate
56-
57-
return RecentPatientItem(
58-
uuid = recentPatient.uuid,
59-
name = recentPatient.fullName,
60-
age = recentPatient.ageDetails.estimateAge(userClock),
61-
gender = recentPatient.gender,
62-
updatedAt = recentPatient.updatedAt,
36+
val model = RecentPatientUiModel.fromDomain(
37+
recentPatient = recentPatient,
38+
today = today,
39+
userClock = userClock,
6340
dateFormatter = dateFormatter,
64-
clock = userClock,
65-
isNewRegistration = isNewRegistration,
66-
isSuspectedForHypertension = recentPatient.diagnosedWithHypertension == Suspected,
67-
isSuspectedForDiabetes = recentPatient.diagnosedWithDiabetes == Suspected
41+
isEligibleForReassignment = false
6842
)
43+
44+
return RecentPatientItem(model)
6945
}
7046
}
7147

72-
override fun layoutResId(): Int = R.layout.recent_patient_item_view
48+
val uuid: UUID get() = model.uuid
7349

74-
override fun render(holder: BindingViewHolder, subject: Subject<UiEvent>) {
75-
val context = holder.itemView.context
76-
val binding = holder.binding as RecentPatientItemViewBinding
50+
override fun layoutResId(): Int = org.simple.clinic.R.layout.recent_patient_item_view
7751

78-
holder.itemView.setOnClickListener {
52+
override fun render(holder: BindingViewHolder, subject: Subject<UiEvent>) {
53+
RecentPatientViewBinder.bind(holder, model) {
7954
subject.onNext(RecentPatientItemClicked(patientUuid = uuid))
8055
}
81-
82-
val statusText: String? = when {
83-
isSuspectedForHypertension && isSuspectedForDiabetes ->
84-
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension_and_diabetes)
85-
86-
isSuspectedForHypertension ->
87-
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension)
88-
89-
isSuspectedForDiabetes ->
90-
context.getString(R.string.recent_patients_itemview_suspected_for_diabetes)
91-
92-
isNewRegistration ->
93-
context.getString(R.string.recent_patients_itemview_new_registration)
94-
95-
else -> null
96-
}
97-
98-
binding.patientStatusTextView.visibleOrGone(statusText != null)
99-
binding.patientStatusTextView.text = statusText
100-
101-
binding.patientNameTextView.text = context.resources.getString(R.string.patients_recentpatients_nameage, name, age.toString())
102-
binding.genderImageView.setImageResource(gender.displayIconRes)
103-
binding.lastSeenTextView.text = dateFormatter.format(updatedAt.toLocalDateAtZone(clock.zone))
10456
}
10557
}
10658

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package org.simple.clinic.recentpatient
2+
3+
import org.simple.clinic.R
4+
import org.simple.clinic.databinding.RecentPatientItemViewBinding
5+
import org.simple.clinic.medicalhistory.Answer.Suspected
6+
import org.simple.clinic.patient.Gender
7+
import org.simple.clinic.patient.RecentPatient
8+
import org.simple.clinic.patient.displayIconRes
9+
import org.simple.clinic.util.UserClock
10+
import org.simple.clinic.util.toLocalDateAtZone
11+
import org.simple.clinic.widgets.recyclerview.BindingViewHolder
12+
import org.simple.clinic.widgets.visibleOrGone
13+
import java.time.Instant
14+
import java.time.LocalDate
15+
import java.time.format.DateTimeFormatter
16+
import java.util.UUID
17+
18+
/**
19+
* Shared UI model used by both paged and non-paged adapters.
20+
*/
21+
data class RecentPatientUiModel(
22+
val uuid: UUID,
23+
val name: String,
24+
val age: Int,
25+
val gender: Gender,
26+
val updatedAt: Instant,
27+
val dateFormatter: DateTimeFormatter,
28+
val clock: UserClock,
29+
val isNewRegistration: Boolean,
30+
val isEligibleForReassignment: Boolean = false,
31+
val isSuspectedForHypertension: Boolean = false,
32+
val isSuspectedForDiabetes: Boolean = false
33+
) {
34+
companion object {
35+
fun fromDomain(
36+
recentPatient: RecentPatient,
37+
today: LocalDate,
38+
userClock: UserClock,
39+
dateFormatter: DateTimeFormatter,
40+
isEligibleForReassignment: Boolean = false
41+
): RecentPatientUiModel {
42+
val patientRegisteredOnDate = recentPatient.patientRecordedAt.toLocalDateAtZone(userClock.zone)
43+
val isNewRegistration = today == patientRegisteredOnDate
44+
45+
return RecentPatientUiModel(
46+
uuid = recentPatient.uuid,
47+
name = recentPatient.fullName,
48+
age = recentPatient.ageDetails.estimateAge(userClock),
49+
gender = recentPatient.gender,
50+
updatedAt = recentPatient.updatedAt,
51+
dateFormatter = dateFormatter,
52+
clock = userClock,
53+
isNewRegistration = isNewRegistration,
54+
isEligibleForReassignment = isEligibleForReassignment,
55+
isSuspectedForHypertension = recentPatient.diagnosedWithHypertension == Suspected,
56+
isSuspectedForDiabetes = recentPatient.diagnosedWithDiabetes == Suspected
57+
)
58+
}
59+
}
60+
}
61+
62+
object RecentPatientViewBinder {
63+
64+
fun bind(
65+
holder: BindingViewHolder,
66+
model: RecentPatientUiModel,
67+
onClick: (UUID) -> Unit
68+
) {
69+
val context = holder.itemView.context
70+
val binding = holder.binding as RecentPatientItemViewBinding
71+
72+
holder.itemView.setOnClickListener {
73+
onClick(model.uuid)
74+
}
75+
76+
val statusText: String? = when {
77+
model.isSuspectedForHypertension && model.isSuspectedForDiabetes ->
78+
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension_and_diabetes)
79+
80+
model.isSuspectedForHypertension ->
81+
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension)
82+
83+
model.isSuspectedForDiabetes ->
84+
context.getString(R.string.recent_patients_itemview_suspected_for_diabetes)
85+
86+
model.isNewRegistration ->
87+
context.getString(R.string.recent_patients_itemview_new_registration)
88+
89+
else -> null
90+
}
91+
92+
binding.patientStatusTextView.visibleOrGone(statusText != null)
93+
binding.patientStatusTextView.text = statusText
94+
binding.facilityReassignmentView.root.visibleOrGone(model.isEligibleForReassignment)
95+
96+
binding.patientNameTextView.text =
97+
context.resources.getString(R.string.patients_recentpatients_nameage, model.name, model.age.toString())
98+
99+
binding.genderImageView.setImageResource(model.gender.displayIconRes)
100+
binding.lastSeenTextView.text = model.dateFormatter.format(model.updatedAt.toLocalDateAtZone(model.clock.zone))
101+
}
102+
}

app/src/main/java/org/simple/clinic/recentpatientsview/RecentPatientItem.kt

Lines changed: 14 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,20 @@ package org.simple.clinic.recentpatientsview
33
import androidx.recyclerview.widget.DiffUtil
44
import io.reactivex.subjects.Subject
55
import org.simple.clinic.R
6-
import org.simple.clinic.databinding.RecentPatientItemViewBinding
76
import org.simple.clinic.databinding.SeeAllItemViewBinding
8-
import org.simple.clinic.medicalhistory.Answer.Suspected
97
import org.simple.clinic.patient.Answer
10-
import org.simple.clinic.patient.Gender
118
import org.simple.clinic.patient.RecentPatient
12-
import org.simple.clinic.patient.displayIconRes
9+
import org.simple.clinic.recentpatient.RecentPatientUiModel
10+
import org.simple.clinic.recentpatient.RecentPatientViewBinder
1311
import org.simple.clinic.util.UserClock
14-
import org.simple.clinic.util.toLocalDateAtZone
1512
import org.simple.clinic.widgets.ItemAdapter
1613
import org.simple.clinic.widgets.UiEvent
1714
import org.simple.clinic.widgets.recyclerview.BindingViewHolder
18-
import org.simple.clinic.widgets.visibleOrGone
19-
import java.time.Instant
2015
import java.time.LocalDate
2116
import java.time.format.DateTimeFormatter
2217
import java.util.UUID
2318

19+
2420
sealed class RecentPatientItemType : ItemAdapter.Item<UiEvent> {
2521

2622
companion object {
@@ -51,73 +47,32 @@ sealed class RecentPatientItemType : ItemAdapter.Item<UiEvent> {
5147
dateFormatter: DateTimeFormatter,
5248
isPatientReassignmentFeatureEnabled: Boolean,
5349
): RecentPatientItem {
54-
val patientRegisteredOnDate = recentPatient.patientRecordedAt.toLocalDateAtZone(userClock.zone)
55-
val isNewRegistration = today == patientRegisteredOnDate
56-
57-
return RecentPatientItem(
58-
uuid = recentPatient.uuid,
59-
name = recentPatient.fullName,
60-
age = recentPatient.ageDetails.estimateAge(userClock),
61-
gender = recentPatient.gender,
62-
updatedAt = recentPatient.updatedAt,
50+
val model = RecentPatientUiModel.fromDomain(
51+
recentPatient = recentPatient,
52+
today = today,
53+
userClock = userClock,
6354
dateFormatter = dateFormatter,
64-
clock = userClock,
65-
isNewRegistration = isNewRegistration,
6655
isEligibleForReassignment = isPatientReassignmentFeatureEnabled &&
67-
recentPatient.eligibleForReassignment == Answer.Yes,
68-
isSuspectedForHypertension = recentPatient.diagnosedWithHypertension == Suspected,
69-
isSuspectedForDiabetes = recentPatient.diagnosedWithDiabetes == Suspected
56+
recentPatient.eligibleForReassignment == Answer.Yes
7057
)
58+
59+
return RecentPatientItem(model)
7160
}
7261
}
7362
}
7463

7564
data class RecentPatientItem(
76-
val uuid: UUID,
77-
val name: String,
78-
val age: Int,
79-
val gender: Gender,
80-
val updatedAt: Instant,
81-
val dateFormatter: DateTimeFormatter,
82-
val clock: UserClock,
83-
val isNewRegistration: Boolean,
84-
val isEligibleForReassignment: Boolean,
85-
val isSuspectedForHypertension: Boolean,
86-
val isSuspectedForDiabetes: Boolean,
65+
private val model: RecentPatientUiModel
8766
) : RecentPatientItemType() {
8867

68+
val uuid: UUID get() = model.uuid
69+
8970
override fun layoutResId(): Int = R.layout.recent_patient_item_view
9071

9172
override fun render(holder: BindingViewHolder, subject: Subject<UiEvent>) {
92-
val context = holder.itemView.context
93-
val binding = holder.binding as RecentPatientItemViewBinding
94-
95-
holder.itemView.setOnClickListener {
73+
RecentPatientViewBinder.bind(holder, model) {
9674
subject.onNext(RecentPatientItemClicked(patientUuid = uuid))
9775
}
98-
99-
val statusText: String? = when {
100-
isSuspectedForHypertension && isSuspectedForDiabetes ->
101-
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension_and_diabetes)
102-
103-
isSuspectedForHypertension ->
104-
context.getString(R.string.recent_patients_itemview_suspected_for_hypertension)
105-
106-
isSuspectedForDiabetes ->
107-
context.getString(R.string.recent_patients_itemview_suspected_for_diabetes)
108-
109-
isNewRegistration ->
110-
context.getString(R.string.recent_patients_itemview_new_registration)
111-
112-
else -> null
113-
}
114-
115-
binding.patientStatusTextView.visibleOrGone(statusText != null)
116-
binding.patientStatusTextView.text = statusText
117-
binding.facilityReassignmentView.root.visibleOrGone(isEligibleForReassignment)
118-
binding.patientNameTextView.text = context.resources.getString(R.string.patients_recentpatients_nameage, name, age.toString())
119-
binding.genderImageView.setImageResource(gender.displayIconRes)
120-
binding.lastSeenTextView.text = dateFormatter.format(updatedAt.toLocalDateAtZone(clock.zone))
12176
}
12277
}
12378

0 commit comments

Comments
 (0)