Skip to content

Commit

Permalink
HoursThisWeek: Fix brunch hours (#316)
Browse files Browse the repository at this point in the history
Fix bug where brunch hours were not being reflected as both lunch and dinner
in the "hours this week" view.
  • Loading branch information
whoiswillma authored Aug 29, 2021
1 parent 840fb9b commit e965f7d
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,18 @@
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "Eatery Watch App Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Eatery">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
Expand All @@ -75,16 +77,27 @@
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "8"
notificationPayloadFile = "Eatery Watch App Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Eatery">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
25 changes: 19 additions & 6 deletions Eatery.xcodeproj/xcshareddata/xcschemes/Eatery Watch App.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,18 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
notificationPayloadFile = "Eatery Watch App Extension/PushNotificationPayload.apns">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Eatery">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<LocationScenarioReference
identifier = "New York, NY, USA"
referenceType = "1">
Expand All @@ -76,16 +78,27 @@
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Eatery">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5D05FF3123C2C14400EF8CC9"
BuildableName = "Eatery Watch App.app"
BlueprintName = "Eatery Watch App"
ReferencedContainer = "container:Eatery.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ extension CampusEateriesViewController: EateriesViewControllerDelegate {
}

if filters.contains(.favorites) {
filteredEateries = filteredEateries.filter { $0.hasFavorite }
filteredEateries = filteredEateries.filter { $0.currentlyHasFavorite }
}

if !filters.isDisjoint(with: Filter.areaFilters) {
Expand Down
67 changes: 8 additions & 59 deletions Eatery/Controllers/Look Ahead/LookAheadViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import NVActivityIndicatorView

class LookAheadViewController: UIViewController {

typealias MealChoice = CampusEatery.MajorMeal

typealias EateryArea = (area: Area, eateries: [CampusEatery])

private enum CellIdentifier: String {
Expand All @@ -26,53 +28,6 @@ class LookAheadViewController: UIViewController {

}

private enum MealChoice: Int, CaseIterable, CustomStringConvertible, Comparable {

case breakfast
case lunch
case dinner

static func < (lhs: MealChoice, rhs: MealChoice) -> Bool {
lhs.rawValue < rhs.rawValue
}

init?(hour: Int) {
for choice in MealChoice.allCases {
if choice.hours.contains(hour) {
self = choice
return
}
}

return nil
}

init(from date: Date) {
var calendar = Calendar.current
calendar.timeZone = TimeZone(identifier: "America/New_York")!

let hour = calendar.component(.hour, from: date)
self = MealChoice(hour: hour) ?? .breakfast
}

var description: String {
switch self {
case .breakfast: return "Breakfast"
case .lunch: return "Lunch"
case .dinner: return "Dinner"
}
}

var hours: CountableClosedRange<Int> {
switch self {
case .breakfast: return 0...9
case .lunch: return 10...15
case .dinner: return 15...23
}
}

}

private enum DayChoice: Int, CaseIterable {

case today
Expand Down Expand Up @@ -139,15 +94,6 @@ class LookAheadViewController: UIViewController {
// used to prevent table view jitter when recomputing layout
private var cellHeights: [IndexPath: CGFloat] = [:]

/// Try and find the event that most closely matches the specified meal
private func findEvent(from events: [CampusEatery.EventName: Event], matching meal: MealChoice) -> Event? {
switch meal {
case .breakfast: return events["Breakfast"] ?? events["Brunch"]
case .lunch: return events["Lunch"] ?? events["Brunch"] ?? events["Lite Lunch"]
case .dinner: return events["Dinner"]
}
}

override func viewDidLoad() {
super.viewDidLoad()

Expand Down Expand Up @@ -272,7 +218,7 @@ extension LookAheadViewController: UITableViewDataSource {
cell.eateryNameLabel.text = eatery.displayName

let events = eatery.eventsByName(onDayOf: selectedDate)
if let event = findEvent(from: events, matching: selectedMeal) {
if let event = CampusEatery.findEvent(from: events, matching: selectedMeal) {
if selectedDay == .today {
// There is an event, and it's today

Expand Down Expand Up @@ -349,7 +295,10 @@ extension LookAheadViewController: UITableViewDelegate {
tableView.deselectRow(at: indexPath, animated: true)

let eatery = eateriesByArea[indexPath.section].eateries[indexPath.row]
guard findEvent(from: eatery.eventsByName(onDayOf: selectedDate), matching: selectedMeal) != nil else {
guard CampusEatery.findEvent(
from: eatery.eventsByName(onDayOf: selectedDate),
matching: selectedMeal
) != nil else {
return
}

Expand Down Expand Up @@ -397,7 +346,7 @@ extension LookAheadViewController: FilterEateriesViewDelegate {

func filterEateriesView(_ filterEateriesView: FilterEateriesView, didFilterMeal sender: UIButton) {
guard let index = filterEateriesView.mealButtons.firstIndex(of: sender),
let meal = MealChoice(rawValue: index) else {
let meal = MealChoice(rawValue: index) else {
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import UIKit

class HoursThisWeekView: UIView {

typealias Meal = CampusEatery.MajorMeal

// only shown for dining halls
private let segmentedControl = UISegmentedControl()
private var showDiningHallConstraints: [Constraint] = []
Expand All @@ -21,8 +23,6 @@ class HoursThisWeekView: UIView {

private var eatery: Eatery?

private let diningMeals = ["Breakfast", "Lunch", "Dinner"]

init() {
super.init(frame: .zero)

Expand Down Expand Up @@ -89,23 +89,17 @@ class HoursThisWeekView: UIView {
setShowDiningHall(true)

segmentedControl.removeAllSegments()
for meal in diningMeals {
for meal in Meal.allCases {
segmentedControl.insertSegment(
withTitle: meal,
withTitle: meal.description,
at: segmentedControl.numberOfSegments,
animated: false
)
}

let indexToDisplay: Int
if let activeMealName = eatery.currentActiveEvent()?.desc,
let index = diningMeals.firstIndex(of: activeMealName) {
indexToDisplay = index
} else {
indexToDisplay = 0
}
displayMeal(withName: diningMeals[indexToDisplay])
segmentedControl.selectedSegmentIndex = indexToDisplay
let meal = Meal(description: eatery.currentActiveEvent()?.desc) ?? Meal.breakfast
display(meal: meal)
segmentedControl.selectedSegmentIndex = meal.rawValue

default:
setShowDiningHall(false)
Expand All @@ -127,19 +121,22 @@ class HoursThisWeekView: UIView {

@objc private func segmentedControlValueChanged(_ sender: UISegmentedControl) {
let index = sender.selectedSegmentIndex
guard 0 <= index, index < diningMeals.count else {
guard 0 <= index, index < Meal.allCases.count else {
return
}

displayMeal(withName: diningMeals[sender.selectedSegmentIndex])
display(meal: Meal.allCases[index])
}

private func displayMeal(withName name: String) {
private func display(meal: Meal) {
for subview in stackView.arrangedSubviews {
subview.removeFromSuperview()
}

let daysAndEvents = datesThisWeek().map { ($0, eatery?.eventsByName(onDayOf: $0)[name]) }
let daysAndEvents: [(Date, Event?)] = datesThisWeek().map { date in
let events = eatery?.eventsByName(onDayOf: date) ?? [:]
return (date, CampusEatery.findEvent(from: events, matching: meal))
}

for (day, event) in daysAndEvents {
let dayAndHoursView = DayAndHoursView()
Expand Down
71 changes: 70 additions & 1 deletion Shared/Models/CampusEatery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ extension CampusEatery {
getMenuAndType(meal: meal, onDayOf: date)?.0
}

var hasFavorite: Bool {
var currentlyHasFavorite: Bool {
let events = eventsByName(onDayOf: Date())
for event in events {
for (_, items) in event.value.menu.data {
Expand Down Expand Up @@ -310,6 +310,75 @@ extension CampusEatery {
return false
}

/// A "major" meal of the day: breakfast, lunch, or dinner
enum MajorMeal: Int, CaseIterable, CustomStringConvertible, Comparable {

case breakfast
case lunch
case dinner

static func < (lhs: MajorMeal, rhs: MajorMeal) -> Bool {
lhs.rawValue < rhs.rawValue
}

init?(hour: Int) {
for choice in MajorMeal.allCases {
if choice.hours.contains(hour) {
self = choice
return
}
}

return nil
}

init(from date: Date) {
var calendar = Calendar.current
if let timeZone = TimeZone(identifier: "America/New_York") {
calendar.timeZone = timeZone
}

let hour = calendar.component(.hour, from: date)
self = MajorMeal(hour: hour) ?? .breakfast
}

/// Inverse of MajorMeal.description
init?(description: String?) {
if let description = description,
let value = MajorMeal.allCases.first(where: { $0.description == description }) {
self = value
} else {
return nil
}
}

var description: String {
switch self {
case .breakfast: return "Breakfast"
case .lunch: return "Lunch"
case .dinner: return "Dinner"
}
}

var hours: CountableClosedRange<Int> {
switch self {
case .breakfast: return 0...9
case .lunch: return 10...15
case .dinner: return 15...23
}
}

}

/// Try and find the event that most closely matches the specified meal
static func findEvent(from events: [CampusEatery.EventName: Event], matching meal: MajorMeal) -> Event? {
switch meal {
case .breakfast: return events["Breakfast"] ?? events["Brunch"]
case .lunch: return events["Lunch"] ?? events["Brunch"] ?? events["Lite Lunch"]
case .dinner: return events["Dinner"]
}
}

}

// MARK: - ExpandedMenu Information
Expand Down

0 comments on commit e965f7d

Please sign in to comment.