Skip to content

Commit d30a856

Browse files
siddh1004sagarwal
andauthored
Migrate clinical decision support alert to Jetpack Compose (#5461)
https://app.shortcut.com/simpledotorg/story/15921/migrate-cdss-alert-container-to-jetpack-compose --------- Co-authored-by: sagarwal <[email protected]>
1 parent d8e1ff8 commit d30a856

File tree

7 files changed

+105
-144
lines changed

7 files changed

+105
-144
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Migrate assigned facility view to Jetpack Compose
1818
- Migrate next appointment view to Jetpack Compose
1919
- Migrate patient status view to Jetpack Compose
20+
- Migrate clinical decision support alert to Jetpack Compose
2021

2122
## 2025.05.20
2223

app/src/main/java/org/simple/clinic/summary/PatientSummaryScreen.kt

Lines changed: 19 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ import androidx.compose.ui.res.dimensionResource
2020
import androidx.compose.ui.res.painterResource
2121
import androidx.compose.ui.res.stringResource
2222
import androidx.compose.ui.unit.dp
23-
import androidx.dynamicanimation.animation.DynamicAnimation
24-
import androidx.transition.AutoTransition
25-
import androidx.transition.Transition
26-
import androidx.transition.TransitionManager
2723
import com.google.android.material.dialog.MaterialAlertDialogBuilder
2824
import com.jakewharton.rxbinding3.view.clicks
2925
import com.spotify.mobius.Init
@@ -67,6 +63,7 @@ import org.simple.clinic.scheduleappointment.ScheduleAppointmentSheet
6763
import org.simple.clinic.scheduleappointment.facilityselection.FacilitySelectionScreen
6864
import org.simple.clinic.summary.addcholesterol.CholesterolEntrySheet
6965
import org.simple.clinic.summary.addphone.AddPhoneNumberDialog
66+
import org.simple.clinic.summary.clinicaldecisionsupport.ui.ClinicalDecisionHighBpAlert
7067
import org.simple.clinic.summary.compose.StatinNudge
7168
import org.simple.clinic.summary.linkId.LinkIdWithPatientSheet.LinkIdWithPatientSheetKey
7269
import org.simple.clinic.summary.teleconsultation.contactdoctor.ContactDoctorSheet
@@ -83,7 +80,6 @@ import org.simple.clinic.widgets.UiEvent
8380
import org.simple.clinic.widgets.compose.PatientStatusView
8481
import org.simple.clinic.widgets.hideKeyboard
8582
import org.simple.clinic.widgets.scrollToChild
86-
import org.simple.clinic.widgets.spring
8783
import java.time.format.DateTimeFormatter
8884
import java.util.UUID
8985
import java.util.concurrent.TimeUnit
@@ -154,9 +150,6 @@ class PatientSummaryScreen :
154150
private val nextAppointmentFacilityView
155151
get() = binding.nextAppointmentFacilityView
156152

157-
private val clinicalDecisionSupportAlertView
158-
get() = binding.clinicalDecisionSupportBpHighAlert.rootView
159-
160153
private val composeView
161154
get() = binding.composeView
162155

@@ -200,6 +193,9 @@ class PatientSummaryScreen :
200193

201194
private var showPatientDiedStatusView by mutableStateOf(false)
202195

196+
private var showClinicalDecisionAlert by mutableStateOf(false)
197+
private var animateClinicalDecisionSupportAlert by mutableStateOf(false)
198+
203199
override fun defaultModel(): PatientSummaryModel {
204200
return PatientSummaryModel.from(screenKey.intention, screenKey.patientUuid)
205201
}
@@ -302,6 +298,16 @@ class PatientSummaryScreen :
302298
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
303299
setContent {
304300
SimpleTheme {
301+
ClinicalDecisionHighBpAlert(
302+
showAlert = showClinicalDecisionAlert,
303+
animateExit = animateClinicalDecisionSupportAlert,
304+
modifier = Modifier.padding(
305+
start = dimensionResource(R.dimen.spacing_8),
306+
end = dimensionResource(R.dimen.spacing_8),
307+
top = dimensionResource(R.dimen.spacing_8),
308+
),
309+
)
310+
305311
StatinNudge(
306312
statinInfo = statinInfo,
307313
modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 8.dp),
@@ -743,82 +749,23 @@ class PatientSummaryScreen :
743749
}
744750

745751
override fun showClinicalDecisionSupportAlert() {
746-
showWithAnimation(clinicalDecisionSupportAlertView)
752+
showClinicalDecisionAlert = true
747753
}
748754

749755
override fun hideClinicalDecisionSupportAlert() {
750-
hideWithAnimation(clinicalDecisionSupportAlertView, R.id.tag_clinical_decision_pending_end_listener)
756+
showClinicalDecisionAlert = false
757+
animateClinicalDecisionSupportAlert = true
751758
}
752759

753760
override fun hideClinicalDecisionSupportAlertWithoutAnimation() {
754-
clinicalDecisionSupportAlertView.visibility = GONE
761+
showClinicalDecisionAlert = false
762+
animateClinicalDecisionSupportAlert = false
755763
}
756764

757765
override fun updateStatinAlert(statinInfo: StatinInfo) {
758766
this.statinInfo = statinInfo
759767
}
760768

761-
private fun showWithAnimation(view: View) {
762-
view.translationY = view.height.unaryMinus().toFloat()
763-
764-
val spring = view.spring(DynamicAnimation.TRANSLATION_Y)
765-
766-
val transition = AutoTransition().apply {
767-
excludeChildren(view, true)
768-
// We are doing this to wait for the router transitions to be done before we start this.
769-
startDelay = 500
770-
}
771-
val transitionListener = object : Transition.TransitionListener {
772-
override fun onTransitionStart(transition: Transition) {
773-
}
774-
775-
override fun onTransitionEnd(transition: Transition) {
776-
transition.removeListener(this)
777-
spring.animateToFinalPosition(0f)
778-
}
779-
780-
override fun onTransitionCancel(transition: Transition) {
781-
}
782-
783-
override fun onTransitionPause(transition: Transition) {
784-
}
785-
786-
override fun onTransitionResume(transition: Transition) {
787-
}
788-
}
789-
transition.addListener(transitionListener)
790-
TransitionManager.beginDelayedTransition(summaryViewsContainer, transition)
791-
792-
view.visibility = VISIBLE
793-
}
794-
795-
private fun hideWithAnimation(view: View, tag: Int) {
796-
if (view.visibility != VISIBLE) return
797-
798-
val spring = view.spring(DynamicAnimation.TRANSLATION_Y)
799-
(view.getTag(tag) as?
800-
DynamicAnimation.OnAnimationEndListener)?.let {
801-
spring.removeEndListener(it)
802-
}
803-
804-
val listener = object : DynamicAnimation.OnAnimationEndListener {
805-
override fun onAnimationEnd(animation: DynamicAnimation<*>?, canceled: Boolean, value: Float, velocity: Float) {
806-
spring.removeEndListener(this)
807-
view.visibility = GONE
808-
}
809-
}
810-
spring.addEndListener(listener)
811-
view.setTag(tag, listener)
812-
813-
val transition = AutoTransition().apply {
814-
excludeChildren(view, true)
815-
}
816-
TransitionManager.beginDelayedTransition(summaryViewsContainer, transition)
817-
818-
spring.animateToFinalPosition(view.height.unaryMinus().toFloat())
819-
}
820-
821-
822769
override fun showReassignPatientWarningSheet(
823770
patientUuid: UUID,
824771
currentFacility: Facility,
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package org.simple.clinic.summary.clinicaldecisionsupport.ui
2+
3+
import androidx.compose.animation.AnimatedVisibility
4+
import androidx.compose.animation.ExitTransition
5+
import androidx.compose.animation.core.tween
6+
import androidx.compose.animation.expandVertically
7+
import androidx.compose.animation.shrinkVertically
8+
import androidx.compose.foundation.BorderStroke
9+
import androidx.compose.foundation.Image
10+
import androidx.compose.foundation.layout.Arrangement
11+
import androidx.compose.foundation.layout.Column
12+
import androidx.compose.foundation.layout.Row
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.material.Card
15+
import androidx.compose.material.MaterialTheme
16+
import androidx.compose.material.Text
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.ui.Alignment
19+
import androidx.compose.ui.Modifier
20+
import androidx.compose.ui.res.colorResource
21+
import androidx.compose.ui.res.dimensionResource
22+
import androidx.compose.ui.res.painterResource
23+
import androidx.compose.ui.res.stringResource
24+
import androidx.compose.ui.tooling.preview.Preview
25+
import org.simple.clinic.R
26+
import org.simple.clinic.common.ui.theme.SimpleTheme
27+
28+
@Composable
29+
fun ClinicalDecisionHighBpAlert(
30+
showAlert: Boolean,
31+
animateExit: Boolean,
32+
modifier: Modifier = Modifier
33+
) {
34+
AnimatedVisibility(
35+
visible = showAlert,
36+
enter = expandVertically(
37+
animationSpec = tween(500),
38+
expandFrom = Alignment.Top
39+
),
40+
exit = if (animateExit) shrinkVertically(animationSpec = tween(500)) else ExitTransition.None
41+
) {
42+
Card(
43+
modifier = modifier,
44+
elevation = dimensionResource(R.dimen.spacing_0),
45+
backgroundColor = colorResource(R.color.simple_red_100_alpha_50),
46+
border = BorderStroke(
47+
width = dimensionResource(id = R.dimen.spacing_1),
48+
color = colorResource(id = R.color.simple_red_600)
49+
),
50+
51+
) {
52+
Row(
53+
modifier = Modifier.padding(dimensionResource(id = R.dimen.spacing_8)),
54+
verticalAlignment = Alignment.CenterVertically,
55+
horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_8))
56+
) {
57+
Image(
58+
painter = painterResource(id = R.drawable.ic_clinical_decision_warning),
59+
contentDescription = null,
60+
)
61+
Column {
62+
Text(
63+
text = stringResource(id = R.string.clinical_decision_support_alert_bp_high_title),
64+
style = SimpleTheme.typography.subtitle1Medium,
65+
color = colorResource(id = R.color.simple_red_600)
66+
)
67+
Text(
68+
modifier = Modifier.padding(top = dimensionResource(R.dimen.spacing_2)),
69+
text = stringResource(id = R.string.clinical_decision_support_alert_bp_high_subtitle),
70+
style = MaterialTheme.typography.body1,
71+
color = colorResource(id = R.color.simple_red_600_alpha_80)
72+
)
73+
}
74+
}
75+
}
76+
}
77+
}
78+
79+
@Preview(showBackground = true)
80+
@Composable
81+
private fun ClinicalDecisionHighBpAlertPreview() {
82+
SimpleTheme {
83+
ClinicalDecisionHighBpAlert(showAlert = true, animateExit = false)
84+
}
85+
}

app/src/main/res/drawable/background_clinical_decision_alert.xml

Lines changed: 0 additions & 12 deletions
This file was deleted.

app/src/main/res/layout/screen_patient_summary.xml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@
4343
android:clipToPadding="false"
4444
android:orientation="vertical">
4545

46-
<include
47-
android:id="@+id/clinicalDecisionSupportBpHighAlert"
48-
layout="@layout/view_clinical_decision_support_bp_high" />
49-
5046
<androidx.compose.ui.platform.ComposeView
5147
android:id="@+id/compose_view"
5248
android:layout_width="match_parent"

app/src/main/res/layout/view_clinical_decision_support_bp_high.xml

Lines changed: 0 additions & 55 deletions
This file was deleted.

app/src/main/res/values/ids.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,4 @@
1414
<item name="spring_animation_alpha" type="id" />
1515
<item name="spring_animation_scrollx" type="id" />
1616
<item name="spring_animation_scrollY" type="id" />
17-
<item name="tag_clinical_decision_pending_end_listener" type="id" />
1817
</resources>

0 commit comments

Comments
 (0)