diff --git a/app/src/main/java/com/android/periodpals/ui/components/AlertComponents.kt b/app/src/main/java/com/android/periodpals/ui/components/AlertComponents.kt index a258629d..3d438983 100644 --- a/app/src/main/java/com/android/periodpals/ui/components/AlertComponents.kt +++ b/app/src/main/java/com/android/periodpals/ui/components/AlertComponents.kt @@ -614,7 +614,6 @@ fun formatAlertTime(createdAt: String?): String { * Capitalizes the first letter of the string. * * @param s String whose first letter will be capitilized. - * * @return Capitalized string. */ fun capitalized(s: String): String = s.lowercase().replaceFirstChar { it.uppercase() } @@ -626,7 +625,7 @@ fun capitalized(s: String): String = s.lowercase().replaceFirstChar { it.upperca * @return Trimmed text. */ fun trimLocationText(locationText: String): String { - if (locationText.length >= LOCATION_TEXT_LEN_LIMIT) return locationText.take( - LOCATION_TEXT_LEN_LIMIT) + "..." + if (locationText.length >= LOCATION_TEXT_LEN_LIMIT) + return locationText.take(LOCATION_TEXT_LEN_LIMIT) + "..." return locationText -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/periodpals/ui/components/MapComponents.kt b/app/src/main/java/com/android/periodpals/ui/components/MapComponents.kt index 47978697..002cffbd 100644 --- a/app/src/main/java/com/android/periodpals/ui/components/MapComponents.kt +++ b/app/src/main/java/com/android/periodpals/ui/components/MapComponents.kt @@ -45,7 +45,6 @@ import com.android.periodpals.resources.C.Tag.MapScreen.PROFILE_NAME import com.android.periodpals.resources.C.Tag.MapScreen.PROFILE_PICTURE import com.android.periodpals.resources.C.Tag.MapScreen.RESOLVE_ALERT_BUTTON import com.android.periodpals.resources.ComponentColor.getFilledPrimaryContainerButtonColors -import com.android.periodpals.ui.navigation.Screen import com.android.periodpals.ui.theme.dimens private const val EDIT_BUTTON_TEXT = "Edit" @@ -73,18 +72,18 @@ enum class CONTENT { * @param alertToDisplay Alert to be displayed in the bottom sheet * @param onEditClick Callback run when the edit button is pressed * @param onAcceptClick Callback run when the accept button is pressed - * @param onResolveClick Callback run when the resolve button is pressed + * @param onResolveClick Callback run when the resolve button is pressed */ @OptIn(ExperimentalMaterial3Api::class) @Composable fun MapBottomSheet( - sheetState: SheetState, - content: CONTENT, - onSheetDismissRequest: () -> Unit, - alertToDisplay: Alert?, - onEditClick: () -> Unit, - onAcceptClick: () -> Unit, - onResolveClick: () -> Unit + sheetState: SheetState, + content: CONTENT, + onSheetDismissRequest: () -> Unit, + alertToDisplay: Alert?, + onEditClick: () -> Unit, + onAcceptClick: () -> Unit, + onResolveClick: () -> Unit ) { ModalBottomSheet( @@ -93,20 +92,18 @@ fun MapBottomSheet( modifier = Modifier.fillMaxWidth().wrapContentHeight().testTag(BOTTOM_SHEET), ) { Column( - verticalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small2, Alignment.CenterVertically), - modifier = - Modifier.padding(MaterialTheme.dimens.small3), + verticalArrangement = + Arrangement.spacedBy(MaterialTheme.dimens.small2, Alignment.CenterVertically), + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(MaterialTheme.dimens.small3), ) { - alertToDisplay?.let { - AlertInfo(it) - } ?: Log.d(TAG, "Alert is null") + alertToDisplay?.let { AlertInfo(it) } ?: Log.d(TAG, "Alert is null") InteractionButtons( - content = content, - onEditClick = onEditClick, - onAccpetClick = { TODO("TO be implemented") }, - onResolveClick = { TODO("To be implemented") } - ) + content = content, + onEditClick = onEditClick, + onAccpetClick = { TODO("TO be implemented") }, + onResolveClick = { TODO("To be implemented") }) } } } @@ -118,78 +115,80 @@ fun MapBottomSheet( */ @Composable private fun AlertInfo(alert: Alert) { - Column { - Row( - horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small3), - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.fillMaxWidth()) { + Column( + verticalArrangement = + Arrangement.spacedBy(MaterialTheme.dimens.small2, Alignment.CenterVertically)) { + Row( + horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small3), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth()) { - // Profile picture - Icon( - imageVector = Icons.Outlined.AccountCircle, // TODO fetch from database - contentDescription = "Profile picture", - modifier = - Modifier.size(MaterialTheme.dimens.iconSize) - .wrapContentSize() - .testTag(PROFILE_PICTURE), - ) + // Profile picture + Icon( + imageVector = Icons.Outlined.AccountCircle, // TODO fetch from database + contentDescription = "Profile picture", + modifier = + Modifier.size(MaterialTheme.dimens.iconSize) + .wrapContentSize() + .testTag(PROFILE_PICTURE), + ) - Column(verticalArrangement = Arrangement.Center) { + Column(verticalArrangement = Arrangement.Center) { - // Name - Text( - text = alert.name, - style = MaterialTheme.typography.bodyLarge, - textAlign = TextAlign.Left, - modifier = Modifier.testTag(PROFILE_NAME), - ) + // Name + Text( + text = alert.name, + style = MaterialTheme.typography.bodyLarge, + textAlign = TextAlign.Left, + modifier = Modifier.testTag(PROFILE_NAME), + ) - Row(horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small1)) { - val locationText = trimLocationText(Location.fromString(alert.location).name) + Row(horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small1)) { + val locationText = trimLocationText(Location.fromString(alert.location).name) - // Location - Text( - text = locationText, - style = MaterialTheme.typography.bodySmall, - textAlign = TextAlign.Left, - modifier = Modifier.testTag(ALERT_LOCATION_TEXT), - ) + // Location + Text( + text = locationText, + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Left, + modifier = Modifier.testTag(ALERT_LOCATION_TEXT), + ) - // Time - Text( - text = formatAlertTime(alert.createdAt), - style = MaterialTheme.typography.bodySmall, - textAlign = TextAlign.Left, - modifier = Modifier.testTag(ALERT_TIME_TEXT), - ) - } - } + // Time + Text( + text = formatAlertTime(alert.createdAt), + style = MaterialTheme.typography.bodyMedium, + textAlign = TextAlign.Left, + modifier = Modifier.testTag(ALERT_TIME_TEXT), + ) + } + } - val periodPalsProduct = productToPeriodPalsIcon(alert.product) - val periodPalsUrgency = urgencyToPeriodPalsIcon(alert.urgency) + val periodPalsProduct = productToPeriodPalsIcon(alert.product) + val periodPalsUrgency = urgencyToPeriodPalsIcon(alert.urgency) - // Product type - Icon( - painter = painterResource(periodPalsProduct.icon), - contentDescription = periodPalsProduct.textId + " product", - modifier = Modifier.testTag(ALERT_PRODUCT_ICON), - ) + // Product type + Icon( + painter = painterResource(periodPalsProduct.icon), + contentDescription = periodPalsProduct.textId + " product", + modifier = Modifier.testTag(ALERT_PRODUCT_ICON), + ) - // Urgency level - Icon( - painter = painterResource(periodPalsUrgency.icon), - contentDescription = periodPalsUrgency.textId + " urgency", - modifier = Modifier.testTag(ALERT_URGENCY_ICON), + // Urgency level + Icon( + painter = painterResource(periodPalsUrgency.icon), + contentDescription = periodPalsUrgency.textId + " urgency", + modifier = Modifier.testTag(ALERT_URGENCY_ICON), + ) + } + OutlinedCard { + Text( + text = alert.message, + modifier = Modifier.padding(MaterialTheme.dimens.small2).testTag(ALERT_MESSAGE), + style = MaterialTheme.typography.bodyMedium, ) } - OutlinedCard { - Text( - text = alert.message, - modifier = Modifier.padding(MaterialTheme.dimens.small2).testTag(ALERT_MESSAGE), - style = MaterialTheme.typography.bodyMedium, - ) - } - } + } } /** @@ -202,10 +201,10 @@ private fun AlertInfo(alert: Alert) { */ @Composable private fun InteractionButtons( - content: CONTENT, - onEditClick: () -> Unit, - onAccpetClick: () -> Unit, - onResolveClick: () -> Unit, + content: CONTENT, + onEditClick: () -> Unit, + onAccpetClick: () -> Unit, + onResolveClick: () -> Unit, ) { Row( horizontalArrangement = Arrangement.spacedBy(MaterialTheme.dimens.small2), @@ -257,4 +256,4 @@ private fun InteractionButtons( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/android/periodpals/ui/map/Map.kt b/app/src/main/java/com/android/periodpals/ui/map/Map.kt index 8c66fcec..8604f7c0 100644 --- a/app/src/main/java/com/android/periodpals/ui/map/Map.kt +++ b/app/src/main/java/com/android/periodpals/ui/map/Map.kt @@ -165,8 +165,7 @@ fun MapScreen( showBottomSheet = true content = CONTENT.PAL_ALERT alertViewModel.selectAlert(alert) - } - ) + }) } LaunchedEffect(myLocation) { @@ -193,9 +192,7 @@ fun MapScreen( } Scaffold( - modifier = Modifier - .fillMaxSize() - .testTag(C.Tag.MapScreen.SCREEN), + modifier = Modifier.fillMaxSize().testTag(C.Tag.MapScreen.SCREEN), bottomBar = { BottomNavigationMenu( onTabSelect = { route -> navigationActions.navigateTo(route) }, @@ -205,9 +202,9 @@ fun MapScreen( }, topBar = { TopAppBar(title = SCREEN_TITLE) }, floatingActionButton = { - Column ( - verticalArrangement = - Arrangement.spacedBy(MaterialTheme.dimens.small3, Alignment.CenterVertically), + Column( + verticalArrangement = + Arrangement.spacedBy(MaterialTheme.dimens.small3, Alignment.CenterVertically), ) { // Recenter button @@ -228,25 +225,24 @@ fun MapScreen( content = { paddingValues -> AndroidView( modifier = - Modifier - .padding(paddingValues) - .fillMaxSize() - .testTag(C.Tag.MapScreen.MAP_VIEW_CONTAINER), + Modifier.padding(paddingValues) + .fillMaxSize() + .testTag(C.Tag.MapScreen.MAP_VIEW_CONTAINER), factory = { mapView }, ) if (showBottomSheet) { MapBottomSheet( - sheetState = sheetState, - content = content, - onSheetDismissRequest = { showBottomSheet = false }, - alertToDisplay = alertViewModel.selectedAlert.value, - onEditClick = { - alertViewModel.selectAlert(alertViewModel.selectedAlert.value!!) - navigationActions.navigateTo(Screen.EDIT_ALERT) - }, - onAcceptClick = { TODO("To be implemented") }, - onResolveClick = { TODO("To be implemented") }) + sheetState = sheetState, + content = content, + onSheetDismissRequest = { showBottomSheet = false }, + alertToDisplay = alertViewModel.selectedAlert.value, + onEditClick = { + alertViewModel.selectAlert(alertViewModel.selectedAlert.value!!) + navigationActions.navigateTo(Screen.EDIT_ALERT) + }, + onAcceptClick = { TODO("To be implemented") }, + onResolveClick = { TODO("To be implemented") }) } if (showFilterDialog) { @@ -254,18 +250,14 @@ fun MapScreen( context = context, currentRadius = radiusInMeters, location = selectedLocation, - - product = productFilter?.let { - productToPeriodPalsIcon(it).textId - } ?: FILTERS_NO_PREFERENCE_TEXT, - - urgency = urgencyFilter?.let { - urgencyToPeriodPalsIcon(it).textId - } ?: FILTERS_NO_PREFERENCE_TEXT, - + product = + productFilter?.let { productToPeriodPalsIcon(it).textId } + ?: FILTERS_NO_PREFERENCE_TEXT, + urgency = + urgencyFilter?.let { urgencyToPeriodPalsIcon(it).textId } + ?: FILTERS_NO_PREFERENCE_TEXT, onDismiss = { showFilterDialog = false }, onLocationSelected = { selectedLocation = it }, - onSave = { radius, product, urgency -> radiusInMeters = radius productFilter = stringToProduct(product) @@ -276,16 +268,16 @@ fun MapScreen( selectedLocation?.let { alertViewModel.fetchAlertsWithinRadius( - location = it, - radius = radiusInMeters, - onSuccess = { - Log.d(TAG, "Successfully fetched alerts within radius: $radiusInMeters") - }, - onFailure = { e -> Log.e(TAG, "Error fetching alerts within radius", e) } - ) + location = it, + radius = radiusInMeters, + onSuccess = { + Log.d(TAG, "Successfully fetched alerts within radius: $radiusInMeters") + }, + onFailure = { e -> Log.e(TAG, "Error fetching alerts within radius", e) }) } ?: Log.d(TAG, "Please select a valid location") - // Due to lazy evaluation, if the first clause is true, then the second will be skipped + // Due to lazy evaluation, if the first clause is true, then the second will be + // skipped // and it will evaluate the third clause after the &&. alertViewModel.setFilter { (productFilter == Product.NO_PREFERENCE || diff --git a/app/src/test/java/com/android/periodpals/ui/map/MapComponentsTest.kt b/app/src/test/java/com/android/periodpals/ui/map/MapComponentsTest.kt index 5b7ebf9f..cea482e5 100644 --- a/app/src/test/java/com/android/periodpals/ui/map/MapComponentsTest.kt +++ b/app/src/test/java/com/android/periodpals/ui/map/MapComponentsTest.kt @@ -99,8 +99,7 @@ class MapComponentsTest { alertToDisplay = mockAlertViewModel.selectedAlert.value, onEditClick = {}, onAcceptClick = {}, - onResolveClick = {} - ) + onResolveClick = {}) } composeTestRule.onNodeWithTag(Tag.MapScreen.BOTTOM_SHEET).assertIsDisplayed() @@ -131,14 +130,13 @@ class MapComponentsTest { composeTestRule.setContent { MapBottomSheet( - sheetState = sheetState, - content = CONTENT.MY_ALERT, - onSheetDismissRequest = {}, - alertToDisplay = mockAlertViewModel.selectedAlert.value, - onEditClick = {}, - onAcceptClick = {}, - onResolveClick = {} - ) + sheetState = sheetState, + content = CONTENT.MY_ALERT, + onSheetDismissRequest = {}, + alertToDisplay = mockAlertViewModel.selectedAlert.value, + onEditClick = {}, + onAcceptClick = {}, + onResolveClick = {}) } composeTestRule.onNodeWithTag(Tag.MapScreen.BOTTOM_SHEET).assertIsDisplayed() @@ -151,14 +149,13 @@ class MapComponentsTest { fun `bottom sheet appears with correct buttons when clicking on a pal alert`() { composeTestRule.setContent { MapBottomSheet( - sheetState = sheetState, - content = CONTENT.PAL_ALERT, - onSheetDismissRequest = {}, - alertToDisplay = mockAlertViewModel.selectedAlert.value , - onEditClick = {}, - onAcceptClick = {}, - onResolveClick = {} - ) + sheetState = sheetState, + content = CONTENT.PAL_ALERT, + onSheetDismissRequest = {}, + alertToDisplay = mockAlertViewModel.selectedAlert.value, + onEditClick = {}, + onAcceptClick = {}, + onResolveClick = {}) } composeTestRule.onNodeWithTag(Tag.MapScreen.BOTTOM_SHEET).assertIsDisplayed()