mirror of
https://github.com/NinjaCheetah/RIT-Dining.git
synced 2025-10-19 06:36:18 -04:00
Added support for Gracie's multiple open times
This commit is contained in:
parent
f12f12bac8
commit
3f812495b0
@ -9,7 +9,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct Location: Hashable {
|
struct Location: Hashable {
|
||||||
let name: String
|
let name: String
|
||||||
let todaysHours: String
|
let todaysHours: [String]
|
||||||
let isOpen: openStatus
|
let isOpen: openStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,6 +17,7 @@ struct ContentView: View {
|
|||||||
@State private var isLoading = true
|
@State private var isLoading = true
|
||||||
@State private var rotationDegrees: Double = 0
|
@State private var rotationDegrees: Double = 0
|
||||||
@State private var diningLocations: [Location] = []
|
@State private var diningLocations: [Location] = []
|
||||||
|
@State private var lastRefreshed: Date?
|
||||||
|
|
||||||
private var animation: Animation {
|
private var animation: Animation {
|
||||||
.linear
|
.linear
|
||||||
@ -43,14 +44,15 @@ struct ContentView: View {
|
|||||||
|
|
||||||
// Parse the open status and times to create the hours string. If either time is missing, assume it has no openings
|
// Parse the open status and times to create the hours string. If either time is missing, assume it has no openings
|
||||||
// and use "Not Open Today". If there are times, then set those to be displayed.
|
// and use "Not Open Today". If there are times, then set those to be displayed.
|
||||||
let todaysHours: String
|
var todaysHours: [String] = []
|
||||||
if diningInfo.openTime == .none || diningInfo.closeTime == .none {
|
if diningInfo.diningTimes == .none {
|
||||||
todaysHours = "Not Open Today"
|
todaysHours = ["Not Open Today"]
|
||||||
} else {
|
} else {
|
||||||
print("Open:", display.string(from: diningInfo.openTime!),
|
for time in diningInfo.diningTimes! {
|
||||||
"Close:", display.string(from: diningInfo.closeTime!))
|
print("Open:", display.string(from: time.openTime),
|
||||||
|
"Close:", display.string(from: time.closeTime))
|
||||||
todaysHours = "\(display.string(from: diningInfo.openTime!)) - \(display.string(from: diningInfo.closeTime!))"
|
todaysHours.append("\(display.string(from: time.openTime)) - \(display.string(from: time.closeTime))")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DispatchQueue.global().sync {
|
DispatchQueue.global().sync {
|
||||||
newDiningLocations.append(
|
newDiningLocations.append(
|
||||||
@ -60,6 +62,7 @@ struct ContentView: View {
|
|||||||
isOpen: diningInfo.open
|
isOpen: diningInfo.open
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
lastRefreshed = Date()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DispatchQueue.global().sync {
|
DispatchQueue.global().sync {
|
||||||
@ -91,26 +94,40 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
} else {
|
} else {
|
||||||
Form {
|
VStack() {
|
||||||
ForEach(diningLocations, id: \.self) { location in
|
List {
|
||||||
VStack(alignment: .leading) {
|
Section(content: {
|
||||||
Text(location.name)
|
ForEach(diningLocations, id: \.self) { location in
|
||||||
Text(location.todaysHours)
|
VStack(alignment: .leading) {
|
||||||
switch location.isOpen {
|
Text(location.name)
|
||||||
case .open:
|
ForEach(location.todaysHours, id: \.self) { hours in
|
||||||
Text("Open")
|
Text(hours)
|
||||||
.foregroundStyle(.green)
|
}
|
||||||
case .closed:
|
switch location.isOpen {
|
||||||
Text("Closed")
|
case .open:
|
||||||
.foregroundStyle(.red)
|
Text("Open")
|
||||||
case .openingSoon:
|
.foregroundStyle(.green)
|
||||||
Text("Opening Soon")
|
case .closed:
|
||||||
.foregroundStyle(.orange)
|
Text("Closed")
|
||||||
case .closingSoon:
|
.foregroundStyle(.red)
|
||||||
Text("Closing Soon")
|
case .openingSoon:
|
||||||
.foregroundStyle(.orange)
|
Text("Opening Soon")
|
||||||
|
.foregroundStyle(.orange)
|
||||||
|
case .closingSoon:
|
||||||
|
Text("Closing Soon")
|
||||||
|
.foregroundStyle(.orange)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}, footer: {
|
||||||
|
if let lastRefreshed {
|
||||||
|
VStack(alignment: .center) {
|
||||||
|
Text("Last refreshed: \(lastRefreshed.formatted())")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("RIT Dining")
|
.navigationTitle("RIT Dining")
|
||||||
|
@ -79,11 +79,15 @@ enum openStatus {
|
|||||||
case closingSoon
|
case closingSoon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DiningTimes: Equatable {
|
||||||
|
let openTime: Date
|
||||||
|
let closeTime: Date
|
||||||
|
}
|
||||||
|
|
||||||
struct DiningInfo {
|
struct DiningInfo {
|
||||||
let id: Int
|
let id: Int
|
||||||
let name: String
|
let name: String
|
||||||
let openTime: Date?
|
let diningTimes: [DiningTimes]?
|
||||||
let closeTime: Date?
|
|
||||||
let open: openStatus
|
let open: openStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,13 +99,12 @@ func getLocationInfo(location: DiningLocation) -> DiningInfo {
|
|||||||
return DiningInfo(
|
return DiningInfo(
|
||||||
id: location.id,
|
id: location.id,
|
||||||
name: location.name,
|
name: location.name,
|
||||||
openTime: .none,
|
diningTimes: .none,
|
||||||
closeTime: .none,
|
|
||||||
open: .closed)
|
open: .closed)
|
||||||
}
|
}
|
||||||
|
|
||||||
let openString: String
|
var openStrings: [String] = []
|
||||||
let closeString: String
|
var closeStrings: [String] = []
|
||||||
|
|
||||||
// Dining locations have a regular schedule, but then they also have exceptions listed for days like weekends or holidays. If there
|
// Dining locations have a regular schedule, but then they also have exceptions listed for days like weekends or holidays. If there
|
||||||
// are exceptions, use those times for the day, otherwise we can just use the default times.
|
// are exceptions, use those times for the day, otherwise we can just use the default times.
|
||||||
@ -111,67 +114,84 @@ func getLocationInfo(location: DiningLocation) -> DiningInfo {
|
|||||||
return DiningInfo(
|
return DiningInfo(
|
||||||
id: location.id,
|
id: location.id,
|
||||||
name: location.name,
|
name: location.name,
|
||||||
openTime: .none,
|
diningTimes: .none,
|
||||||
closeTime: .none,
|
|
||||||
open: .closed)
|
open: .closed)
|
||||||
}
|
}
|
||||||
openString = location.events[0].exceptions![0].startTime
|
openStrings.append(location.events[0].exceptions![0].startTime)
|
||||||
closeString = location.events[0].exceptions![0].endTime
|
closeStrings.append(location.events[0].exceptions![0].endTime)
|
||||||
} else {
|
} else {
|
||||||
openString = location.events[0].startTime
|
for event in location.events {
|
||||||
closeString = location.events[0].endTime
|
openStrings.append(event.startTime)
|
||||||
|
closeStrings.append(event.endTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// I hate all of this date component nonsense.
|
// I hate all of this date component nonsense.
|
||||||
let openParts = openString.split(separator: ":").map { Int($0) ?? 0 }
|
var openDates: [Date] = []
|
||||||
let openTimeComponents = DateComponents(hour: openParts[0], minute: openParts[1], second: openParts[2])
|
var closeDates: [Date] = []
|
||||||
|
|
||||||
let closeParts = closeString.split(separator: ":").map { Int($0) ?? 0 }
|
|
||||||
let closeTimeComponents = DateComponents(hour: closeParts[0], minute: closeParts[1], second: closeParts[2])
|
|
||||||
|
|
||||||
let calendar = Calendar.current
|
let calendar = Calendar.current
|
||||||
let now = Date()
|
let now = Date()
|
||||||
|
|
||||||
let openDate = calendar.date(
|
for i in 0..<openStrings.count {
|
||||||
bySettingHour: openTimeComponents.hour!,
|
let openParts = openStrings[i].split(separator: ":").map { Int($0) ?? 0 }
|
||||||
minute: openTimeComponents.minute!,
|
let openTimeComponents = DateComponents(hour: openParts[0], minute: openParts[1], second: openParts[2])
|
||||||
second: openTimeComponents.second!,
|
|
||||||
of: now)!
|
|
||||||
|
|
||||||
var closeDate = calendar.date(
|
let closeParts = closeStrings[i].split(separator: ":").map { Int($0) ?? 0 }
|
||||||
bySettingHour: closeTimeComponents.hour!,
|
let closeTimeComponents = DateComponents(hour: closeParts[0], minute: closeParts[1], second: closeParts[2])
|
||||||
minute: closeTimeComponents.minute!,
|
|
||||||
second: closeTimeComponents.second!,
|
openDates.append(calendar.date(
|
||||||
of: now)!
|
bySettingHour: openTimeComponents.hour!,
|
||||||
|
minute: openTimeComponents.minute!,
|
||||||
|
second: openTimeComponents.second!,
|
||||||
|
of: now)!)
|
||||||
|
|
||||||
|
closeDates.append(calendar.date(
|
||||||
|
bySettingHour: closeTimeComponents.hour!,
|
||||||
|
minute: closeTimeComponents.minute!,
|
||||||
|
second: closeTimeComponents.second!,
|
||||||
|
of: now)!)
|
||||||
|
}
|
||||||
|
|
||||||
// If the closing time is less than or equal to the opening time, it's probably midnight and means either open until midnight
|
// If the closing time is less than or equal to the opening time, it's probably midnight and means either open until midnight
|
||||||
// or open 24/7, in the case of Bytes.
|
// or open 24/7, in the case of Bytes.
|
||||||
if closeDate <= openDate {
|
for i in 0..<closeDates.count {
|
||||||
closeDate = calendar.date(byAdding: .day, value: 1, to: closeDate)!
|
if closeDates[i] <= openDates[i] {
|
||||||
|
closeDates[i] = calendar.date(byAdding: .day, value: 1, to: closeDates[i])!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This can probably be done in a cleaner way but it's okay for now. If the location is open but the close date is within the next
|
// This can probably be done in a cleaner way but it's okay for now. If the location is open but the close date is within the next
|
||||||
// 30 minutes, label it as closing soon, and do the opposite if it's closed but the open date is within the next 30 minutes.
|
// 30 minutes, label it as closing soon, and do the opposite if it's closed but the open date is within the next 30 minutes.
|
||||||
let isOpen = (now >= openDate && now <= closeDate)
|
var openStatus: openStatus = .closed
|
||||||
let openStatus: openStatus
|
for i in 0..<openDates.count {
|
||||||
if isOpen {
|
let isOpen = (now >= openDates[i] && now <= closeDates[i])
|
||||||
if closeDate < calendar.date(byAdding: .minute, value: 30, to: now)! {
|
if isOpen {
|
||||||
openStatus = .closingSoon
|
if closeDates[i] < calendar.date(byAdding: .minute, value: 30, to: now)! {
|
||||||
|
openStatus = .closingSoon
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
openStatus = .open
|
||||||
|
break
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
openStatus = .open
|
if openDates[i] < calendar.date(byAdding: .minute, value: 30, to: now)! {
|
||||||
}
|
openStatus = .openingSoon
|
||||||
} else {
|
break
|
||||||
if openDate < calendar.date(byAdding: .minute, value: 30, to: now)! {
|
} else {
|
||||||
openStatus = .openingSoon
|
openStatus = .closed
|
||||||
} else {
|
}
|
||||||
openStatus = .closed
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var diningTimes: [DiningTimes] = []
|
||||||
|
for i in 0..<openDates.count {
|
||||||
|
diningTimes.append(DiningTimes(openTime: openDates[i], closeTime: closeDates[i]))
|
||||||
|
}
|
||||||
|
|
||||||
return DiningInfo(
|
return DiningInfo(
|
||||||
id: location.id,
|
id: location.id,
|
||||||
name: location.name,
|
name: location.name,
|
||||||
openTime: openDate,
|
diningTimes: diningTimes,
|
||||||
closeTime: closeDate,
|
|
||||||
open: openStatus)
|
open: openStatus)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user