Skip to content

Commit a4ecaa0

Browse files
committed
dining ui rework
1 parent bd30db2 commit a4ecaa0

11 files changed

Lines changed: 451 additions & 234 deletions

File tree

PennMobile/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ dependencies {
6161
// If you want the foundation layout, use the bundle or the specific activity compose you have defined
6262
implementation libs.androidx.activity.compose
6363
implementation libs.androidx.material3.android
64+
implementation libs.places
6465
// implementation libs.androidx.foundation.layout
6566

6667
androidTestImplementation libs.androidx.espresso.core

PennMobile/src/main/java/com/pennapps/labs/pennmobile/dining/adapters/MenuAdapter.java

Lines changed: 0 additions & 120 deletions
This file was deleted.

PennMobile/src/main/java/com/pennapps/labs/pennmobile/dining/classes/DiningHall.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ open class DiningHall : Parcelable {
2222
var image: Int
2323
private set
2424

25+
// key date string "yyyy-MM-dd"
26+
// populated by DiningFragment.getMenusForWeek() for today + 6 days.
27+
@Transient
28+
val menusByDate: MutableMap<String, MutableList<Menu>> = HashMap()
29+
2530
@SerializedName("tblDayPart")
2631
var menus: MutableList<Menu> = ArrayList()
2732

@@ -55,6 +60,16 @@ open class DiningHall : Parcelable {
5560
this.menus.sortedWith(comparator)
5661
}
5762

63+
// Sort and store menus for a specific date in menusByDate.
64+
fun sortMealsForDate(
65+
date: String,
66+
menus: MutableList<Menu>,
67+
) {
68+
val mealOrder = listOf("Breakfast", "Brunch", "Lunch", "Dinner", "Express")
69+
val sorted = menus.sortedBy { mealOrder.indexOf(it.name) }
70+
menusByDate[date] = sorted.toMutableList()
71+
}
72+
5873
override fun describeContents(): Int = 0
5974

6075
override fun writeToParcel(

PennMobile/src/main/java/com/pennapps/labs/pennmobile/dining/fragments/DiningFragment.kt

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import dagger.hilt.android.AndroidEntryPoint
7070
import rx.schedulers.Schedulers
7171
import java.time.LocalDateTime
7272
import java.time.format.DateTimeFormatter
73+
import kotlin.text.get
7374

7475
@AndroidEntryPoint
7576
class DiningFragment : Fragment() {
@@ -293,36 +294,60 @@ class DiningFragment : Fragment() {
293294
}
294295

295296
companion object {
296-
// Gets the dining hall menus
297-
fun getMenus(venues: MutableList<DiningHall>) {
298-
try {
299-
val idVenueMap = mutableMapOf<Int, DiningHall>()
300-
venues.forEach { idVenueMap[it.id] = it }
301-
val current = LocalDateTime.now()
302-
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
303-
val formatted = current.format(formatter)
304-
val studentLife = MainActivity.studentLifeInstance
305-
studentLife
306-
.getMenus(formatted)
307-
.subscribeOn(Schedulers.io())
308-
.subscribe({ menus ->
309-
menus?.filterNotNull()?.forEach { menu ->
310-
menu.venue?.let { venue ->
311-
idVenueMap[venue.venueId]?.let { diningHall ->
312-
val diningHallMenus = diningHall.menus
313-
diningHallMenus.add(menu)
314-
diningHall.sortMeals(diningHallMenus)
297+
private val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
298+
299+
// Fetch menus for today + next 6 days for all venues (closed and open)
300+
fun getMenusForWeek(venues: MutableList<DiningHall>) {
301+
val idVenueMap = mutableMapOf<Int, DiningHall>()
302+
venues.forEach { idVenueMap[it.id] = it }
303+
304+
val today = LocalDateTime.now()
305+
for (offset in 0..6) {
306+
val date = today.plusDays(offset.toLong())
307+
val formatted = date.format(dateFormatter)
308+
309+
try {
310+
val studentLife = MainActivity.studentLifeInstance
311+
studentLife
312+
.getMenus(formatted)
313+
.subscribeOn(Schedulers.io())
314+
.subscribe({ menus ->
315+
menus?.filterNotNull()?.forEach { menu ->
316+
menu.venue?.let { venue ->
317+
idVenueMap[venue.venueId]?.let { diningHall ->
318+
synchronized(diningHall.menusByDate) {
319+
val dayMenus =
320+
diningHall.menusByDate
321+
.getOrPut(formatted) { ArrayList() }
322+
(dayMenus as java.util.ArrayList).add(menu)
323+
diningHall.sortMealsForDate(formatted, dayMenus)
324+
}
325+
// Keep today's menus in the legacy .menus field so existing code that reads it still works
326+
if (offset == 0) {
327+
synchronized(diningHall) {
328+
diningHall.sortMeals(
329+
diningHall.menusByDate[formatted]
330+
?: ArrayList(),
331+
)
332+
}
333+
}
334+
}
315335
}
316336
}
317-
}
318-
}, { throwable ->
319-
Log.e("DiningFragment", "Error getting Menus", throwable)
320-
})
321-
} catch (e: Exception) {
322-
e.printStackTrace()
337+
}, { throwable ->
338+
Log.e("DiningFragment", "Error getting menus for $formatted", throwable)
339+
})
340+
} catch (e: Exception) {
341+
Log.e("DiningFragment", "Exception fetching menus for $formatted", e)
342+
}
323343
}
324344
}
325345

346+
// single-day fetch
347+
fun getMenus(venues: MutableList<DiningHall>) {
348+
getMenusForWeek(venues)
349+
}
350+
326351
// Takes a venue then adds an image and modifies venue name if name is too long
327352
fun createHall(venue: Venue): DiningHall {
328353
when (venue.id) {

PennMobile/src/main/java/com/pennapps/labs/pennmobile/dining/fragments/DiningInfoFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ import org.joda.time.format.DateTimeFormat
2020
*/
2121
class DiningInfoFragment : Fragment() {
2222
private lateinit var menuParent: RelativeLayout
23-
private var mDiningHall: DiningHall? = null
23+
var mDiningHall: DiningHall? = null
2424
private lateinit var mActivity: MainActivity
2525

2626
override fun onCreate(savedInstanceState: Bundle?) {
2727
super.onCreate(savedInstanceState)
28-
mDiningHall = arguments?.getParcelable("DiningHall")
28+
// mDiningHall = arguments?.getParcelable("DiningHall") // removed
2929
mActivity = activity as MainActivity
3030
}
3131

PennMobile/src/main/java/com/pennapps/labs/pennmobile/dining/fragments/DiningViewModel.kt

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package com.pennapps.labs.pennmobile.dining.fragments
22

33
import android.content.SharedPreferences
44
import android.util.Log
5-
import androidx.compose.runtime.State
65
import androidx.core.content.edit
76
import androidx.lifecycle.ViewModel
87
import androidx.lifecycle.viewModelScope
8+
import com.pennapps.labs.pennmobile.MainActivity
99
import com.pennapps.labs.pennmobile.compose.utils.Result
1010
import com.pennapps.labs.pennmobile.compose.utils.SnackBarEvent
1111
import com.pennapps.labs.pennmobile.dining.classes.DiningHall
@@ -18,9 +18,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
1818
import kotlinx.coroutines.flow.SharingStarted
1919
import kotlinx.coroutines.flow.StateFlow
2020
import kotlinx.coroutines.flow.combine
21-
import kotlinx.coroutines.flow.map
2221
import kotlinx.coroutines.flow.stateIn
22+
import kotlinx.coroutines.flow.update
2323
import kotlinx.coroutines.launch
24+
import rx.schedulers.Schedulers
25+
import java.time.LocalDate
26+
import java.time.format.DateTimeFormatter
2427
import javax.inject.Inject
2528

2629
@HiltViewModel
@@ -42,6 +45,10 @@ class DiningViewModel
4245
private val _snackBarEvent = MutableStateFlow<SnackBarEvent>(SnackBarEvent.None)
4346
val snackBarEvent: StateFlow<SnackBarEvent> = _snackBarEvent
4447

48+
private val _menusByDate =
49+
MutableStateFlow<Map<String, List<DiningHall.Menu>>>(emptyMap())
50+
val menusByDate: StateFlow<Map<String, List<DiningHall.Menu>>> = _menusByDate
51+
4552
private val _favouriteDiningHalls =
4653
diningRepo.favouriteDiningHalls.stateIn(
4754
viewModelScope,
@@ -57,9 +64,9 @@ class DiningViewModel
5764
halls.filter { diningHall -> favouriteIDs.contains(diningHall.id) }
5865
}
5966
// when refreshed, wiped out the hearts in the all-dining-halls list
60-
// .map { favouriteIDs ->
61-
// allDiningHalls.value.filter { diningHall -> favouriteIDs.contains(diningHall.id) }
62-
// }
67+
// .map { favouriteIDs ->
68+
// allDiningHalls.value.filter { diningHall -> favouriteIDs.contains(diningHall.id) }
69+
// }
6370

6471
init {
6572
fetchSortOrder()
@@ -94,6 +101,42 @@ class DiningViewModel
94101
}
95102
}
96103

104+
fun fetchMenusForWeek(hall: DiningHall) {
105+
_menusByDate.value = emptyMap()
106+
val fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd")
107+
val today = LocalDate.now()
108+
val mealOrder = listOf("Breakfast", "Brunch", "Lunch", "Dinner", "Express")
109+
110+
for (offset in 0..6) {
111+
val dateStr = today.plusDays(offset.toLong()).format(fmt)
112+
try {
113+
MainActivity.studentLifeInstance
114+
.getMenus(dateStr)
115+
.subscribeOn(Schedulers.io())
116+
.subscribe({ menus ->
117+
val dayMenus =
118+
menus
119+
?.filterNotNull()
120+
?.filter { it.venue?.venueId == hall.id }
121+
?.sortedWith { a, b ->
122+
mealOrder.indexOf(a.name) - mealOrder.indexOf(b.name)
123+
}
124+
?: emptyList()
125+
126+
if (dayMenus.isNotEmpty()) {
127+
_menusByDate.update { current ->
128+
current + (dateStr to dayMenus)
129+
}
130+
}
131+
}, { throwable ->
132+
Log.e("DiningViewModel", "Error fetching menus for $dateStr", throwable)
133+
})
134+
} catch (e: Exception) {
135+
Log.e("DiningViewModel", "Exception fetching menus for $dateStr", e)
136+
}
137+
}
138+
}
139+
97140
private fun fetchSortOrder() {
98141
_sortOrder.value =
99142
DiningHallSortOrder.fromKey(

0 commit comments

Comments
 (0)