Archived
Edited canteen views to have direct database access in the CanteenPageFragment.kt, allowing for filtering the individual days through the database; filtering now works (with changes animated!!) through updating a LiveData and observing it in the page fragment
This commit is contained in:
@@ -8,11 +8,9 @@ import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.denizk0461.studip.R
|
||||
import com.denizk0461.studip.adapter.CanteenOfferItemAdapter
|
||||
import com.denizk0461.studip.adapter.CanteenOfferPageAdapter
|
||||
import com.denizk0461.studip.databinding.FragmentCanteenBinding
|
||||
import com.denizk0461.studip.model.*
|
||||
import com.denizk0461.studip.sheet.AllergenSheet
|
||||
import com.denizk0461.studip.sheet.TextSheet
|
||||
import com.denizk0461.studip.viewmodel.CanteenViewModel
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
@@ -21,7 +19,7 @@ import com.google.android.material.tabs.TabLayoutMediator
|
||||
* User-facing fragment view that displays the canteen offers from the website of the
|
||||
* Studierendenwerk Bremen.
|
||||
*/
|
||||
class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
class CanteenFragment : AppFragment() {
|
||||
|
||||
// Nullable view binding reference
|
||||
private var _binding: FragmentCanteenBinding? = null
|
||||
@@ -83,7 +81,7 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
binding.swipeRefreshLayout.isRefreshing = true
|
||||
|
||||
// Refresh the canteen menu for the newly selected canteen
|
||||
refresh()
|
||||
// refresh()
|
||||
true
|
||||
}
|
||||
inflate(R.menu.menu_canteens)
|
||||
@@ -148,40 +146,41 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
// Set up the view pager's adapter
|
||||
viewPagerAdapter = CanteenOfferPageAdapter(
|
||||
activity as FragmentActivity,
|
||||
listOf(),
|
||||
0,
|
||||
this,
|
||||
viewModel.preferenceAllergen,
|
||||
)
|
||||
|
||||
viewModel.getDateCount().observe(viewLifecycleOwner) { dateCount ->
|
||||
viewPagerAdapter.itemCount = dateCount
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
// Assign the adapter to the view pager
|
||||
binding.viewPager.adapter = viewPagerAdapter
|
||||
|
||||
// Set up LiveData observer to refresh the view on update
|
||||
viewModel.allOffers.observe(viewLifecycleOwner) { offers ->
|
||||
// Update the element list stored in this fragment
|
||||
elements = offers
|
||||
|
||||
// Group elements by category
|
||||
val groupedElements = offers.groupElements().distinct()
|
||||
|
||||
// Find all dates for which items are available
|
||||
val newDates = groupedElements.map { it.date }.distinct()
|
||||
|
||||
// Update the date count stored in this fragment
|
||||
dateSize = newDates.size
|
||||
|
||||
// Update the item list in the view pager's adapter
|
||||
viewPagerAdapter.setNewItems(groupedElements, dateSize)
|
||||
|
||||
// Set the text for the opening hours dialogue
|
||||
openingHours = viewModel.getCanteenOpeningHours()
|
||||
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
|
||||
// Create and attach the tab layout for the ViewPager
|
||||
createTabLayoutMediator(newDates)
|
||||
}
|
||||
// viewModel.allOffers.observe(viewLifecycleOwner) { offers ->
|
||||
// // Update the element list stored in this fragment
|
||||
// elements = offers
|
||||
//
|
||||
// // Group elements by category
|
||||
// val groupedElements = offers.groupElements().distinct()
|
||||
//
|
||||
// // Find all dates for which items are available
|
||||
// val newDates = groupedElements.map { it.date }.distinct()
|
||||
//
|
||||
// // Update the date count stored in this fragment
|
||||
// dateSize = newDates.size
|
||||
//
|
||||
// // Update the item list in the view pager's adapter
|
||||
//// viewPagerAdapter.setNewItems(groupedElements, dateSize)
|
||||
//
|
||||
// // Set the text for the opening hours dialogue
|
||||
// openingHours = viewModel.getCanteenOpeningHours()
|
||||
//
|
||||
// binding.swipeRefreshLayout.isRefreshing = false
|
||||
//
|
||||
// // Create and attach the tab layout for the ViewPager
|
||||
// createTabLayoutMediator(newDates)
|
||||
// }
|
||||
|
||||
// Set up functions for when the user swipes to refresh the view
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
@@ -223,7 +222,8 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
viewModel.setPreference(pref, newValue)
|
||||
|
||||
// Update the view
|
||||
viewPagerAdapter.setNewItems(elements.groupElements().distinct(), dateSize)
|
||||
viewModel.registerDietaryPreferencesUpdate()
|
||||
// viewPagerAdapter.setNewItems(elements.groupElements().distinct(), dateSize)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,97 +235,6 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
private fun getPreference(pref: DietaryPreferences): Boolean =
|
||||
viewModel.getPreference(pref)
|
||||
|
||||
/**
|
||||
* Retrieves the user's dietary preferences and compiles them into a regular expression that can
|
||||
* be used to filter out items that don't fulfil the preferences. Example:
|
||||
* .......t..|........t.
|
||||
* This will retrieve all items that marked as either vegetarian or vegan
|
||||
* *
|
||||
* @return regular expression object reflecting the user's preferences
|
||||
*/
|
||||
private fun getPrefRegex(): Regex {
|
||||
// Retrieve the user's dietary preference as a string
|
||||
val prefs = viewModel.getDietaryPrefs().deconstruct()
|
||||
|
||||
// Return the 'empty' template string if no preference has been set or found
|
||||
return if (prefs == emptyPreferenceRegex) {
|
||||
Regex(emptyPreferenceRegex)
|
||||
} else {
|
||||
// Create the variable to insert the regular expression into
|
||||
var regexString = ""
|
||||
|
||||
// Create the object to store which preferences need to be met
|
||||
val indices = mutableListOf<Int>()
|
||||
|
||||
// Find all preferences that need to be met
|
||||
prefs.forEachIndexed { index, c ->
|
||||
if (c == DietaryPreferences.C_TRUE) indices.add(index)
|
||||
}
|
||||
|
||||
// Needs to be set to correctly assemble the regular expression
|
||||
var isFirst = true
|
||||
|
||||
// Iterate through every preference that has been set
|
||||
indices.forEach { index ->
|
||||
// Set an OR if more than one preference needs to be met
|
||||
if (!isFirst) regexString += '|'
|
||||
|
||||
// Add the expression looking for the single preference to the entire string
|
||||
regexString += emptyPreferenceRegex.substring(0 until index) +
|
||||
DietaryPreferences.C_TRUE +
|
||||
emptyPreferenceRegex.substring(index+1)
|
||||
|
||||
// Ensure that OR statements will be placed between the individual expressions
|
||||
isFirst = false
|
||||
}
|
||||
|
||||
// Compile the string to a regular expression object
|
||||
Regex(regexString)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups [CanteenOffer] elements by their categories into [CanteenOfferGroup] elements and
|
||||
* filters for the user's dietary preferences.
|
||||
*
|
||||
* @return the grouped and filtered elements
|
||||
*/
|
||||
private fun List<CanteenOffer>.groupElements(): List<CanteenOfferGroup> {
|
||||
// Get dietary preference regex
|
||||
val prefsRegex = getPrefRegex()
|
||||
|
||||
val filteredForPrefs = if (prefsRegex.toString() == emptyPreferenceRegex) {
|
||||
// Show all elements and skip filtering if no preference is set
|
||||
this
|
||||
} else {
|
||||
// Filter for dietary preferences
|
||||
this.filter {
|
||||
prefsRegex.matches(it.dietaryPreferences)
|
||||
}
|
||||
}
|
||||
|
||||
return filteredForPrefs.map { (_, date, dateId, category, _, canteen, _, _, _, _, _) ->
|
||||
// Create new group elements to group the already filtered elements by their categories
|
||||
CanteenOfferGroup(
|
||||
date,
|
||||
dateId,
|
||||
category,
|
||||
canteen,
|
||||
filteredForPrefs.filter {
|
||||
it.category == category && it.date == date && it.canteen == canteen
|
||||
}.map {
|
||||
// Map the individual items to their respective groups
|
||||
CanteenOfferGroupElement(
|
||||
it.title,
|
||||
it.price,
|
||||
it.dietaryPreferences,
|
||||
it.allergens
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the localised string for the canteen selected by the user.
|
||||
*
|
||||
@@ -370,17 +279,17 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
|
||||
*
|
||||
* @param offer item that has been clicked
|
||||
*/
|
||||
override fun onClick(offer: CanteenOfferGroupElement, category: String) {
|
||||
openBottomSheet(AllergenSheet(offer, category))
|
||||
}
|
||||
|
||||
/**
|
||||
* Executed when an item has been long-pressed.
|
||||
*
|
||||
* @param offer item that has been long-pressed
|
||||
* @return whether the long press was successful
|
||||
*/
|
||||
override fun onLongClick(offer: CanteenOfferGroupElement): Boolean {
|
||||
return false
|
||||
}
|
||||
// override fun onClick(offer: CanteenOfferGroupElement, category: String) {
|
||||
// openBottomSheet(AllergenSheet(offer, category))
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Executed when an item has been long-pressed.
|
||||
// *
|
||||
// * @param offer item that has been long-pressed
|
||||
// * @return whether the long press was successful
|
||||
// */
|
||||
// override fun onLongClick(offer: CanteenOfferGroupElement): Boolean {
|
||||
// return false
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user