From 304fec18b290e61441e55fa950f621aa5574110f Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 10:41:04 +0100 Subject: [PATCH 01/18] feat(Events): Add new event types --- .../com/android/unio/model/event/Event.kt | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/android/unio/model/event/Event.kt b/app/src/main/java/com/android/unio/model/event/Event.kt index 20b9764e8..4e16521ad 100644 --- a/app/src/main/java/com/android/unio/model/event/Event.kt +++ b/app/src/main/java/com/android/unio/model/event/Event.kt @@ -10,14 +10,8 @@ import com.android.unio.model.association.Association import com.android.unio.model.firestore.ReferenceList import com.android.unio.model.firestore.UniquelyIdentifiable import com.android.unio.model.map.Location -import com.android.unio.ui.theme.eventTypeAperitif -import com.android.unio.ui.theme.eventTypeFestival -import com.android.unio.ui.theme.eventTypeJam -import com.android.unio.ui.theme.eventTypeNetworking -import com.android.unio.ui.theme.eventTypeNightParty -import com.android.unio.ui.theme.eventTypeOther -import com.android.unio.ui.theme.eventTypeSport -import com.android.unio.ui.theme.eventTypeTrip +import com.android.unio.ui.theme.EventColors +import com.android.unio.R import com.google.firebase.Timestamp import java.util.Date @@ -53,7 +47,7 @@ data class Event( val startDate: Timestamp = Timestamp(Date()), val endDate: Timestamp = Timestamp(Date()), val location: Location = Location(), - val types: List = mutableListOf(EventType.OTHER), + val types: List, val maxNumberOfPlaces: Int = -1, val numberOfSaved: Int = 0, val eventPictures: ReferenceList, @@ -67,15 +61,25 @@ data class Event( * @property color event type color * @property text event type text */ -enum class EventType(val color: Color, val text: String) { - FESTIVAL(eventTypeFestival, "festival"), - APERITIF(eventTypeAperitif, "aperitif"), - NIGHT_PARTY(eventTypeNightParty, "night party"), - JAM(eventTypeJam, "jam"), - NETWORKING(eventTypeNetworking, "networking"), - SPORT(eventTypeSport, "sport"), - TRIP(eventTypeTrip, "trip"), - OTHER(eventTypeOther, "other") +enum class EventType(val color: Color, val text: Int) { + FESTIVAL(EventColors.Festival, R.string.event_type_festival), // + Music and Festivals + APERITIF(EventColors.Aperitif, R.string.event_type_aperitif), // + Food and Apéro + NIGHT_PARTY(EventColors.NightParty, R.string.event_type_night_party), // + Music and Festivals + JAM(EventColors.Jam, R.string.event_type_jam), // + Music and Art + NETWORKING(EventColors.Networking, R.string.event_type_networking), // + Apéro and Networking + SPORT_TOURNAMENT(EventColors.SportTournament, R.string.event_type_sport_tournament), // + Sports + SPORT_DISCOVERY(EventColors.SportDiscovery, R.string.event_type_sport_discovery), // + Sports, Socialising + TRIP(EventColors.Trip, R.string.event_type_trip), // + Travel, Culture + LAN(EventColors.Lan, R.string.event_type_lan), // + Gaming + FILM_PROJECTION(EventColors.FilmProjection, R.string.event_type_film_projection), // + Art, Culture + FOREIGN_CULTURE_DISCOVERY(EventColors.ForeignCultureDiscovery, R.string.event_type_foreign_culture_discovery), // + Culture, Literature + TECH_PRESENTATION(EventColors.TechPresentation, R.string.event_type_tech_presentation), // + Tech, Science + SCIENCE_FARE(EventColors.ScienceFare, R.string.event_type_science_fare), // + Science, Tech + FOOD_DISTRIBUTION(EventColors.FoodDistribution, R.string.event_type_food_distribuition), // + Food + ART_CONVENTION(EventColors.ArtConvention, R.string.event_type_art_convention), // + Art, Literature + MANIFESTATION(EventColors.Manifestation, R.string.event_type_manifestation), // + Culture, Socialising + BOARD_GAMES(EventColors.BoardGames, R.string.event_type_board_games), // + Gaming, Socialising + GROUP_STUDY(EventColors.GroupStudy, R.string.event_type_group_study), // + Science, Tech } /** From ac1455725f57fe66ea545408f0e66cbc7a10fe0c Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 10:41:27 +0100 Subject: [PATCH 02/18] feat(Users): Add new user interests to match event types --- app/src/main/java/com/android/unio/model/user/User.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/android/unio/model/user/User.kt b/app/src/main/java/com/android/unio/model/user/User.kt index 07610be7c..437900180 100644 --- a/app/src/main/java/com/android/unio/model/user/User.kt +++ b/app/src/main/java/com/android/unio/model/user/User.kt @@ -21,6 +21,9 @@ enum class Interest(val title: Int) { FOOD(R.string.interest_food), GAMING(R.string.interest_gaming), FESTIVALS(R.string.interest_festivals), + APEROS(R.string.interest_apero), + NETWORKING(R.string.interest_networking), + CULTURE(R.string.interest_culture) } enum class Social(val title: String, val icon: Int, val url: String) { From 775087746be47c60ad5031f0e24364dfd65fec07 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 10:41:48 +0100 Subject: [PATCH 03/18] feat(Event): Add new translations for new event types --- app/src/main/res/values-fr/strings.xml | 20 ++++++++++++++++++-- app/src/main/res/values/strings.xml | 19 +++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f25249eaa..c86d6b984 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -375,9 +375,19 @@ Soirée Jam Réseautage - Sport Voyage - Autre + Tournoi de sport + Découverte de sport + Lan + Projection de film + Découverte de culture étrangère + Présentation de Tech + Exposition de Sciences + Distribution de nourriture + Convention d\'Art + Manifestation + Jeux de sociétés + Études en groupe Erreur lors de la conversion du document de la base de données en objet Évènement @@ -401,6 +411,12 @@ Nourriture Gaming Festivals + Apéro + Résautage + Culture + + + Retour Modifier l\'Association Recrutement diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4926a2889..9b94d67e6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -421,9 +421,20 @@ Night Party Jam Networking - Sport Trip - Other + Sport Tournament + Sport + Lan + Film Projection + Foreing Culture Discovery + Tech Presentation + Science Fare + Food Distribution + Art Convention + Manifestation + Board Games + Groups study + Error while converting db document to Event object @@ -461,6 +472,10 @@ Food Gaming Festivals + Apero + Networking + Culture + An email has been sent to the given address From 29009167265733d9ac4714df04fcaecbcf7bdeda Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 10:42:03 +0100 Subject: [PATCH 04/18] feat(Event): Add new colors for new event types --- .../java/com/android/unio/ui/theme/Color.kt | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/android/unio/ui/theme/Color.kt b/app/src/main/java/com/android/unio/ui/theme/Color.kt index 97ba23147..383c54b9a 100644 --- a/app/src/main/java/com/android/unio/ui/theme/Color.kt +++ b/app/src/main/java/com/android/unio/ui/theme/Color.kt @@ -219,14 +219,26 @@ val surfaceContainerDarkHighContrast = Color(0xFF1F1F25) val surfaceContainerHighDarkHighContrast = Color(0xFF2A292F) val surfaceContainerHighestDarkHighContrast = Color(0xFF35343A) -val eventTypeFestival = Color(0xFF6200EE) // Purple -val eventTypeAperitif = Color(0xFF03DAC5) // Teal -val eventTypeNightParty = Color(0xFFFF5722) // Deep Orange -val eventTypeJam = Color(0xFFFFEB3B) // Yellow -val eventTypeNetworking = Color(0xFF009688) // Cyan -val eventTypeSport = Color(0xFF8BC34A) // Light Green -val eventTypeTrip = Color(0xFFE91E63) // Pink -val eventTypeOther = Color.Gray // Default Color +object EventColors{ + val Festival = Color(0xFF6200EE) // Purple + val Aperitif = Color(0xFF03DAC5) // Teal + val NightParty = Color(0xFFFF5722) // Deep Orange + val Jam = Color(0xFFFFEB3B) // Yellow + val Networking = Color(0xFF009688) // Cyan + val SportTournament = Color(0xFF8BC34A) // Light Green + val Trip = Color(0xFFE91E63) // Pink + val SportDiscovery = Color(0xFF3B40F4) + val Lan = Color(0xFF3F074C) + val FilmProjection = Color(0xFFFCD746) + val ForeignCultureDiscovery = Color(0xFF7EE4CA) + val TechPresentation = Color(0xFFB8397D) + val ScienceFare = Color(0xFF5DF09B) + val FoodDistribution = Color(0xFF33811E) + val ArtConvention = Color(0xFF2dAAAF) + val Manifestation = Color(0xFFF2801D) + val BoardGames = Color(0xFFAE86AC) + val GroupStudy = Color(0xFFF3A885) +} // Colors for the approximate user location circle on the map val mapUserLocationCircleFiller = Color(0x2200A0FF) From b25bcc03d1f8448826b6ba87a1e29a2d67552b9b Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 11:18:28 +0100 Subject: [PATCH 05/18] feat(Event): Add Other event type as a default --- app/src/main/java/com/android/unio/model/event/Event.kt | 1 + app/src/main/java/com/android/unio/ui/theme/Color.kt | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 4 files changed, 4 insertions(+) diff --git a/app/src/main/java/com/android/unio/model/event/Event.kt b/app/src/main/java/com/android/unio/model/event/Event.kt index 4e16521ad..81ab52f32 100644 --- a/app/src/main/java/com/android/unio/model/event/Event.kt +++ b/app/src/main/java/com/android/unio/model/event/Event.kt @@ -80,6 +80,7 @@ enum class EventType(val color: Color, val text: Int) { MANIFESTATION(EventColors.Manifestation, R.string.event_type_manifestation), // + Culture, Socialising BOARD_GAMES(EventColors.BoardGames, R.string.event_type_board_games), // + Gaming, Socialising GROUP_STUDY(EventColors.GroupStudy, R.string.event_type_group_study), // + Science, Tech + OTHER(EventColors.Other, R.string.event_type_other) } /** diff --git a/app/src/main/java/com/android/unio/ui/theme/Color.kt b/app/src/main/java/com/android/unio/ui/theme/Color.kt index 383c54b9a..399052745 100644 --- a/app/src/main/java/com/android/unio/ui/theme/Color.kt +++ b/app/src/main/java/com/android/unio/ui/theme/Color.kt @@ -238,6 +238,7 @@ object EventColors{ val Manifestation = Color(0xFFF2801D) val BoardGames = Color(0xFFAE86AC) val GroupStudy = Color(0xFFF3A885) + val Other = Color.Gray // Default Color } // Colors for the approximate user location circle on the map diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c86d6b984..c70f71df9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -388,6 +388,7 @@ Manifestation Jeux de sociétés Études en groupe + Autre Erreur lors de la conversion du document de la base de données en objet Évènement diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b94d67e6..b20b3370d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -434,6 +434,7 @@ Manifestation Board Games Groups study + Other From 6dc85672b5c1121ff4d67e62e70f05d7dcf8bc59 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 15:14:11 +0100 Subject: [PATCH 06/18] feat(EventType): Add EventTypeOverlay skeleton --- .../com/android/unio/ui/event/EventCard.kt | 2 +- .../android/unio/ui/event/EventCreation.kt | 24 +++ .../com/android/unio/ui/event/EventEdit.kt | 15 ++ .../unio/ui/event/overlay/EventTypeOverlay.kt | 140 ++++++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt diff --git a/app/src/main/java/com/android/unio/ui/event/EventCard.kt b/app/src/main/java/com/android/unio/ui/event/EventCard.kt index a46a2e85a..06dcac6a2 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventCard.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventCard.kt @@ -232,7 +232,7 @@ fun EventCardScaffold( .background(addAlphaToColor(type.color, 200)) .wrapContentWidth()) { Text( - text = type.text, + text = context.getString(type.text), modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp) .testTag(EventCardTestTags.EVENT_MAIN_TYPE), diff --git a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt index a6f1c2ba7..0d321a3e1 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt @@ -39,6 +39,7 @@ import com.android.unio.mocks.firestore.MockReferenceList import com.android.unio.model.association.Association import com.android.unio.model.association.AssociationViewModel import com.android.unio.model.event.Event +import com.android.unio.model.event.EventType import com.android.unio.model.event.EventViewModel import com.android.unio.model.firestore.firestoreReferenceListWith import com.android.unio.model.map.Location @@ -52,9 +53,11 @@ import com.android.unio.ui.components.BannerImagePicker import com.android.unio.ui.components.DateAndTimePicker import com.android.unio.ui.components.NominatimLocationPicker import com.android.unio.ui.event.overlay.AssociationsOverlay +import com.android.unio.ui.event.overlay.EventTypeOverlay import com.android.unio.ui.navigation.NavigationAction import com.android.unio.ui.theme.AppTypography import com.google.firebase.Timestamp +import kotlinx.coroutines.flow.MutableStateFlow /** * A screen that allows users to create an event. @@ -77,11 +80,18 @@ fun EventCreationScreen( val scrollState = rememberScrollState() var showCoauthorsOverlay by remember { mutableStateOf(false) } var showTaggedOverlay by remember { mutableStateOf(false) } + var showEventTypeOverlay by remember { mutableStateOf(false) } var name by remember { mutableStateOf("") } var shortDescription by remember { mutableStateOf("") } var longDescription by remember { mutableStateOf("") } + val EventTypeFlow = remember { + MutableStateFlow(EventType.entries.map { it to mutableStateOf(false) }.toList()) + } + + val eventTypes by EventTypeFlow.collectAsState() + var coauthorsAndBoolean = associationViewModel.associations.collectAsState().value.map { it to mutableStateOf(false) } @@ -194,6 +204,19 @@ fun EventCreationScreen( AssociationChips(taggedAndBoolean) + OutlinedButton( + modifier = Modifier + .fillMaxWidth() + .testTag("todo"), + onClick = { showEventTypeOverlay = true } + ) { + Icon( + Icons.Default.Add, + contentDescription = + context.getString(R.string.social_overlay_content_description_add)) + Text(context.getString(R.string.event_creation_tagged_label)) + } + OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.DESCRIPTION), value = longDescription, @@ -304,6 +327,7 @@ fun EventCreationScreen( startDate = startTimestamp!!, endDate = endTimestamp!!, location = selectedLocation!!, + types = emptyList(), eventPictures = MockReferenceList(), ) eventViewModel.addEvent( diff --git a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt index 7f26a2afb..287d5270f 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt @@ -80,6 +80,7 @@ fun EventEditScreen( val scrollState = rememberScrollState() var showCoauthorsOverlay by remember { mutableStateOf(false) } var showTaggedOverlay by remember { mutableStateOf(false) } + var showEventTypeOverlay by remember { mutableStateOf(false) } val eventToEdit = remember { eventViewModel.selectedEvent.value!! } @@ -175,6 +176,19 @@ fun EventEditScreen( AssociationChips(taggedAndBoolean) + OutlinedButton( + modifier = Modifier + .fillMaxWidth() + .testTag("todo"), + onClick = { showEventTypeOverlay = true } + ) { + Icon( + Icons.Default.Add, + contentDescription = + context.getString(R.string.social_overlay_content_description_add)) + Text(context.getString(R.string.event_creation_tagged_label)) + } + OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventEditTestTags.DESCRIPTION), value = longDescription, @@ -294,6 +308,7 @@ fun EventEditScreen( startDate = startTimestamp!!, endDate = endTimestamp!!, location = selectedLocation!!, + types = emptyList(), eventPictures = MockReferenceList(), ) // This should be extracted to a util diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt new file mode 100644 index 000000000..a5e9d2d4c --- /dev/null +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -0,0 +1,140 @@ +package com.android.unio.ui.event.overlay + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.sizeIn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Checkbox +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.android.unio.model.event.EventType +import com.android.unio.ui.theme.AppTypography + + +@Composable +fun EventTypeOverlay( + onDismiss: () -> Unit, + onSave: (List>>) -> Unit, + types: List>> +) { + val context = LocalContext.current + val scrollState = rememberScrollState() + val copiedTypes = types.toList().map { it.first to mutableStateOf(it.second.value) } + + Dialog( + onDismissRequest = onDismiss, + properties = DialogProperties(usePlatformDefaultWidth = false)) { + Card( + elevation = CardDefaults.cardElevation(8.dp), + shape = RoundedCornerShape(16.dp), + modifier = + Modifier.fillMaxWidth().padding(20.dp).testTag()) { //InterestsOverlayTestTags.CARD + Column( + modifier = + Modifier.fillMaxWidth() + .padding(15.dp) + .sizeIn(maxHeight = 400.dp) + .testTag(), //InterestsOverlayTestTags.COLUMN + verticalArrangement = Arrangement.SpaceBetween) { + + // Text fields for the title and description of the Interest Overlay + Text( + text = context.getString(), //R.string.interest_overlay_title + style = AppTypography.headlineSmall, + modifier = Modifier.testTag()) //InterestsOverlayTestTags.TITLE_TEXT + Text( + text = context.getString(), //R.string.interest_overlay_description + style = AppTypography.bodyMedium, + modifier = + Modifier.padding(bottom = 5.dp) + .testTag()) //InterestsOverlayTestTags.SUBTITLE_TEXT + Surface( + modifier = Modifier.sizeIn(maxHeight = 250.dp), color = Color.Transparent) { + Column(modifier = Modifier.verticalScroll(scrollState)) { + copiedTypes.forEachIndexed { index, pair -> + + // The row for each interest + EventTypeOverlayRow(pair) + + if (index != copiedTypes.size - 1) { + HorizontalDivider( + modifier = + Modifier.testTag()) //InterestsOverlayTestTags.DIVIDER + "$index" + } + } + } + } + + // Buttons for saving and cancelling the changes + Row( + modifier = Modifier.fillMaxWidth().padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Absolute.Right) { + OutlinedButton( + shape = RoundedCornerShape(16.dp), + onClick = onDismiss, + modifier = + Modifier.padding(5.dp) + .testTag()) { //InterestsOverlayTestTags.CANCEL_BUTTON + Text(context.getString()) //R.string.overlay_cancel + } + + Button( + onClick = { onSave(copiedTypes) }, + modifier = + Modifier.padding(5.dp) + .testTag()) { //InterestsOverlayTestTags.SAVE_BUTTON + Text(context.getString()) //R.string.overlay_save + } + } + } + } + } +} + +@Composable +private fun EventTypeOverlayRow( + pair: Pair>, +) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier.padding(5.dp) + .fillMaxWidth() + .testTag() //InterestsOverlayTestTags.CLICKABLE_ROW + pair.first.name + .clickable { pair.second.value = !pair.second.value }) { + Text( + text = pair.first.name, + style = AppTypography.bodyMedium, + modifier = + Modifier.padding(start = 5.dp) + .testTag()) //InterestsOverlayTestTags.TEXT + pair.first.name + Checkbox( + checked = pair.second.value, + onCheckedChange = { pair.second.value = it }, + modifier = Modifier.testTag()) //InterestsOverlayTestTags.CHECKBOX + pair.first.name + } +} From e735a1dcf7255cb720f834447d631e8493125d65 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 15:59:29 +0100 Subject: [PATCH 07/18] chore(EventTypeOverlay): Add necessary test tags --- .../strings/test_tags/event/EventTestTags.kt | 13 ++++++++++++ .../unio/ui/event/overlay/EventTypeOverlay.kt | 21 ++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt index 3b41aec7a..2d1e63400 100644 --- a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt +++ b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt @@ -115,3 +115,16 @@ object EventDetailsTestTags { const val EVENT_PICTURES_ARROW_RIGHT = "picturesArrowRight" const val PICTURE_FULL_SCREEN = "pictureFullScreen" } + +object EventTypeOverlayTestTags { + const val CARD = "eventOverlayCard" + const val COLUMN = "eventOverlayColumn" + const val TITLE_TEXT = "eventOverlayTitleText" + const val SUBTITLE_TEXT = "eventOverlaySubtitleText" + const val DIVIDER = "eventOverlayDivider" + const val CANCEL_BUTTON = "eventOverlayCancelButton" + const val SAVE_BUTTON = "eventOverlaySaveButton" + const val CLICKABLE_ROW = "eventOverlayClickableRow" + const val TEXT = "eventOverlayRowText" + const val CHECK_BOX = "eventOverlayRowCheckBox" +} diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index a5e9d2d4c..d96964791 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.android.unio.model.event.EventType +import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags import com.android.unio.ui.theme.AppTypography @@ -50,26 +51,26 @@ fun EventTypeOverlay( elevation = CardDefaults.cardElevation(8.dp), shape = RoundedCornerShape(16.dp), modifier = - Modifier.fillMaxWidth().padding(20.dp).testTag()) { //InterestsOverlayTestTags.CARD + Modifier.fillMaxWidth().padding(20.dp).testTag(EventTypeOverlayTestTags.CARD)) { Column( modifier = Modifier.fillMaxWidth() .padding(15.dp) .sizeIn(maxHeight = 400.dp) - .testTag(), //InterestsOverlayTestTags.COLUMN + .testTag(EventTypeOverlayTestTags.COLUMN), verticalArrangement = Arrangement.SpaceBetween) { // Text fields for the title and description of the Interest Overlay Text( text = context.getString(), //R.string.interest_overlay_title style = AppTypography.headlineSmall, - modifier = Modifier.testTag()) //InterestsOverlayTestTags.TITLE_TEXT + modifier = Modifier.testTag(EventTypeOverlayTestTags.TITLE_TEXT)) Text( text = context.getString(), //R.string.interest_overlay_description style = AppTypography.bodyMedium, modifier = Modifier.padding(bottom = 5.dp) - .testTag()) //InterestsOverlayTestTags.SUBTITLE_TEXT + .testTag(EventTypeOverlayTestTags.SUBTITLE_TEXT)) Surface( modifier = Modifier.sizeIn(maxHeight = 250.dp), color = Color.Transparent) { Column(modifier = Modifier.verticalScroll(scrollState)) { @@ -81,7 +82,7 @@ fun EventTypeOverlay( if (index != copiedTypes.size - 1) { HorizontalDivider( modifier = - Modifier.testTag()) //InterestsOverlayTestTags.DIVIDER + "$index" + Modifier.testTag(EventTypeOverlayTestTags.DIVIDER + "$index")) } } } @@ -97,7 +98,7 @@ fun EventTypeOverlay( onClick = onDismiss, modifier = Modifier.padding(5.dp) - .testTag()) { //InterestsOverlayTestTags.CANCEL_BUTTON + .testTag(EventTypeOverlayTestTags.CANCEL_BUTTON)) { Text(context.getString()) //R.string.overlay_cancel } @@ -105,7 +106,7 @@ fun EventTypeOverlay( onClick = { onSave(copiedTypes) }, modifier = Modifier.padding(5.dp) - .testTag()) { //InterestsOverlayTestTags.SAVE_BUTTON + .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { Text(context.getString()) //R.string.overlay_save } } @@ -124,17 +125,17 @@ private fun EventTypeOverlayRow( modifier = Modifier.padding(5.dp) .fillMaxWidth() - .testTag() //InterestsOverlayTestTags.CLICKABLE_ROW + pair.first.name + .testTag(EventTypeOverlayTestTags.CLICKABLE_ROW + pair.first.name) .clickable { pair.second.value = !pair.second.value }) { Text( text = pair.first.name, style = AppTypography.bodyMedium, modifier = Modifier.padding(start = 5.dp) - .testTag()) //InterestsOverlayTestTags.TEXT + pair.first.name + .testTag(EventTypeOverlayTestTags.TEXT + pair.first.name)) Checkbox( checked = pair.second.value, onCheckedChange = { pair.second.value = it }, - modifier = Modifier.testTag()) //InterestsOverlayTestTags.CHECKBOX + pair.first.name + modifier = Modifier.testTag(EventTypeOverlayTestTags.CHECK_BOX + pair.first.name)) } } From df1a23f83e6973129910c2b93a7761a6ebed479b Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 16:22:07 +0100 Subject: [PATCH 08/18] feat(EventCreation): Add functional types selector overlay --- .../android/unio/ui/event/EventCreation.kt | 21 ++++++++++++++----- .../unio/ui/event/overlay/EventTypeOverlay.kt | 9 ++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt index ed3eafd7e..46178de88 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt @@ -86,11 +86,11 @@ fun EventCreationScreen( var shortDescription by remember { mutableStateOf("") } var longDescription by remember { mutableStateOf("") } - val EventTypeFlow = remember { + val eventTypeFlow = remember { MutableStateFlow(EventType.entries.map { it to mutableStateOf(false) }.toList()) } - val eventTypes by EventTypeFlow.collectAsState() + val types by eventTypeFlow.collectAsState() var coauthorsAndBoolean = associationViewModel.associations.collectAsState().value.map { it to mutableStateOf(false) } @@ -219,14 +219,14 @@ fun EventCreationScreen( OutlinedButton( modifier = Modifier .fillMaxWidth() - .testTag("todo"), + .testTag(EventCreationTestTags.EVENT_TYPE), onClick = { showEventTypeOverlay = true } ) { Icon( Icons.Default.Add, contentDescription = context.getString(R.string.social_overlay_content_description_add)) - Text(context.getString(R.string.event_creation_tagged_label)) + Text(context.getString(R.string.event_creation_type)) } OutlinedTextField( @@ -345,7 +345,7 @@ fun EventCreationScreen( startDate = startTimestamp!!, endDate = endTimestamp!!, location = selectedLocation!!, - types = emptyList(), + types = types.filter { it.second.value }.map { it.first }, eventPictures = MockReferenceList(), ) eventViewModel.addEvent( @@ -392,5 +392,16 @@ fun EventCreationScreen( headerText = context.getString(R.string.associations_overlay_tagged_title), bodyText = context.getString(R.string.associations_overlay_tagged_description)) } + + if(showEventTypeOverlay) { + EventTypeOverlay( + onDismiss = { showEventTypeOverlay = false }, + onSave = { types -> + eventTypeFlow.value = types + showEventTypeOverlay = false + }, + types = types + ) + } } } diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index d96964791..c83d18c41 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties +import com.android.unio.R import com.android.unio.model.event.EventType import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags import com.android.unio.ui.theme.AppTypography @@ -62,11 +63,11 @@ fun EventTypeOverlay( // Text fields for the title and description of the Interest Overlay Text( - text = context.getString(), //R.string.interest_overlay_title + text = context.getString(R.string.event_type_overlay_title), style = AppTypography.headlineSmall, modifier = Modifier.testTag(EventTypeOverlayTestTags.TITLE_TEXT)) Text( - text = context.getString(), //R.string.interest_overlay_description + text = context.getString(R.string.event_type_overlay_description), style = AppTypography.bodyMedium, modifier = Modifier.padding(bottom = 5.dp) @@ -99,7 +100,7 @@ fun EventTypeOverlay( modifier = Modifier.padding(5.dp) .testTag(EventTypeOverlayTestTags.CANCEL_BUTTON)) { - Text(context.getString()) //R.string.overlay_cancel + Text(context.getString(R.string.overlay_cancel)) } Button( @@ -107,7 +108,7 @@ fun EventTypeOverlay( modifier = Modifier.padding(5.dp) .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { - Text(context.getString()) //R.string.overlay_save + Text(context.getString(R.string.overlay_save)) } } } From 499acbf8132d978bf8ceba35cab897a88f9f6769 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 18:27:23 +0100 Subject: [PATCH 09/18] refactor(EventEditComposable): Make association Chip generic --- .../unio/ui/components/EventEditComponents.kt | 93 ++++++++++--------- 1 file changed, 50 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt index 424dbd2bc..83964321d 100644 --- a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt +++ b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt @@ -57,7 +57,6 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties import com.android.unio.R -import com.android.unio.model.association.Association import com.android.unio.model.map.Location import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel import com.android.unio.model.strings.FormatStrings.DAY_MONTH_YEAR_FORMAT @@ -166,33 +165,35 @@ fun NominatimLocationPicker( } /** - * Composable for the association chips that show the selected associations. + * Composable for the different chips used that must be displayed in a flowRow * - * @param associations List>> : List of associations and - * their selected state. + * @param items a generic list of items that can have their elements selected or not */ @OptIn(ExperimentalLayoutApi::class) @Composable -fun AssociationChips( - associations: List>>, -) { - val context = LocalContext.current - FlowRow { - associations.forEach { (association, selected) -> - if (selected.value) { - InputChip( - label = { Text(association.name) }, - onClick = {}, - selected = selected.value, - avatar = { - Icon( - Icons.Default.Close, - contentDescription = context.getString(R.string.associations_overlay_remove), - modifier = Modifier.clickable { selected.value = !selected.value }) - }) - } +fun Chips( + items: List>>, + getName: (T) -> String, +){ + val context = LocalContext.current + + FlowRow { + items.forEach { (item, selected) -> + if (selected.value) { + InputChip( + label = { Text(getName(item)) }, + onClick = {}, + selected = selected.value, + avatar = { + Icon( + Icons.Default.Close, + contentDescription = context.getString(R.string.associations_overlay_remove), + modifier = Modifier.clickable { selected.value = !selected.value }) + }) + } + + } } - } } /** @@ -268,17 +269,20 @@ fun DateAndTimePicker( ) { OutlinedTextField( modifier = - Modifier.testTag(dateFieldTestTag).weight(1f).pointerInput(Unit) { - awaitEachGesture { - // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput - // in the Initial pass to observe events before the text field consumes them - // in the Main pass. - awaitFirstDown(pass = PointerEventPass.Initial) - val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) - if (upEvent != null) { - isDatePickerVisible = true + Modifier + .testTag(dateFieldTestTag) + .weight(1f) + .pointerInput(Unit) { + awaitEachGesture { + // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput + // in the Initial pass to observe events before the text field consumes them + // in the Main pass. + awaitFirstDown(pass = PointerEventPass.Initial) + val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) + if (upEvent != null) { + isDatePickerVisible = true + } } - } }, value = selectedDate?.let { convertMillisToDate(it) } @@ -302,17 +306,20 @@ fun DateAndTimePicker( Spacer(modifier = Modifier.weight(0.05f)) OutlinedTextField( modifier = - Modifier.testTag(timeFieldTestTag).weight(1f).pointerInput(Unit) { - awaitEachGesture { - // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput - // in the Initial pass to observe events before the text field consumes them - // in the Main pass. - awaitFirstDown(pass = PointerEventPass.Initial) - val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) - if (upEvent != null) { - isTimePickerVisible = true + Modifier + .testTag(timeFieldTestTag) + .weight(1f) + .pointerInput(Unit) { + awaitEachGesture { + // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput + // in the Initial pass to observe events before the text field consumes them + // in the Main pass. + awaitFirstDown(pass = PointerEventPass.Initial) + val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) + if (upEvent != null) { + isTimePickerVisible = true + } } - } }, value = selectedTime?.let { convertMillisToTime(it) } From 0844fe1989906da70deac9456f33dcf1d62a2e04 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 18:28:22 +0100 Subject: [PATCH 10/18] refactor(EventCreation/Edition): Use the new generic chip composable --- .../android/unio/ui/event/EventCreation.kt | 17 +++++-- .../com/android/unio/ui/event/EventEdit.kt | 44 ++++++++++++++++--- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt index 46178de88..154d05c03 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt @@ -48,8 +48,8 @@ import com.android.unio.model.search.SearchViewModel import com.android.unio.model.strings.test_tags.event.EventCreationTestTags import com.android.unio.model.utils.TextLength import com.android.unio.model.utils.Utils -import com.android.unio.ui.components.AssociationChips import com.android.unio.ui.components.BannerImagePicker +import com.android.unio.ui.components.Chips import com.android.unio.ui.components.DateAndTimePicker import com.android.unio.ui.components.NominatimLocationPicker import com.android.unio.ui.event.overlay.AssociationsOverlay @@ -202,7 +202,10 @@ fun EventCreationScreen( Text(context.getString(R.string.event_creation_coauthors_label)) } - AssociationChips(coauthorsAndBoolean) + Chips( + coauthorsAndBoolean, + getName = { it.name } + ) OutlinedButton( modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.TAGGED_ASSOCIATIONS), @@ -214,7 +217,10 @@ fun EventCreationScreen( Text(context.getString(R.string.event_creation_tagged_label)) } - AssociationChips(taggedAndBoolean) + Chips( + taggedAndBoolean, + getName = { it.name } + ) OutlinedButton( modifier = Modifier @@ -229,6 +235,11 @@ fun EventCreationScreen( Text(context.getString(R.string.event_creation_type)) } + Chips( + types, + getName = { context.getString(it.text) } + ) + OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.DESCRIPTION), value = longDescription, diff --git a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt index 4b85e1863..a623a84ef 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt @@ -41,6 +41,7 @@ import com.android.unio.mocks.firestore.MockReferenceList import com.android.unio.model.association.Association import com.android.unio.model.association.AssociationViewModel import com.android.unio.model.event.Event +import com.android.unio.model.event.EventType import com.android.unio.model.event.EventViewModel import com.android.unio.model.firestore.firestoreReferenceListWith import com.android.unio.model.map.Location @@ -49,15 +50,17 @@ import com.android.unio.model.search.SearchViewModel import com.android.unio.model.strings.test_tags.event.EventEditTestTags import com.android.unio.model.user.ImageUriType import com.android.unio.model.user.checkImageUri -import com.android.unio.ui.components.AssociationChips import com.android.unio.ui.components.BannerImagePicker +import com.android.unio.ui.components.Chips import com.android.unio.ui.components.DateAndTimePicker import com.android.unio.ui.components.NominatimLocationPicker import com.android.unio.ui.components.getHHMMInMillisFromTimestamp import com.android.unio.ui.event.overlay.AssociationsOverlay +import com.android.unio.ui.event.overlay.EventTypeOverlay import com.android.unio.ui.navigation.NavigationAction import com.android.unio.ui.theme.AppTypography import com.google.firebase.Timestamp +import kotlinx.coroutines.flow.MutableStateFlow /** * Composable function that displays the event edit screen. It functions similarly to the Event @@ -88,6 +91,12 @@ fun EventEditScreen( var shortDescription by remember { mutableStateOf(eventToEdit.catchyDescription.trim()) } var longDescription by remember { mutableStateOf(eventToEdit.description.trim()) } + val eventTypeFlow = remember { + MutableStateFlow(EventType.entries.map { it to mutableStateOf(eventToEdit.types.contains(it)) }) + } + + val types by eventTypeFlow.collectAsState() + var coauthorsAndBoolean = associationViewModel.associations.collectAsState().value.map { it to @@ -174,7 +183,10 @@ fun EventEditScreen( Text(context.getString(R.string.event_creation_coauthors_label)) } - AssociationChips(coauthorsAndBoolean) + Chips( + coauthorsAndBoolean, + getName = { it.name }, + ) OutlinedButton( modifier = Modifier.fillMaxWidth().testTag(EventEditTestTags.TAGGED_ASSOCIATIONS), @@ -186,21 +198,30 @@ fun EventEditScreen( Text(context.getString(R.string.event_creation_tagged_label)) } - AssociationChips(taggedAndBoolean) + Chips( + taggedAndBoolean, + getName = { it.name }, + ) OutlinedButton( modifier = Modifier .fillMaxWidth() - .testTag("todo"), + .testTag(EventEditTestTags.EVENT_TYPE), onClick = { showEventTypeOverlay = true } ) { Icon( Icons.Default.Add, contentDescription = context.getString(R.string.social_overlay_content_description_add)) - Text(context.getString(R.string.event_creation_tagged_label)) + Text(context.getString(R.string.event_edit_type)) } + Chips( + types, + getName = { context.getString(it.text) } + ) + + OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventEditTestTags.DESCRIPTION), value = longDescription, @@ -326,7 +347,7 @@ fun EventEditScreen( startDate = startTimestamp!!, endDate = endTimestamp!!, location = selectedLocation!!, - types = emptyList(), + types = types.filter { it.second.value }.map { it.first }, eventPictures = MockReferenceList(), ) // This should be extracted to a util @@ -388,5 +409,16 @@ fun EventEditScreen( bodyText = context.getString(R.string.associations_overlay_tagged_description)) } } + + if(showEventTypeOverlay){ + EventTypeOverlay( + onDismiss = { showEventTypeOverlay = false }, + onSave = { types -> + eventTypeFlow.value = types + showEventTypeOverlay = false + }, + types = types + ) + } } } From 3424e52da1fc4da9f107368126f7908bd2ea7660 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 18:28:45 +0100 Subject: [PATCH 11/18] chore(TestTage/Strings): Add corresponding test tags and strings --- .../unio/model/strings/test_tags/event/EventTestTags.kt | 2 ++ app/src/main/res/values-fr/strings.xml | 7 +++++++ app/src/main/res/values/strings.xml | 9 +++++++++ 3 files changed, 18 insertions(+) diff --git a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt index 2d1e63400..cbdbac15b 100644 --- a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt +++ b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt @@ -20,6 +20,7 @@ object EventCreationTestTags { const val SHORT_DESCRIPTION = "eventCreationShortDescription" const val COAUTHORS = "eventCreationCoauthors" const val TAGGED_ASSOCIATIONS = "eventCreationTaggedAssociations" + const val EVENT_TYPE = "eventCreationEventType" const val DESCRIPTION = "eventCreationDescription" const val LOCATION = "eventCreationLocation" const val SAVE_BUTTON = "eventCreationSaveButton" @@ -59,6 +60,7 @@ object EventEditTestTags { const val SHORT_DESCRIPTION = "eventEditShortDescription" const val COAUTHORS = "eventEditCoauthors" const val TAGGED_ASSOCIATIONS = "eventEditTaggedAssociations" + const val EVENT_TYPE = "eventEditEventType" const val DESCRIPTION = "eventEditDescription" const val LOCATION = "eventEditLocation" const val LOCATION_SUGGESTION_ITEM = "eventCreationSuggestionItem: " diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 12133cd5e..ce66c865a 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -213,12 +213,15 @@ Entrez un nom d\'événement Entrez une courte description de l\'événement Entrez une description de l\'événement + Ajouter des types à l\'événement Modifier Supprimer Echec lors de la modification Sauvegarder + Modifier les types de votre événement + Sélectionner une date @@ -228,6 +231,10 @@ Localisation erronée Continuez à taper pour voir plus de résultats + + Type de l\'événement + Choisissez jusqu\'à trois types d\'événements pour mieux décrire votre événement à votre audiance + Co-organisateurs Choisir quels associations organisent l\'évènement avec vous diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5dfec9ba7..c019279b4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -217,12 +217,16 @@ Enter an event name Enter an event short description Enter an event description + Add types to your event + Edit Delete Failed to edit event Save + Edit the type of your event + Select date @@ -232,6 +236,11 @@ Wrong location input Continue typing to see more results + + Event Type + Choose up to three event types to better describe your event to your audience + + Coauthors Select coauthors for your event From 646db53eca32963657c538df7a8bd6d17acb3669 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 18:29:22 +0100 Subject: [PATCH 12/18] feat(EventTypeOverlay): Make sure that max event types is 3 --- .../unio/ui/event/overlay/EventTypeOverlay.kt | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index c83d18c41..a54c13efd 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -21,6 +21,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -44,6 +45,9 @@ fun EventTypeOverlay( val context = LocalContext.current val scrollState = rememberScrollState() val copiedTypes = types.toList().map { it.first to mutableStateOf(it.second.value) } + val isError = remember { + mutableStateOf(false) + } Dialog( onDismissRequest = onDismiss, @@ -78,7 +82,11 @@ fun EventTypeOverlay( copiedTypes.forEachIndexed { index, pair -> // The row for each interest - EventTypeOverlayRow(pair) + EventTypeOverlayRow(pair, + onChange = { + isError.value = copiedTypes.count({ it.second.value }) > 3 + println(isError) + }) if (index != copiedTypes.size - 1) { HorizontalDivider( @@ -104,11 +112,16 @@ fun EventTypeOverlay( } Button( - onClick = { onSave(copiedTypes) }, + onClick = { + onSave(copiedTypes) + }, + enabled = !isError.value, modifier = - Modifier.padding(5.dp) + Modifier + .padding(5.dp) .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { - Text(context.getString(R.string.overlay_save)) + if(!isError.value) + Text(context.getString(R.string.overlay_save)) } } } @@ -119,6 +132,7 @@ fun EventTypeOverlay( @Composable private fun EventTypeOverlayRow( pair: Pair>, + onChange: () -> Unit ) { Row( horizontalArrangement = Arrangement.SpaceBetween, @@ -127,16 +141,21 @@ private fun EventTypeOverlayRow( Modifier.padding(5.dp) .fillMaxWidth() .testTag(EventTypeOverlayTestTags.CLICKABLE_ROW + pair.first.name) - .clickable { pair.second.value = !pair.second.value }) { + .clickable { + pair.second.value = !pair.second.value + onChange() + }) { Text( text = pair.first.name, style = AppTypography.bodyMedium, modifier = - Modifier.padding(start = 5.dp) + Modifier + .padding(start = 5.dp) .testTag(EventTypeOverlayTestTags.TEXT + pair.first.name)) Checkbox( checked = pair.second.value, - onCheckedChange = { pair.second.value = it }, + onCheckedChange = { pair.second.value = it + onChange() }, modifier = Modifier.testTag(EventTypeOverlayTestTags.CHECK_BOX + pair.first.name)) } } From fe53358903328493f75c843de7a75d276aa1adf7 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 18:30:55 +0100 Subject: [PATCH 13/18] style(All): ktfmt --- .../com/android/unio/model/event/Event.kt | 33 ++-- .../unio/ui/components/EventEditComponents.kt | 81 ++++----- .../android/unio/ui/event/EventCreation.kt | 67 +++---- .../com/android/unio/ui/event/EventEdit.kt | 56 +++--- .../unio/ui/event/overlay/EventTypeOverlay.kt | 164 +++++++++--------- .../java/com/android/unio/ui/theme/Color.kt | 2 +- 6 files changed, 189 insertions(+), 214 deletions(-) diff --git a/app/src/main/java/com/android/unio/model/event/Event.kt b/app/src/main/java/com/android/unio/model/event/Event.kt index 4893b2321..2741fbb94 100644 --- a/app/src/main/java/com/android/unio/model/event/Event.kt +++ b/app/src/main/java/com/android/unio/model/event/Event.kt @@ -6,12 +6,12 @@ import androidx.appsearch.annotation.Document.Namespace import androidx.appsearch.annotation.Document.StringProperty import androidx.appsearch.app.AppSearchSchema.StringPropertyConfig import androidx.compose.ui.graphics.Color +import com.android.unio.R import com.android.unio.model.association.Association import com.android.unio.model.firestore.ReferenceList import com.android.unio.model.firestore.UniquelyIdentifiable import com.android.unio.model.map.Location import com.android.unio.ui.theme.EventColors -import com.android.unio.R import com.google.firebase.Timestamp import java.util.Date @@ -82,19 +82,26 @@ enum class EventType(val color: Color, val text: Int) { JAM(EventColors.Jam, R.string.event_type_jam), // + Music and Art NETWORKING(EventColors.Networking, R.string.event_type_networking), // + Apéro and Networking SPORT_TOURNAMENT(EventColors.SportTournament, R.string.event_type_sport_tournament), // + Sports - SPORT_DISCOVERY(EventColors.SportDiscovery, R.string.event_type_sport_discovery), // + Sports, Socialising + SPORT_DISCOVERY( + EventColors.SportDiscovery, R.string.event_type_sport_discovery), // + Sports, Socialising TRIP(EventColors.Trip, R.string.event_type_trip), // + Travel, Culture - LAN(EventColors.Lan, R.string.event_type_lan), // + Gaming - FILM_PROJECTION(EventColors.FilmProjection, R.string.event_type_film_projection), // + Art, Culture - FOREIGN_CULTURE_DISCOVERY(EventColors.ForeignCultureDiscovery, R.string.event_type_foreign_culture_discovery), // + Culture, Literature - TECH_PRESENTATION(EventColors.TechPresentation, R.string.event_type_tech_presentation), // + Tech, Science - SCIENCE_FARE(EventColors.ScienceFare, R.string.event_type_science_fare), // + Science, Tech - FOOD_DISTRIBUTION(EventColors.FoodDistribution, R.string.event_type_food_distribuition), // + Food - ART_CONVENTION(EventColors.ArtConvention, R.string.event_type_art_convention), // + Art, Literature - MANIFESTATION(EventColors.Manifestation, R.string.event_type_manifestation), // + Culture, Socialising - BOARD_GAMES(EventColors.BoardGames, R.string.event_type_board_games), // + Gaming, Socialising - GROUP_STUDY(EventColors.GroupStudy, R.string.event_type_group_study), // + Science, Tech - OTHER(EventColors.Other, R.string.event_type_other) + LAN(EventColors.Lan, R.string.event_type_lan), // + Gaming + FILM_PROJECTION( + EventColors.FilmProjection, R.string.event_type_film_projection), // + Art, Culture + FOREIGN_CULTURE_DISCOVERY( + EventColors.ForeignCultureDiscovery, + R.string.event_type_foreign_culture_discovery), // + Culture, Literature + TECH_PRESENTATION( + EventColors.TechPresentation, R.string.event_type_tech_presentation), // + Tech, Science + SCIENCE_FARE(EventColors.ScienceFare, R.string.event_type_science_fare), // + Science, Tech + FOOD_DISTRIBUTION(EventColors.FoodDistribution, R.string.event_type_food_distribuition), // + Food + ART_CONVENTION( + EventColors.ArtConvention, R.string.event_type_art_convention), // + Art, Literature + MANIFESTATION( + EventColors.Manifestation, R.string.event_type_manifestation), // + Culture, Socialising + BOARD_GAMES(EventColors.BoardGames, R.string.event_type_board_games), // + Gaming, Socialising + GROUP_STUDY(EventColors.GroupStudy, R.string.event_type_group_study), // + Science, Tech + OTHER(EventColors.Other, R.string.event_type_other) } /** diff --git a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt index 83964321d..7f465bf88 100644 --- a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt +++ b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt @@ -174,26 +174,25 @@ fun NominatimLocationPicker( fun Chips( items: List>>, getName: (T) -> String, -){ - val context = LocalContext.current - - FlowRow { - items.forEach { (item, selected) -> - if (selected.value) { - InputChip( - label = { Text(getName(item)) }, - onClick = {}, - selected = selected.value, - avatar = { - Icon( - Icons.Default.Close, - contentDescription = context.getString(R.string.associations_overlay_remove), - modifier = Modifier.clickable { selected.value = !selected.value }) - }) - } +) { + val context = LocalContext.current - } + FlowRow { + items.forEach { (item, selected) -> + if (selected.value) { + InputChip( + label = { Text(getName(item)) }, + onClick = {}, + selected = selected.value, + avatar = { + Icon( + Icons.Default.Close, + contentDescription = context.getString(R.string.associations_overlay_remove), + modifier = Modifier.clickable { selected.value = !selected.value }) + }) + } } + } } /** @@ -269,20 +268,17 @@ fun DateAndTimePicker( ) { OutlinedTextField( modifier = - Modifier - .testTag(dateFieldTestTag) - .weight(1f) - .pointerInput(Unit) { - awaitEachGesture { - // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput - // in the Initial pass to observe events before the text field consumes them - // in the Main pass. - awaitFirstDown(pass = PointerEventPass.Initial) - val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) - if (upEvent != null) { - isDatePickerVisible = true - } + Modifier.testTag(dateFieldTestTag).weight(1f).pointerInput(Unit) { + awaitEachGesture { + // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput + // in the Initial pass to observe events before the text field consumes them + // in the Main pass. + awaitFirstDown(pass = PointerEventPass.Initial) + val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) + if (upEvent != null) { + isDatePickerVisible = true } + } }, value = selectedDate?.let { convertMillisToDate(it) } @@ -306,20 +302,17 @@ fun DateAndTimePicker( Spacer(modifier = Modifier.weight(0.05f)) OutlinedTextField( modifier = - Modifier - .testTag(timeFieldTestTag) - .weight(1f) - .pointerInput(Unit) { - awaitEachGesture { - // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput - // in the Initial pass to observe events before the text field consumes them - // in the Main pass. - awaitFirstDown(pass = PointerEventPass.Initial) - val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) - if (upEvent != null) { - isTimePickerVisible = true - } + Modifier.testTag(timeFieldTestTag).weight(1f).pointerInput(Unit) { + awaitEachGesture { + // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput + // in the Initial pass to observe events before the text field consumes them + // in the Main pass. + awaitFirstDown(pass = PointerEventPass.Initial) + val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) + if (upEvent != null) { + isTimePickerVisible = true } + } }, value = selectedTime?.let { convertMillisToTime(it) } diff --git a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt index 154d05c03..8363e0d37 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventCreation.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventCreation.kt @@ -80,17 +80,17 @@ fun EventCreationScreen( val scrollState = rememberScrollState() var showCoauthorsOverlay by remember { mutableStateOf(false) } var showTaggedOverlay by remember { mutableStateOf(false) } - var showEventTypeOverlay by remember { mutableStateOf(false) } + var showEventTypeOverlay by remember { mutableStateOf(false) } var name by remember { mutableStateOf("") } var shortDescription by remember { mutableStateOf("") } var longDescription by remember { mutableStateOf("") } - val eventTypeFlow = remember { - MutableStateFlow(EventType.entries.map { it to mutableStateOf(false) }.toList()) - } + val eventTypeFlow = remember { + MutableStateFlow(EventType.entries.map { it to mutableStateOf(false) }.toList()) + } - val types by eventTypeFlow.collectAsState() + val types by eventTypeFlow.collectAsState() var coauthorsAndBoolean = associationViewModel.associations.collectAsState().value.map { it to mutableStateOf(false) } @@ -202,10 +202,7 @@ fun EventCreationScreen( Text(context.getString(R.string.event_creation_coauthors_label)) } - Chips( - coauthorsAndBoolean, - getName = { it.name } - ) + Chips(coauthorsAndBoolean, getName = { it.name }) OutlinedButton( modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.TAGGED_ASSOCIATIONS), @@ -217,28 +214,19 @@ fun EventCreationScreen( Text(context.getString(R.string.event_creation_tagged_label)) } - Chips( - taggedAndBoolean, - getName = { it.name } - ) - - OutlinedButton( - modifier = Modifier - .fillMaxWidth() - .testTag(EventCreationTestTags.EVENT_TYPE), - onClick = { showEventTypeOverlay = true } - ) { - Icon( - Icons.Default.Add, - contentDescription = - context.getString(R.string.social_overlay_content_description_add)) - Text(context.getString(R.string.event_creation_type)) - } + Chips(taggedAndBoolean, getName = { it.name }) + + OutlinedButton( + modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.EVENT_TYPE), + onClick = { showEventTypeOverlay = true }) { + Icon( + Icons.Default.Add, + contentDescription = + context.getString(R.string.social_overlay_content_description_add)) + Text(context.getString(R.string.event_creation_type)) + } - Chips( - types, - getName = { context.getString(it.text) } - ) + Chips(types, getName = { context.getString(it.text) }) OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventCreationTestTags.DESCRIPTION), @@ -404,15 +392,14 @@ fun EventCreationScreen( bodyText = context.getString(R.string.associations_overlay_tagged_description)) } - if(showEventTypeOverlay) { - EventTypeOverlay( - onDismiss = { showEventTypeOverlay = false }, - onSave = { types -> - eventTypeFlow.value = types - showEventTypeOverlay = false - }, - types = types - ) - } + if (showEventTypeOverlay) { + EventTypeOverlay( + onDismiss = { showEventTypeOverlay = false }, + onSave = { types -> + eventTypeFlow.value = types + showEventTypeOverlay = false + }, + types = types) + } } } diff --git a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt index a623a84ef..a32a9a86c 100644 --- a/app/src/main/java/com/android/unio/ui/event/EventEdit.kt +++ b/app/src/main/java/com/android/unio/ui/event/EventEdit.kt @@ -83,7 +83,7 @@ fun EventEditScreen( val scrollState = rememberScrollState() var showCoauthorsOverlay by remember { mutableStateOf(false) } var showTaggedOverlay by remember { mutableStateOf(false) } - var showEventTypeOverlay by remember { mutableStateOf(false) } + var showEventTypeOverlay by remember { mutableStateOf(false) } val eventToEdit = remember { eventViewModel.selectedEvent.value!! } @@ -91,11 +91,11 @@ fun EventEditScreen( var shortDescription by remember { mutableStateOf(eventToEdit.catchyDescription.trim()) } var longDescription by remember { mutableStateOf(eventToEdit.description.trim()) } - val eventTypeFlow = remember { - MutableStateFlow(EventType.entries.map { it to mutableStateOf(eventToEdit.types.contains(it)) }) - } + val eventTypeFlow = remember { + MutableStateFlow(EventType.entries.map { it to mutableStateOf(eventToEdit.types.contains(it)) }) + } - val types by eventTypeFlow.collectAsState() + val types by eventTypeFlow.collectAsState() var coauthorsAndBoolean = associationViewModel.associations.collectAsState().value.map { @@ -203,24 +203,17 @@ fun EventEditScreen( getName = { it.name }, ) - OutlinedButton( - modifier = Modifier - .fillMaxWidth() - .testTag(EventEditTestTags.EVENT_TYPE), - onClick = { showEventTypeOverlay = true } - ) { - Icon( - Icons.Default.Add, - contentDescription = - context.getString(R.string.social_overlay_content_description_add)) - Text(context.getString(R.string.event_edit_type)) - } - - Chips( - types, - getName = { context.getString(it.text) } - ) + OutlinedButton( + modifier = Modifier.fillMaxWidth().testTag(EventEditTestTags.EVENT_TYPE), + onClick = { showEventTypeOverlay = true }) { + Icon( + Icons.Default.Add, + contentDescription = + context.getString(R.string.social_overlay_content_description_add)) + Text(context.getString(R.string.event_edit_type)) + } + Chips(types, getName = { context.getString(it.text) }) OutlinedTextField( modifier = Modifier.fillMaxWidth().testTag(EventEditTestTags.DESCRIPTION), @@ -410,15 +403,14 @@ fun EventEditScreen( } } - if(showEventTypeOverlay){ - EventTypeOverlay( - onDismiss = { showEventTypeOverlay = false }, - onSave = { types -> - eventTypeFlow.value = types - showEventTypeOverlay = false - }, - types = types - ) - } + if (showEventTypeOverlay) { + EventTypeOverlay( + onDismiss = { showEventTypeOverlay = false }, + onSave = { types -> + eventTypeFlow.value = types + showEventTypeOverlay = false + }, + types = types) + } } } diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index a54c13efd..b0f6a5fad 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -35,98 +35,93 @@ import com.android.unio.model.event.EventType import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags import com.android.unio.ui.theme.AppTypography - @Composable fun EventTypeOverlay( onDismiss: () -> Unit, onSave: (List>>) -> Unit, types: List>> ) { - val context = LocalContext.current - val scrollState = rememberScrollState() - val copiedTypes = types.toList().map { it.first to mutableStateOf(it.second.value) } - val isError = remember { - mutableStateOf(false) - } + val context = LocalContext.current + val scrollState = rememberScrollState() + val copiedTypes = types.toList().map { it.first to mutableStateOf(it.second.value) } + val isError = remember { mutableStateOf(false) } - Dialog( - onDismissRequest = onDismiss, - properties = DialogProperties(usePlatformDefaultWidth = false)) { + Dialog( + onDismissRequest = onDismiss, + properties = DialogProperties(usePlatformDefaultWidth = false)) { Card( elevation = CardDefaults.cardElevation(8.dp), shape = RoundedCornerShape(16.dp), modifier = - Modifier.fillMaxWidth().padding(20.dp).testTag(EventTypeOverlayTestTags.CARD)) { - Column( - modifier = - Modifier.fillMaxWidth() - .padding(15.dp) - .sizeIn(maxHeight = 400.dp) - .testTag(EventTypeOverlayTestTags.COLUMN), - verticalArrangement = Arrangement.SpaceBetween) { + Modifier.fillMaxWidth().padding(20.dp).testTag(EventTypeOverlayTestTags.CARD)) { + Column( + modifier = + Modifier.fillMaxWidth() + .padding(15.dp) + .sizeIn(maxHeight = 400.dp) + .testTag(EventTypeOverlayTestTags.COLUMN), + verticalArrangement = Arrangement.SpaceBetween) { - // Text fields for the title and description of the Interest Overlay - Text( - text = context.getString(R.string.event_type_overlay_title), - style = AppTypography.headlineSmall, - modifier = Modifier.testTag(EventTypeOverlayTestTags.TITLE_TEXT)) - Text( - text = context.getString(R.string.event_type_overlay_description), - style = AppTypography.bodyMedium, - modifier = - Modifier.padding(bottom = 5.dp) - .testTag(EventTypeOverlayTestTags.SUBTITLE_TEXT)) - Surface( - modifier = Modifier.sizeIn(maxHeight = 250.dp), color = Color.Transparent) { - Column(modifier = Modifier.verticalScroll(scrollState)) { - copiedTypes.forEachIndexed { index, pair -> + // Text fields for the title and description of the Interest Overlay + Text( + text = context.getString(R.string.event_type_overlay_title), + style = AppTypography.headlineSmall, + modifier = Modifier.testTag(EventTypeOverlayTestTags.TITLE_TEXT)) + Text( + text = context.getString(R.string.event_type_overlay_description), + style = AppTypography.bodyMedium, + modifier = + Modifier.padding(bottom = 5.dp) + .testTag(EventTypeOverlayTestTags.SUBTITLE_TEXT)) + Surface( + modifier = Modifier.sizeIn(maxHeight = 250.dp), color = Color.Transparent) { + Column(modifier = Modifier.verticalScroll(scrollState)) { + copiedTypes.forEachIndexed { index, pair -> - // The row for each interest - EventTypeOverlayRow(pair, - onChange = { + // The row for each interest + EventTypeOverlayRow( + pair, + onChange = { isError.value = copiedTypes.count({ it.second.value }) > 3 println(isError) - }) + }) - if (index != copiedTypes.size - 1) { + if (index != copiedTypes.size - 1) { HorizontalDivider( modifier = - Modifier.testTag(EventTypeOverlayTestTags.DIVIDER + "$index")) + Modifier.testTag( + EventTypeOverlayTestTags.DIVIDER + "$index")) + } } + } } - } - } - // Buttons for saving and cancelling the changes - Row( - modifier = Modifier.fillMaxWidth().padding(8.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Absolute.Right) { - OutlinedButton( - shape = RoundedCornerShape(16.dp), - onClick = onDismiss, - modifier = - Modifier.padding(5.dp) - .testTag(EventTypeOverlayTestTags.CANCEL_BUTTON)) { - Text(context.getString(R.string.overlay_cancel)) - } + // Buttons for saving and cancelling the changes + Row( + modifier = Modifier.fillMaxWidth().padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Absolute.Right) { + OutlinedButton( + shape = RoundedCornerShape(16.dp), + onClick = onDismiss, + modifier = + Modifier.padding(5.dp) + .testTag(EventTypeOverlayTestTags.CANCEL_BUTTON)) { + Text(context.getString(R.string.overlay_cancel)) + } - Button( - onClick = { - onSave(copiedTypes) - }, - enabled = !isError.value, - modifier = - Modifier - .padding(5.dp) - .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { - if(!isError.value) - Text(context.getString(R.string.overlay_save)) - } - } + Button( + onClick = { onSave(copiedTypes) }, + enabled = !isError.value, + modifier = + Modifier.padding(5.dp) + .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { + if (!isError.value) Text(context.getString(R.string.overlay_save)) + } + } + } } - } - } + } } @Composable @@ -134,28 +129,29 @@ private fun EventTypeOverlayRow( pair: Pair>, onChange: () -> Unit ) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - modifier = - Modifier.padding(5.dp) - .fillMaxWidth() - .testTag(EventTypeOverlayTestTags.CLICKABLE_ROW + pair.first.name) - .clickable { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = + Modifier.padding(5.dp) + .fillMaxWidth() + .testTag(EventTypeOverlayTestTags.CLICKABLE_ROW + pair.first.name) + .clickable { pair.second.value = !pair.second.value onChange() - }) { + }) { Text( text = pair.first.name, style = AppTypography.bodyMedium, modifier = - Modifier - .padding(start = 5.dp) - .testTag(EventTypeOverlayTestTags.TEXT + pair.first.name)) + Modifier.padding(start = 5.dp) + .testTag(EventTypeOverlayTestTags.TEXT + pair.first.name)) Checkbox( checked = pair.second.value, - onCheckedChange = { pair.second.value = it - onChange() }, + onCheckedChange = { + pair.second.value = it + onChange() + }, modifier = Modifier.testTag(EventTypeOverlayTestTags.CHECK_BOX + pair.first.name)) - } + } } diff --git a/app/src/main/java/com/android/unio/ui/theme/Color.kt b/app/src/main/java/com/android/unio/ui/theme/Color.kt index 399052745..9db6239ca 100644 --- a/app/src/main/java/com/android/unio/ui/theme/Color.kt +++ b/app/src/main/java/com/android/unio/ui/theme/Color.kt @@ -219,7 +219,7 @@ val surfaceContainerDarkHighContrast = Color(0xFF1F1F25) val surfaceContainerHighDarkHighContrast = Color(0xFF2A292F) val surfaceContainerHighestDarkHighContrast = Color(0xFF35343A) -object EventColors{ +object EventColors { val Festival = Color(0xFF6200EE) // Purple val Aperitif = Color(0xFF03DAC5) // Teal val NightParty = Color(0xFFFF5722) // Deep Orange From 23f73b23baf73ed1d6bd8a439724a694a6ae28f1 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 19:13:00 +0100 Subject: [PATCH 14/18] test(EventCreation/Edition): Add corresponding tests --- .../unio/components/event/EventCardTest.kt | 5 +- .../components/event/EventCreationTest.kt | 58 ++++++++++++++++++- .../unio/components/event/EventEditTests.kt | 55 ++++++++++++++++++ 3 files changed, 114 insertions(+), 4 deletions(-) diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt b/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt index dc87a517e..3ebbee4d5 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt @@ -17,7 +17,6 @@ import com.android.unio.mocks.user.MockUser import com.android.unio.model.association.AssociationRepositoryFirestore import com.android.unio.model.event.Event import com.android.unio.model.event.EventRepositoryFirestore -import com.android.unio.model.event.EventType import com.android.unio.model.event.EventUserPictureRepositoryFirestore import com.android.unio.model.event.EventViewModel import com.android.unio.model.image.ImageRepositoryFirebaseStorage @@ -41,12 +40,12 @@ import io.mockk.mockkObject import io.mockk.runs import io.mockk.spyk import io.mockk.verify -import java.util.Date import me.zhanghai.compose.preference.ProvidePreferenceLocals import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test +import java.util.Date class EventCardTest : TearDown() { @@ -142,7 +141,7 @@ class EventCardTest : TearDown() { composeTestRule .onNodeWithTag(EventCardTestTags.EVENT_MAIN_TYPE, useUnmergedTree = true) .assertExists() - .assertTextEquals(EventType.TRIP.text) + .assertTextEquals("Trip") composeTestRule .onNodeWithTag(EventCardTestTags.EVENT_LOCATION, useUnmergedTree = true) diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt b/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt index fa43c131e..10a60727b 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt @@ -1,6 +1,7 @@ package com.android.unio.components.event import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.isDisplayed import androidx.compose.ui.test.junit4.createComposeRule @@ -30,6 +31,8 @@ import com.android.unio.model.search.SearchViewModel import com.android.unio.model.strings.TextLengthSamples import com.android.unio.model.strings.test_tags.event.EventCreationOverlayTestTags import com.android.unio.model.strings.test_tags.event.EventCreationTestTags +import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags +import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags import com.android.unio.model.usecase.FollowUseCaseFirestore import com.android.unio.model.usecase.SaveUseCaseFirestore import com.android.unio.ui.event.EventCreationScreen @@ -45,7 +48,6 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockkStatic import io.mockk.spyk -import java.net.HttpURLConnection import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.Before @@ -53,6 +55,7 @@ import org.junit.Rule import org.junit.Test import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory +import java.net.HttpURLConnection @HiltAndroidTest class EventCreationTest : TearDown() { @@ -281,6 +284,59 @@ class EventCreationTest : TearDown() { composeTestRule.onNodeWithTag(EventCreationTestTags.DESCRIPTION).performTextClearance() } + @Test + fun testCorrectlyAddEvenTypes(){ + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventCreationScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } + + composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() + + composeTestRule.onNodeWithTag(EventCreationTestTags.SCREEN).assertIsDisplayed() + + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() + } + + @Test + fun testNotPossibleToAddMoreThan3EventTypes(){ + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventCreationScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } + + composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "JAM").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "TRIP").performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() + } + @Test fun testLocationInputFunctionality() { server = MockWebServer() diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt b/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt index 10aa61e0d..562f8cfa9 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt @@ -25,7 +25,9 @@ import com.android.unio.model.map.nominatim.NominatimLocationRepository import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel import com.android.unio.model.search.SearchRepository import com.android.unio.model.search.SearchViewModel +import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags import com.android.unio.model.strings.test_tags.event.EventEditTestTags +import com.android.unio.model.strings.test_tags.event.EventTypeOverlayTestTags import com.android.unio.model.usecase.FollowUseCaseFirestore import com.android.unio.model.usecase.SaveUseCaseFirestore import com.android.unio.ui.event.EventEditScreen @@ -227,6 +229,59 @@ class EventEditTests : TearDown() { composeTestRule.waitForIdle() } + @Test + fun testCorrectlyAddEvenTypes(){ + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventEditScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } + + composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() + + composeTestRule.onNodeWithTag(EventEditTestTags.SCREEN).assertIsDisplayed() + + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() + } + + @Test + fun testNotPossibleToAddMoreThan3EventTypes(){ + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventEditScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } + + composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "LAN").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FOOD_DISTRIBUTION").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "MANIFESTATION").performScrollTo().performClick() + + + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() + } + @Test fun testDeleteButtonWorksCorrectly() { nominatimLocationSearchViewModel = From 092df88be646f1fed6de15ed6df0c87e38d8e820 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 19:15:08 +0100 Subject: [PATCH 15/18] chore(EventEditComponents): Add necessary test tags --- .../android/unio/model/strings/test_tags/event/EventTestTags.kt | 1 + .../java/com/android/unio/ui/components/EventEditComponents.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt index cbdbac15b..3e8529882 100644 --- a/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt +++ b/app/src/main/java/com/android/unio/model/strings/test_tags/event/EventTestTags.kt @@ -116,6 +116,7 @@ object EventDetailsTestTags { const val EVENT_PICTURES_ARROW_LEFT = "picturesArrowLeft" const val EVENT_PICTURES_ARROW_RIGHT = "picturesArrowRight" const val PICTURE_FULL_SCREEN = "pictureFullScreen" + const val CHIPS = "eventChips" } object EventTypeOverlayTestTags { diff --git a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt index 7f465bf88..020f9be0b 100644 --- a/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt +++ b/app/src/main/java/com/android/unio/ui/components/EventEditComponents.kt @@ -61,6 +61,7 @@ import com.android.unio.model.map.Location import com.android.unio.model.map.nominatim.NominatimLocationSearchViewModel import com.android.unio.model.strings.FormatStrings.DAY_MONTH_YEAR_FORMAT import com.android.unio.model.strings.FormatStrings.HOUR_MINUTE_FORMAT +import com.android.unio.model.strings.test_tags.event.EventDetailsTestTags import com.android.unio.ui.image.AsyncImageWrapper import com.android.unio.ui.utils.ToastUtils import com.google.firebase.Timestamp @@ -184,6 +185,7 @@ fun Chips( label = { Text(getName(item)) }, onClick = {}, selected = selected.value, + modifier = Modifier.testTag(EventDetailsTestTags.CHIPS + getName(item)), avatar = { Icon( Icons.Default.Close, From c6da95e3ae250469fb3241064f5879f823f54988 Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 19:15:21 +0100 Subject: [PATCH 16/18] style(All): ktfmt --- .../unio/components/event/EventCardTest.kt | 2 +- .../components/event/EventCreationTest.kt | 102 ++++++++++-------- .../unio/components/event/EventEditTests.kt | 96 ++++++++++------- .../unio/ui/event/overlay/EventTypeOverlay.kt | 2 +- 4 files changed, 117 insertions(+), 85 deletions(-) diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt b/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt index 3ebbee4d5..5d91cda88 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventCardTest.kt @@ -40,12 +40,12 @@ import io.mockk.mockkObject import io.mockk.runs import io.mockk.spyk import io.mockk.verify +import java.util.Date import me.zhanghai.compose.preference.ProvidePreferenceLocals import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test -import java.util.Date class EventCardTest : TearDown() { diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt b/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt index 10a60727b..6ee080aff 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventCreationTest.kt @@ -48,6 +48,7 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockkStatic import io.mockk.spyk +import java.net.HttpURLConnection import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import org.junit.Before @@ -55,7 +56,6 @@ import org.junit.Rule import org.junit.Test import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory -import java.net.HttpURLConnection @HiltAndroidTest class EventCreationTest : TearDown() { @@ -284,58 +284,76 @@ class EventCreationTest : TearDown() { composeTestRule.onNodeWithTag(EventCreationTestTags.DESCRIPTION).performTextClearance() } - @Test - fun testCorrectlyAddEvenTypes(){ - nominatimLocationSearchViewModel = - NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) - composeTestRule.setContent { - EventCreationScreen( - navigationAction, - searchViewModel, - associationViewModel, - eventViewModel, - nominatimLocationSearchViewModel) - } + @Test + fun testCorrectlyAddEvenTypes() { + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventCreationScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } - composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF") + .performScrollTo() + .performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() - composeTestRule.onNodeWithTag(EventCreationTestTags.SCREEN).assertIsDisplayed() + composeTestRule.onNodeWithTag(EventCreationTestTags.SCREEN).assertIsDisplayed() - composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() - composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() - } + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() + } - @Test - fun testNotPossibleToAddMoreThan3EventTypes(){ - nominatimLocationSearchViewModel = - NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) - composeTestRule.setContent { - EventCreationScreen( - navigationAction, - searchViewModel, - associationViewModel, - eventViewModel, - nominatimLocationSearchViewModel) - } + @Test + fun testNotPossibleToAddMoreThan3EventTypes() { + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventCreationScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } - composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventCreationTestTags.EVENT_TYPE).performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "JAM").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "TRIP").performScrollTo().performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "JAM") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "TRIP") + .performScrollTo() + .performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() - } + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() + } @Test fun testLocationInputFunctionality() { diff --git a/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt b/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt index 562f8cfa9..293e043d7 100644 --- a/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt +++ b/app/src/androidTest/java/com/android/unio/components/event/EventEditTests.kt @@ -229,58 +229,72 @@ class EventEditTests : TearDown() { composeTestRule.waitForIdle() } - @Test - fun testCorrectlyAddEvenTypes(){ - nominatimLocationSearchViewModel = - NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) - composeTestRule.setContent { - EventEditScreen( - navigationAction, - searchViewModel, - associationViewModel, - eventViewModel, - nominatimLocationSearchViewModel) - } - - composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() + @Test + fun testCorrectlyAddEvenTypes() { + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventEditScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FESTIVAL") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "APERITIF") + .performScrollTo() + .performClick() - composeTestRule.onNodeWithTag(EventEditTestTags.SCREEN).assertIsDisplayed() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).performClick() - composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() - composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() - } + composeTestRule.onNodeWithTag(EventEditTestTags.SCREEN).assertIsDisplayed() - @Test - fun testNotPossibleToAddMoreThan3EventTypes(){ - nominatimLocationSearchViewModel = - NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) - composeTestRule.setContent { - EventEditScreen( - navigationAction, - searchViewModel, - associationViewModel, - eventViewModel, - nominatimLocationSearchViewModel) - } + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Festival").assertExists() + composeTestRule.onNodeWithTag(EventDetailsTestTags.CHIPS + "Aperitif").assertExists() + } - composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() + @Test + fun testNotPossibleToAddMoreThan3EventTypes() { + nominatimLocationSearchViewModel = + NominatimLocationSearchViewModel(nominatimLocationRepositoryWithoutFunctionality) + composeTestRule.setContent { + EventEditScreen( + navigationAction, + searchViewModel, + associationViewModel, + eventViewModel, + nominatimLocationSearchViewModel) + } - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + composeTestRule.onNodeWithTag(EventEditTestTags.EVENT_TYPE).performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "LAN").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FOOD_DISTRIBUTION").performScrollTo().performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "MANIFESTATION").performScrollTo().performClick() + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.CARD).assertExists() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "LAN") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "FOOD_DISTRIBUTION") + .performScrollTo() + .performClick() + composeTestRule + .onNodeWithTag(EventTypeOverlayTestTags.CLICKABLE_ROW + "MANIFESTATION") + .performScrollTo() + .performClick() - composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() - } + composeTestRule.onNodeWithTag(EventTypeOverlayTestTags.SAVE_BUTTON).assertIsNotEnabled() + } @Test fun testDeleteButtonWorksCorrectly() { diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index b0f6a5fad..c431fce73 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -116,7 +116,7 @@ fun EventTypeOverlay( modifier = Modifier.padding(5.dp) .testTag(EventTypeOverlayTestTags.SAVE_BUTTON)) { - if (!isError.value) Text(context.getString(R.string.overlay_save)) + Text(context.getString(R.string.overlay_save)) } } } From 9fb429691daf3619a23e8a224a79c445ed2df7db Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 20:12:37 +0100 Subject: [PATCH 17/18] fix(UnitTests): Add default list (empty) for types field --- .../unio/model/firestore/HydrationAndSerializationTest.kt | 1 + .../java/com/android/unio/model/search/SearchRepositoryTest.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/src/test/java/com/android/unio/model/firestore/HydrationAndSerializationTest.kt b/app/src/test/java/com/android/unio/model/firestore/HydrationAndSerializationTest.kt index 2cb6076a6..22905de75 100644 --- a/app/src/test/java/com/android/unio/model/firestore/HydrationAndSerializationTest.kt +++ b/app/src/test/java/com/android/unio/model/firestore/HydrationAndSerializationTest.kt @@ -83,6 +83,7 @@ class HydrationAndSerializationTest { location = Location(latitude = 0.0, longitude = 0.0, name = "Example Location"), maxNumberOfPlaces = -1, numberOfSaved = 3, + types = emptyList(), eventPictures = EventUserPicture.emptyFirestoreReferenceList()) /** Round-trip tests for serialization and hydration of user, association, and event instances. */ diff --git a/app/src/test/java/com/android/unio/model/search/SearchRepositoryTest.kt b/app/src/test/java/com/android/unio/model/search/SearchRepositoryTest.kt index 6076efe4e..1b307d500 100644 --- a/app/src/test/java/com/android/unio/model/search/SearchRepositoryTest.kt +++ b/app/src/test/java/com/android/unio/model/search/SearchRepositoryTest.kt @@ -124,6 +124,7 @@ class SearchRepositoryTest { startDate = Timestamp(GregorianCalendar(2004, 7, 1).time), location = Location(1.2345, 2.3455, "Somewhere"), maxNumberOfPlaces = -1, + types = emptyList(), eventPictures = EventUserPicture.emptyFirestoreReferenceList()) private val event2 = Event( @@ -137,6 +138,7 @@ class SearchRepositoryTest { startDate = Timestamp(GregorianCalendar(2008, 7, 1).time), location = Location(1.2345, 2.3455, "Somewhere"), maxNumberOfPlaces = -1, + types = emptyList(), eventPictures = EventUserPicture.emptyFirestoreReferenceList()) @Before From 57605b7d6214e454b42a114d7e7149322083ef2d Mon Sep 17 00:00:00 2001 From: Alexei Thornber Date: Wed, 18 Dec 2024 20:39:45 +0100 Subject: [PATCH 18/18] fix(EventTypeOverlay): remove unnecessary print --- .../java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt index c431fce73..e4c247118 100644 --- a/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt +++ b/app/src/main/java/com/android/unio/ui/event/overlay/EventTypeOverlay.kt @@ -83,7 +83,6 @@ fun EventTypeOverlay( pair, onChange = { isError.value = copiedTypes.count({ it.second.value }) > 3 - println(isError) }) if (index != copiedTypes.size - 1) {