Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/filter by associations #368

Merged
merged 7 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ private fun Content(
// online status for disabling the buttons
val isOnline by homeScreenViewModel.isOnline.collectAsState()

// followed associations for the search menu
val followedAssociations by homeScreenViewModel.followedAssociations.collectAsState()
val selectedAssociation by homeScreenViewModel.selectedAssociation.collectAsState()

Box(modifier = Modifier.padding(paddingValues)) {
// Display the list view or the map view
if (mode == MapOrListMode.LIST) {
Expand All @@ -142,7 +146,7 @@ private fun Content(
TagUI(
tags = tags,
selectedTagIds = selectedTagIds,
leftPadding = 8.dp,
leftPadding = 14.dp,
onTagClick = homeScreenViewModel::onFollowedTagClicked
)
}
Expand Down Expand Up @@ -202,7 +206,10 @@ private fun Content(
resetFiltersCallback = homeScreenViewModel::resetFiltersContainer,
timeFilterCallback = homeScreenViewModel::onDateFilterChanged,
initialPage = initialPage,
mode = mode
mode = mode,
followedAssociations = followedAssociations,
selectedAssociation = selectedAssociation,
associationCallback = homeScreenViewModel::onAssociationSelected
)
// {navActions.navigateTo(Routes.SearchScreen)}) <- when we make a whole screen for
// the search menu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ fun TagItem(tag: Tag, isSelected: Boolean, onClick: () -> Unit) {

FilledTonalButton(
onClick = onClick,
contentPadding = PaddingValues(0.dp),
contentPadding = PaddingValues(5.dp),
colors =
ButtonDefaults.buttonColors(
containerColor = backgroundColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ fun SearchMenuSheet(
resetFiltersCallback: () -> Unit,
timeFilterCallback: (Float, Float) -> Unit,
initialPage: Int,
mode: MapOrListMode
mode: MapOrListMode,
followedAssociations: List<String>,
selectedAssociation: Int,
associationCallback: (Int) -> Unit
) {
// Get the TagViewModel from Hilt.
val tagViewModel: TagViewModel =
Expand Down Expand Up @@ -102,7 +105,10 @@ fun SearchMenuSheet(
fullCallback,
sortByCallback,
timeFilterCallback,
mode
mode,
followedAssociations,
selectedAssociation,
associationCallback
)
},
Pair(stringResource(R.string.search_menu_sheet_discover)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ fun SearchMenuFilters(
fullCallback: () -> Unit, // Callback function when the full filter is toggled
sortByCallback: (Int) -> Unit, // Callback function when the sort by filter is changed
timeFilterCallback: (Float, Float) -> Unit, // Callback function when the time filter is changed
mode: MapOrListMode // The current display mode (map or list)
mode: MapOrListMode, // The current display mode (map or list)
followedAssociations: List<String>, // The list of followed associations
selectedAssociation: Int, // The currently selected association
associationCallback: (Int) -> Unit // Callback function when the association filter is changed
) {
// Define the items for the "Events for" filter section
val eventsForItems =
Expand Down Expand Up @@ -112,11 +115,6 @@ fun SearchMenuFilters(
}
)

// Define the list of followed associations and the currently selected association
val followedAssociations = listOf("1", "2", "3", "4", "5")
var selectedAssociation = -1
val associationCallback = { id: Int -> selectedAssociation = id }

// Define the vertical space between elements
val verticalSpacer = 8.dp

Expand All @@ -141,7 +139,7 @@ fun SearchMenuFilters(
Dropdown(
"Sort By",
SortBy.entries.map { stringResource(it.stringKey) },
filters.sortBy?.ordinal ?: -1,
filters.sortBy.ordinal,
Greenade marked this conversation as resolved.
Show resolved Hide resolved
sortByCallback
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ enum class SortBy(val stringKey: Int) {

// Threshold for the status of an event to be considered full or pending
const val STATUS_THRESHOLD = 0.5
// default value for when a dropdown is not selected
const val DEFAULT_DROPDOWN_VALUE = -1

/**
* ViewModel for the home screen. Contains the logic to display the events, filter them, and display
Expand Down Expand Up @@ -142,6 +144,12 @@ constructor(
val initialPage = _initialPage.asStateFlow()
// Flow to observe the network status
val isOnline = networkService.isOnline
// Flow to observe the followed associations
private val _followedAssociations = MutableStateFlow<List<String>>(listOf())
val followedAssociations = _followedAssociations.asStateFlow()
// Flow to observe the selected association
private val _selectedAssociation = MutableStateFlow(DEFAULT_DROPDOWN_VALUE)
val selectedAssociation = _selectedAssociation.asStateFlow()

// Initialize the view model
init {
Expand All @@ -161,10 +169,26 @@ constructor(
followedTagFilter = getTagsAndSubTags(_followedTags.value).toList()
sectionTags = repository.getSubTags(sectionTagId)
semesterTags = repository.getSubTags(semesterTagId)
val followedAssociationIds =
repository.getUserProfile(userId)?.associationsSubscriptions?.map {
it.associationId
} ?: listOf()
_followedAssociations.value =
repository.getAssociations(followedAssociationIds).map { it.name }
refreshFiltersContainer()
}
}

/**
* Change the selected association to display the events of the selected association.
*
* @param selectedAssociation the index of the selected association
*/
fun onAssociationSelected(selectedAssociation: Int) {
_selectedAssociation.value = selectedAssociation
refreshFiltersContainer()
}

/**
* change the selection of tags to display and filter the events accordingly
*
Expand Down Expand Up @@ -310,7 +334,9 @@ constructor(
* the default one, the search mode is on.
*/
private fun updateSearchMode() {
_searchMode.value = _filtersContainer.value != defaultFiltersContainer
_searchMode.value =
_filtersContainer.value != defaultFiltersContainer ||
_selectedAssociation.value != DEFAULT_DROPDOWN_VALUE
}

/**
Expand Down Expand Up @@ -366,7 +392,7 @@ constructor(
-> // filter by time to avoid displaying past events
dateFilterConditions(event)
}
} else /*if (selectedTagId.value == null)*/ {
} else {
allEventsList
.filter { event ->
event.tags.any { tag ->
Expand All @@ -376,78 +402,86 @@ constructor(
.filter { event -> // filter by time to avoid displaying past events
dateFilterConditions(event)
}
} /* else {
allEventsList
.filter { event ->
event.tags.any { tag -> tag.tagId == _selectedTagId.value!! }
}
.filter { event -> // filter by time to avoid displaying past events
dateFilterConditions(event)
}
}*/
}
} else {
_displayEventList.value =
allEventsList
.asSequence()
.filter { event -> // filter by tags, title or description
.filter { event ->
// filter by tags, title or description
_filtersContainer.value.searchEntry == "" ||
event.tags.any { tag ->
filterTagSet.any { tag2 -> tag.tagId == tag2.tagId }
} ||
areWordsInTitle(event, filterWordList) ||
areWordsInDescription(event, filterWordList)
}
.filter { event -> // filter by time
.filter { event ->
// filter by time
dateFilterConditions(event)
}
.filter { event ->
// filter by confirmed check
!_filtersContainer.value.confirmedChecked ||
event.maxParticipants <= 0 ||
(event.participantCount >= event.maxParticipants * STATUS_THRESHOLD &&
event.participantCount < event.maxParticipants)
}
.filter { event ->
// filter by pending check
!_filtersContainer.value.pendingChecked ||
event.maxParticipants <= 0 ||
event.participantCount < event.maxParticipants * STATUS_THRESHOLD
}
.filter { event ->
// filter by full check
!_filtersContainer.value.fullChecked ||
event.maxParticipants <= 0 ||
event.participantCount == event.maxParticipants
}
.filter { event ->
// filter by epfl check
!_filtersContainer.value.epflChecked ||
(!event.tags.any { tag -> sectionTags.contains(tag) } &&
!event.tags.any { tag -> semesterTags.contains(tag) })
}
.filter { event ->
// filter by section
!_filtersContainer.value.sectionChecked ||
_section.value == "" ||
event.tags.any { tag ->
tag.name.lowercase() == _section.value.lowercase()
}
}
.filter { event ->
// filter by semester
!_filtersContainer.value.classChecked ||
_semester.value == "" ||
event.tags.any { tag ->
tag.name.lowercase() == _semester.value.lowercase()
}
}
.filter { event ->
// filter by association
_selectedAssociation.value == DEFAULT_DROPDOWN_VALUE ||
event.organizer?.name ==
_followedAssociations.value[_selectedAssociation.value]
}
.sortedBy { event ->
event.startDate
// when we can sort by distance, update this
/*when (_filtersContainer.value.sortBy) {
SortBy.DATE_ASC -> event.startDate
SortBy.DATE_DESC ->
SortBy.DATE_DESC -> event.startDate
else ->
}*/
}
.toList()

// reverse the list if the sort by is descending
if (_filtersContainer.value.sortBy == SortBy.DATE_DESC) {
if (
_filtersContainer.value.sortBy == SortBy.DATE_DESC
) { // when we can filter by distance, update this too
_displayEventList.value = _displayEventList.value.reversed()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ class SearchMenuSheetTest {
resetFiltersCallback = { callback++ },
timeFilterCallback = { _, _ -> callback++ },
initialPage = 0,
mode = MapOrListMode.MAP
mode = MapOrListMode.MAP,
followedAssociations = listOf(),
selectedAssociation = -1,
associationCallback = { callback++ }
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ class SearchMenuFiltersTest {
filters.from = f
filters.to = t
},
MapOrListMode.LIST
MapOrListMode.LIST,
listOf(),
-1,
{ callback++ }
)
}
}
Expand Down