mirror of
https://github.com/NinjaCheetah/RIT-Dining.git
synced 2026-01-17 12:05:57 -05:00
- The favorites model now lives inside of the base dining model, since it was only ever used in places where the main dining model was also available and is only relevant when the dining model is available. - Removed unnecessary instances of models that were going unused. - Moved the favorite/map/menu buttons in the top right of the DetailView into the right side toolbar. - This frees up a good bit of space at the top of the DetailView and looks cleaner, especially with iOS 26's new toolbar style. - Actually added a copyright string to the about screen. More refactors, both internally and for the UI, will be coming soon.
152 lines
5.8 KiB
Swift
152 lines
5.8 KiB
Swift
//
|
|
// VisitingChefsPush.swift
|
|
// TigerDine
|
|
//
|
|
// Created by Campbell on 10/1/25.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct VisitingChefPush: View {
|
|
@AppStorage("visitingChefPushEnabled") var pushEnabled: Bool = false
|
|
@AppStorage("notificationOffset") var notificationOffset: Int = 2
|
|
|
|
@Environment(DiningModel.self) var model
|
|
|
|
@State private var pushAllowed: Bool = false
|
|
|
|
private let visitingChefs = [
|
|
"California Rollin' Sushi",
|
|
"D'Mangu",
|
|
"Esan's Kitchen",
|
|
"Halal n Out",
|
|
"just chik'n",
|
|
"KO-BQ",
|
|
"Macarollin'",
|
|
"P.H. Express",
|
|
"Tandoor of India"
|
|
]
|
|
|
|
var body: some View {
|
|
VStack {
|
|
Form {
|
|
Section(header: Text("Visiting Chef Notifications"),
|
|
footer: Text(!pushAllowed ? "You must allow notifications from TigerDine to use this feature." : "")) {
|
|
Toggle(isOn: $pushEnabled) {
|
|
Text("Notifications Enabled")
|
|
}
|
|
.disabled(!pushAllowed)
|
|
.onChange(of: pushEnabled) {
|
|
if pushEnabled {
|
|
Task {
|
|
await model.scheduleAllPushes()
|
|
}
|
|
} else {
|
|
Task {
|
|
await model.cancelAllPushes()
|
|
}
|
|
}
|
|
}
|
|
Picker("Send Notifications", selection: $notificationOffset) {
|
|
Text("1 Hour Before").tag(1)
|
|
Text("2 Hours Before").tag(2)
|
|
Text("3 Hours Before").tag(3)
|
|
}
|
|
.disabled(!pushAllowed || !pushEnabled)
|
|
.onChange(of: notificationOffset) {
|
|
Task {
|
|
// If we changed the offset, we need to reschedule everything.
|
|
await model.cancelAllPushes()
|
|
await model.scheduleAllPushes()
|
|
}
|
|
}
|
|
}
|
|
Section(footer: Text("Get notified when and where a specific visiting chef will be on campus.")) {
|
|
ForEach(visitingChefs, id: \.self) { chef in
|
|
Toggle(isOn: Binding(
|
|
get: {
|
|
model.notifyingChefs.contains(chef)
|
|
},
|
|
set: { isOn in
|
|
if isOn {
|
|
model.notifyingChefs.add(chef)
|
|
Task {
|
|
await model.schedulePushesForChef(chef)
|
|
}
|
|
} else {
|
|
model.notifyingChefs.remove(chef)
|
|
model.visitingChefPushes.cancelPushesForChef(name: chef)
|
|
}
|
|
}
|
|
)) {
|
|
Text(chef)
|
|
}
|
|
}
|
|
}
|
|
.disabled(!pushAllowed || !pushEnabled)
|
|
#if DEBUG
|
|
Section(header: Text("DEBUG - Scheduled Pushes")) {
|
|
Button(action: {
|
|
Task {
|
|
await model.scheduleAllPushes()
|
|
}
|
|
}) {
|
|
Text("Schedule All")
|
|
}
|
|
Button(action: {
|
|
let uuids = model.visitingChefPushes.pushes.map(\.uuid)
|
|
Task {
|
|
await cancelVisitingChefNotifs(uuids: uuids)
|
|
model.visitingChefPushes.pushes.removeAll()
|
|
}
|
|
}) {
|
|
Text("Cancel All")
|
|
}
|
|
.tint(.red)
|
|
ForEach(model.visitingChefPushes.pushes, id: \.uuid) { push in
|
|
VStack(alignment: .leading) {
|
|
Text("\(push.name) at \(push.location)")
|
|
Text(push.uuid)
|
|
.font(.caption)
|
|
.foregroundStyle(.secondary)
|
|
Text("\(push.startTime) - \(push.endTime)")
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
.swipeActions {
|
|
Button(action: {
|
|
Task {
|
|
await cancelVisitingChefNotifs(uuids: [push.uuid])
|
|
model.visitingChefPushes.pushes.remove(at: model.visitingChefPushes.pushes.firstIndex(of: push)!)
|
|
}
|
|
}) {
|
|
Label("Delete", systemImage: "trash")
|
|
}
|
|
.tint(.red)
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
.onAppear {
|
|
Task {
|
|
let center = UNUserNotificationCenter.current()
|
|
do {
|
|
try await center.requestAuthorization(options: [.alert, .sound])
|
|
} catch {
|
|
print(error)
|
|
}
|
|
let settings = await center.notificationSettings()
|
|
guard (settings.authorizationStatus == .authorized) else { pushEnabled = false; return }
|
|
pushAllowed = true
|
|
}
|
|
}
|
|
.navigationTitle("Notifications")
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
VisitingChefPush()
|
|
}
|