Skip to content

Commit 1b1c7cb

Browse files
authored
Merge pull request #679 from pennlabs/cassieym
Dining hall info redesign
2 parents 91e70af + c11a2ca commit 1b1c7cb

15 files changed

Lines changed: 667 additions & 251 deletions

File tree

PennMobile/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ dependencies {
7676
// If you want the foundation layout, use the bundle or the specific activity compose you have defined
7777
implementation libs.androidx.activity.compose
7878
implementation libs.androidx.material3.android
79+
implementation libs.places
7980
implementation libs.androidx.compose.ui.tooling.preview
8081
// implementation libs.androidx.foundation.layout
8182

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: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ import dagger.hilt.android.AndroidEntryPoint
7373
import rx.schedulers.Schedulers
7474
import java.time.LocalDateTime
7575
import java.time.format.DateTimeFormatter
76+
import kotlin.collections.listOf
77+
import kotlin.text.get
7678

7779
@AndroidEntryPoint
7880
class DiningFragment : Fragment() {
@@ -107,7 +109,7 @@ class DiningFragment : Fragment() {
107109
val pullToRefreshState = rememberPullToRefreshState()
108110
val isDataRefreshing by viewModel.isRefreshing.collectAsState()
109111
val allDiningHalls by viewModel.allDiningHalls.collectAsState()
110-
val favouriteDiningHalls by viewModel.favouriteDiningHalls.collectAsState(listOf())
112+
val favouriteDiningHalls = viewModel.favouriteDiningHalls.collectAsState(initial = listOf<DiningHall>())
111113

112114
var isOnline by remember { mutableStateOf<Boolean?>(null) }
113115
var isSortMenuExpanded by remember { mutableStateOf(false) }
@@ -278,7 +280,7 @@ class DiningFragment : Fragment() {
278280

279281
item {
280282
FavouriteDiningHalls(
281-
diningHalls = favouriteDiningHalls,
283+
diningHalls = favouriteDiningHalls.value as List<DiningHall>,
282284
toggleFavourite = { viewModel.toggleFavourite(it) },
283285
openDiningHallMenu = { hall -> navigateToMenuFragment(hall) },
284286
modifier =
@@ -306,7 +308,7 @@ class DiningFragment : Fragment() {
306308
items(allDiningHalls) { diningHall ->
307309
DiningHallCard(
308310
diningHall = diningHall,
309-
isFavourite = favouriteDiningHalls.contains(diningHall),
311+
isFavourite = (favouriteDiningHalls.value as List<DiningHall>).any { it.id == diningHall.id },
310312
toggleFavourite = { viewModel.toggleFavourite(diningHall) },
311313
openDiningHallMenu = { hall -> navigateToMenuFragment(hall) },
312314
)
@@ -342,36 +344,60 @@ class DiningFragment : Fragment() {
342344
}
343345

344346
companion object {
345-
// Gets the dining hall menus
346-
fun getMenus(venues: MutableList<DiningHall>) {
347-
try {
348-
val idVenueMap = mutableMapOf<Int, DiningHall>()
349-
venues.forEach { idVenueMap[it.id] = it }
350-
val current = LocalDateTime.now()
351-
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
352-
val formatted = current.format(formatter)
353-
val studentLife = MainActivity.studentLifeInstance
354-
studentLife
355-
.getMenus(formatted)
356-
.subscribeOn(Schedulers.io())
357-
.subscribe({ menus ->
358-
menus?.filterNotNull()?.forEach { menu ->
359-
menu.venue?.let { venue ->
360-
idVenueMap[venue.venueId]?.let { diningHall ->
361-
val diningHallMenus = diningHall.menus
362-
diningHallMenus.add(menu)
363-
diningHall.sortMeals(diningHallMenus)
347+
private val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
348+
349+
// Fetch menus for today + next 6 days for all venues (closed and open)
350+
fun getMenusForWeek(venues: MutableList<DiningHall>) {
351+
val idVenueMap = mutableMapOf<Int, DiningHall>()
352+
venues.forEach { idVenueMap[it.id] = it }
353+
354+
val today = LocalDateTime.now()
355+
for (offset in 0..6) {
356+
val date = today.plusDays(offset.toLong())
357+
val formatted = date.format(dateFormatter)
358+
359+
try {
360+
val studentLife = MainActivity.studentLifeInstance
361+
studentLife
362+
.getMenus(formatted)
363+
.subscribeOn(Schedulers.io())
364+
.subscribe({ menus ->
365+
menus?.filterNotNull()?.forEach { menu ->
366+
menu.venue?.let { venue ->
367+
idVenueMap[venue.venueId]?.let { diningHall ->
368+
synchronized(diningHall.menusByDate) {
369+
val dayMenus =
370+
diningHall.menusByDate
371+
.getOrPut(formatted) { ArrayList() }
372+
(dayMenus as java.util.ArrayList).add(menu)
373+
diningHall.sortMealsForDate(formatted, dayMenus)
374+
}
375+
// Keep today's menus in the legacy .menus field so existing code that reads it still works
376+
if (offset == 0) {
377+
synchronized(diningHall) {
378+
diningHall.sortMeals(
379+
diningHall.menusByDate[formatted]
380+
?: ArrayList(),
381+
)
382+
}
383+
}
384+
}
364385
}
365386
}
366-
}
367-
}, { throwable ->
368-
Log.e("DiningFragment", "Error getting Menus", throwable)
369-
})
370-
} catch (e: Exception) {
371-
e.printStackTrace()
387+
}, { throwable ->
388+
Log.e("DiningFragment", "Error getting menus for $formatted", throwable)
389+
})
390+
} catch (e: Exception) {
391+
Log.e("DiningFragment", "Exception fetching menus for $formatted", e)
392+
}
372393
}
373394
}
374395

396+
// single-day fetch
397+
fun getMenus(venues: MutableList<DiningHall>) {
398+
getMenusForWeek(venues)
399+
}
400+
375401
// Takes a venue then adds an image and modifies venue name if name is too long
376402
fun createHall(venue: Venue): DiningHall {
377403
when (venue.id) {

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,11 @@ 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")
2928
mActivity = activity as MainActivity
3029
}
3130

0 commit comments

Comments
 (0)