Skip to content

Commit

Permalink
Merge branch 'main' into feature/74-bottom-sheets-and-record-operations
Browse files Browse the repository at this point in the history
  • Loading branch information
eldcn committed Aug 25, 2024
2 parents 22a5cd3 + efb0f7c commit 8f9bfee
Show file tree
Hide file tree
Showing 25 changed files with 800 additions and 43 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ dependencies {

implementation(libs.androidx.core.i18n)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.fragment.compose)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.lifecycle.view.model.ktx)
implementation(libs.androidx.splashscreen)
Expand Down
18 changes: 16 additions & 2 deletions app/src/main/kotlin/edu/stanford/bdh/engagehf/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package edu.stanford.bdh.engagehf

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Box
Expand All @@ -14,6 +13,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
Expand All @@ -26,6 +26,7 @@ import edu.stanford.bdh.engagehf.navigation.RegisterParams
import edu.stanford.bdh.engagehf.navigation.Routes
import edu.stanford.bdh.engagehf.navigation.screens.AppScreen
import edu.stanford.bdh.engagehf.navigation.serializableType
import edu.stanford.bdh.engagehf.questionnaire.QuestionnaireScreen
import edu.stanford.spezi.core.coroutines.di.Dispatching
import edu.stanford.spezi.core.design.theme.Sizes
import edu.stanford.spezi.core.design.theme.SpeziTheme
Expand All @@ -48,7 +49,7 @@ import javax.inject.Inject
import kotlin.reflect.typeOf

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
class MainActivity : FragmentActivity() {

private val viewModel by viewModels<MainActivityViewModel>()

Expand All @@ -74,6 +75,7 @@ class MainActivity : ComponentActivity() {
navHostController = navHostController,
startDestination = uiState.startDestination
)
setTheme(R.style.Theme_Spezi_Content)
}
}
}
Expand Down Expand Up @@ -134,6 +136,14 @@ class MainActivity : ComponentActivity() {
AppScreen()
}

composable<Routes.QuestionnaireScreen>(
typeMap = mapOf(
typeOf<String>() to serializableType<String>()
)
) {
QuestionnaireScreen()
}

composable<Routes.InvitationCodeScreen> {
InvitationCodeScreen()
}
Expand Down Expand Up @@ -167,6 +177,10 @@ class MainActivity : ComponentActivity() {
)
)

is AppNavigationEvent.QuestionnaireScreen -> navHostController.navigate(
Routes.QuestionnaireScreen(event.questionnaireId)
)

is AccountNavigationEvent.LoginScreen -> navHostController.navigate(
Routes.LoginScreen(
isAlreadyRegistered = event.isAlreadyRegistered
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import edu.stanford.bdh.engagehf.bluetooth.measurements.MeasurementsRepository
import edu.stanford.bdh.engagehf.education.EngageEducationRepository
import edu.stanford.bdh.engagehf.messages.MessageRepository
import edu.stanford.bdh.engagehf.messages.MessagesAction
import edu.stanford.bdh.engagehf.navigation.AppNavigationEvent
import edu.stanford.spezi.core.bluetooth.api.BLEService
import edu.stanford.spezi.core.bluetooth.data.model.BLEServiceEvent
import edu.stanford.spezi.core.bluetooth.data.model.BLEServiceState
Expand Down Expand Up @@ -162,7 +163,12 @@ class BluetoothViewModel @Inject internal constructor(
is MessagesAction.MedicationsAction -> { /* TODO */
}

is MessagesAction.QuestionnaireAction -> { /* TODO */
is MessagesAction.QuestionnaireAction -> {
navigator.navigateTo(
AppNavigationEvent.QuestionnaireScreen(
mappedAction.questionnaireId
)
)
}

is MessagesAction.VideoSectionAction -> {
Expand All @@ -182,9 +188,6 @@ class BluetoothViewModel @Inject internal constructor(
}
val messageId = action.message.id
messageRepository.completeMessage(messageId = messageId)
_uiState.update {
it.copy(messages = it.messages.filter { message -> message.id != messageId })
}
} else {
logger.e { "Error while mapping action: ${mappingResult.exceptionOrNull()}" }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package edu.stanford.bdh.engagehf.bluetooth.data.mapper

import edu.stanford.bdh.engagehf.messages.MessagesAction
import edu.stanford.bdh.engagehf.messages.Questionnaire
import edu.stanford.bdh.engagehf.messages.VideoSectionVideo
import javax.inject.Inject

Expand All @@ -24,7 +23,7 @@ class MessageActionMapper @Inject constructor() {
questionnaireRegex.matches(action) -> {
val matchResult = questionnaireRegex.find(action)
val (questionnaireId) = matchResult!!.destructured
MessagesAction.QuestionnaireAction(Questionnaire(questionnaireId))
MessagesAction.QuestionnaireAction(questionnaireId)
}

action == "/healthSummary" -> MessagesAction.HealthSummaryAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ fun MedicationCard(
Row(verticalAlignment = Alignment.CenterVertically) {
MedicationStatusIcon(model = model)
Spacer(modifier = Modifier.width(Spacings.small))
Column {
Column(modifier = Modifier.weight(1f)) {
Text(
text = model.title,
style = TextStyles.titleLarge,
overflow = TextOverflow.Clip,
modifier = Modifier.testIdentifier(
identifier = MedicationScreenTestIdentifier.SUCCESS_MEDICATION_CARD_TITLE,
suffix = model.id
Expand All @@ -84,13 +85,13 @@ fun MedicationCard(
Text(
text = model.subtitle,
style = TextStyles.titleSmall,
overflow = TextOverflow.Clip,
modifier = Modifier.testIdentifier(
identifier = MedicationScreenTestIdentifier.SUCCESS_MEDICATION_CARD_SUBTITLE,
suffix = model.id,
)
)
}
Spacer(modifier = Modifier.weight(1f))
IconButton(onClick = {
onAction(
MedicationViewModel.Action.ToggleExpand(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ sealed class MessagesAction {
data class VideoSectionAction(val videoSectionVideo: VideoSectionVideo) : MessagesAction()
data object MedicationsAction : MessagesAction()
data object MeasurementsAction : MessagesAction()
data class QuestionnaireAction(val questionnaire: Questionnaire) : MessagesAction()
data class QuestionnaireAction(val questionnaireId: String) : MessagesAction()
data object HealthSummaryAction : MessagesAction()
}

data class VideoSectionVideo(val videoSectionId: String, val videoId: String)
data class Questionnaire(val questionnaireId: String)
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import edu.stanford.spezi.core.navigation.NavigationEvent

sealed interface AppNavigationEvent : NavigationEvent {
data object AppScreen : AppNavigationEvent
data class QuestionnaireScreen(val questionnaireId: String) : AppNavigationEvent
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ sealed class Routes {
@Serializable
data object AppScreen : Routes()

@Serializable
data class QuestionnaireScreen(val questionnaireId: @Serializable String) : Routes()

@Serializable
data object SequentialOnboardingScreen : Routes()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ enum class ObservationCollection(val collectionName: String, val loinc: Loinc) {
HEART_RATE(collectionName = "heartRateObservations", loinc = Loinc.HEART_RATE),
BODY_WEIGHT(collectionName = "bodyWeightObservations", loinc = Loinc.WEIGHT),
BLOOD_PRESSURE(collectionName = "bloodPressureObservations", loinc = Loinc.BLOOD_PRESSURE),
QUESTIONNAIRE(collectionName = "questionnaireResponses", loinc = Loinc.QUESTIONNAIRE),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package edu.stanford.bdh.engagehf.questionnaire

import com.google.firebase.firestore.FirebaseFirestore
import edu.stanford.bdh.engagehf.observations.ObservationCollection
import edu.stanford.bdh.engagehf.observations.ObservationCollectionProvider
import edu.stanford.healthconnectonfhir.QuestionnaireDocumentMapper
import edu.stanford.spezi.core.coroutines.di.Dispatching
import edu.stanford.spezi.core.logging.speziLogger
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import org.hl7.fhir.r4.model.Questionnaire
import org.hl7.fhir.r4.model.QuestionnaireResponse
import javax.inject.Inject

class QuestionnaireRepository @Inject constructor(
@Dispatching.IO private val ioDispatcher: CoroutineDispatcher,
private val questionnaireDocumentMapper: QuestionnaireDocumentMapper,
private val observationCollectionProvider: ObservationCollectionProvider,
private val firestore: FirebaseFirestore,
) {
private val logger by speziLogger()

suspend fun getQuestionnaire(id: String): Result<Questionnaire> {
return withContext(ioDispatcher) {
runCatching {
val document = firestore.collection(QUESTIONNAIRE_COLLECTION)
.document(id)
.get()
.await()
questionnaireDocumentMapper.map(document)
}.onFailure { exception ->
logger.e(exception) { "Error fetching questionnaire" }
}
}
}

suspend fun save(questionnaireResponse: QuestionnaireResponse): Result<Unit> {
return withContext(ioDispatcher) {
runCatching {
val document = questionnaireDocumentMapper.map(questionnaireResponse)
observationCollectionProvider.getCollection(ObservationCollection.QUESTIONNAIRE)
.add(document).await().let { }
}
}
}

companion object {
private const val QUESTIONNAIRE_COLLECTION = "questionnaires"
}
}
Loading

0 comments on commit 8f9bfee

Please sign in to comment.