mirror of
https://github.com/NinjaCheetah/RIT-Dining.git
synced 2026-03-20 08:27:49 -04:00
Compare commits
2 Commits
a4e3af3e75
...
420f49cafc
| Author | SHA1 | Date | |
|---|---|---|---|
|
420f49cafc
|
|||
|
0c07c509f3
|
@@ -42,6 +42,16 @@ func parseMultiOpenStatus(diningTimes: [DiningTimes]?, referenceTime: Date) -> O
|
|||||||
closeTime: diningTimes[i].closeTime,
|
closeTime: diningTimes[i].closeTime,
|
||||||
referenceTime: referenceTime
|
referenceTime: referenceTime
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// If we're closing soon for the current opening period, but then we're opening again at the same time we close in the next
|
||||||
|
// period, we should just stick with "Open" because showing "Closing Soon" for 30 minutes and then going straight back to
|
||||||
|
// "Open" is kinda confusing. This issue has been observed with Petals specifically.
|
||||||
|
if openStatus == .closingSoon && i != diningTimes.indices.last {
|
||||||
|
if diningTimes[i].closeTime == diningTimes[i + 1].openTime {
|
||||||
|
openStatus = .open
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the first event pass came back closed, loop again in case a later event has a different status. This is mostly to
|
// If the first event pass came back closed, loop again in case a later event has a different status. This is mostly to
|
||||||
// accurately catch Gracie's/Brick City Cafe's multiple open periods each day.
|
// accurately catch Gracie's/Brick City Cafe's multiple open periods each day.
|
||||||
if openStatus != .closed {
|
if openStatus != .closed {
|
||||||
|
|||||||
@@ -57,8 +57,8 @@
|
|||||||
membershipExceptions = (
|
membershipExceptions = (
|
||||||
Components/SharedUtils.swift,
|
Components/SharedUtils.swift,
|
||||||
Components/TigerCenterParsers.swift,
|
Components/TigerCenterParsers.swift,
|
||||||
Data/Static/FDMPMealPeriods.swift,
|
Data/Constant/FDMPMealPeriods.swift,
|
||||||
Data/Static/TCtoFDMPMap.swift,
|
Data/Constant/TCtoFDMPMap.swift,
|
||||||
Types/TigerCenterTypes.swift,
|
Types/TigerCenterTypes.swift,
|
||||||
);
|
);
|
||||||
target = 374CDA572F10A19500D8C50A /* TigerDineWidgets */;
|
target = 374CDA572F10A19500D8C50A /* TigerDineWidgets */;
|
||||||
@@ -292,7 +292,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDineWidgets/TigerDineWidgets.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
INFOPLIST_FILE = TigerDineWidgets/Info.plist;
|
||||||
@@ -337,7 +337,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining.Widgets";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
@@ -481,7 +481,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -500,7 +500,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@@ -518,7 +518,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
CODE_SIGN_ENTITLEMENTS = TigerDine/TigerDine.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 32;
|
CURRENT_PROJECT_VERSION = 34;
|
||||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -537,7 +537,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.0;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
PRODUCT_BUNDLE_IDENTIFIER = "dev.ninjacheetah.RIT-Dining";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ struct ContentView: View {
|
|||||||
|
|
||||||
@State private var loadFailed: Bool = false
|
@State private var loadFailed: Bool = false
|
||||||
@State private var showingDonationSheet: Bool = false
|
@State private var showingDonationSheet: Bool = false
|
||||||
|
@State private var showingFeedbackSheet: Bool = false
|
||||||
@State private var searchText: String = ""
|
@State private var searchText: String = ""
|
||||||
@State private var path = NavigationPath()
|
@State private var path = NavigationPath()
|
||||||
|
|
||||||
@@ -149,6 +150,11 @@ struct ContentView: View {
|
|||||||
Image(systemName: "info.circle")
|
Image(systemName: "info.circle")
|
||||||
Text("About")
|
Text("About")
|
||||||
}
|
}
|
||||||
|
Button(action: {
|
||||||
|
showingFeedbackSheet = true
|
||||||
|
}) {
|
||||||
|
Label("Feedback", systemImage: "paperplane")
|
||||||
|
}
|
||||||
Button(action: {
|
Button(action: {
|
||||||
showingDonationSheet = true
|
showingDonationSheet = true
|
||||||
}) {
|
}) {
|
||||||
@@ -187,6 +193,9 @@ struct ContentView: View {
|
|||||||
.sheet(isPresented: $showingDonationSheet) {
|
.sheet(isPresented: $showingDonationSheet) {
|
||||||
DonationView()
|
DonationView()
|
||||||
}
|
}
|
||||||
|
.sheet(isPresented: $showingFeedbackSheet) {
|
||||||
|
FeedbackView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import SwiftUI
|
|||||||
struct DonationView: View {
|
struct DonationView: View {
|
||||||
@Environment(\.dismiss) var dismiss
|
@Environment(\.dismiss) var dismiss
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
|
|
||||||
@State private var symbolDrawn: Bool = true
|
@State private var symbolDrawn: Bool = true
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
|||||||
170
TigerDine/Views/FeedbackView.swift
Normal file
170
TigerDine/Views/FeedbackView.swift
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
//
|
||||||
|
// FeedbackView.swift
|
||||||
|
// TigerDine
|
||||||
|
//
|
||||||
|
// Created by Campbell on 2/16/26.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import MessageUI
|
||||||
|
|
||||||
|
struct FeedbackView: View {
|
||||||
|
@Environment(\.dismiss) var dismiss
|
||||||
|
@Environment(\.openURL) private var openURL
|
||||||
|
|
||||||
|
@State private var showingMailView = false
|
||||||
|
@State private var mailResult: Result<MFMailComposeResult, Error>? = nil
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationView {
|
||||||
|
ScrollView {
|
||||||
|
VStack(alignment: .leading, spacing: 12) {
|
||||||
|
HStack {
|
||||||
|
Image(systemName: "paperplane")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
Text("Submit Feedback")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.font(.title)
|
||||||
|
}
|
||||||
|
Text("Did I break something? Oops.")
|
||||||
|
Text("Or maybe you just have a suggestion to make TigerDine even cooler. Either way, I'd love to hear your feedback! (Or maybe the hours for a location are off, in which case that feedback is RIT's to handle.)")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
Text("Incorrect Location Hours")
|
||||||
|
.padding(.top, 12)
|
||||||
|
Button(action: {
|
||||||
|
openURL(URL(string: "https://www.rit.edu/dining/locations")!)
|
||||||
|
}) {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
Image(systemName: "clock.badge.questionmark")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Confirm Against the RIT Website")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
Text("Check that the hours displayed in TigerDine match RIT's website.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.forward")
|
||||||
|
}
|
||||||
|
.padding(.all, 6)
|
||||||
|
.background (
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.secondary.opacity(0.1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
Button(action: {
|
||||||
|
openURL(URL(string: "https://www.rit.edu/its/support")!)
|
||||||
|
}) {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
Image(systemName: "clock.badge.exclamationmark")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Submit an ITS Ticket")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
Text("If hours are also incorrect on RIT's website, submit a ticket to ITS.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.forward")
|
||||||
|
}
|
||||||
|
.padding(.all, 6)
|
||||||
|
.background (
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.secondary.opacity(0.1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
Text("If the hours do not match between TigerDine and RIT's website, please contact me instead and I'll look into it.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.font(.caption)
|
||||||
|
Text("TigerDine Issues and Feedback")
|
||||||
|
.padding(.top, 12)
|
||||||
|
Button(action: {
|
||||||
|
openURL(URL(string: "https://github.com/NinjaCheetah/TigerDine/issues")!)
|
||||||
|
}) {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
Image(systemName: "ant.circle")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Submit a GitHub Issue")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
Text("Report a bug or suggest a feature on TigerDine's GitHub repository.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.forward")
|
||||||
|
}
|
||||||
|
.padding(.all, 6)
|
||||||
|
.background (
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.secondary.opacity(0.1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
Button(action: {
|
||||||
|
showingMailView = true
|
||||||
|
}) {
|
||||||
|
HStack(alignment: .center) {
|
||||||
|
Image(systemName: "envelope.circle")
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 50, height: 50)
|
||||||
|
.foregroundStyle(Color.accentColor)
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Send Me an Email")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
Text("Not a GitHub user? Feel free to submit feedback via email.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.multilineTextAlignment(.leading)
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
Image(systemName: "chevron.forward")
|
||||||
|
}
|
||||||
|
.padding(.all, 6)
|
||||||
|
.background (
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.fill(Color.secondary.opacity(0.1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.disabled(!MailView.canSendMail())
|
||||||
|
.sheet(isPresented: $showingMailView) {
|
||||||
|
MailView(result: $mailResult)
|
||||||
|
}
|
||||||
|
Text("Just don't spam my inbox, please and thank you.")
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.toolbar {
|
||||||
|
Button(action: {
|
||||||
|
dismiss()
|
||||||
|
}) {
|
||||||
|
Image(systemName: "xmark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
FeedbackView()
|
||||||
|
}
|
||||||
56
TigerDine/Views/Fragments/MailView.swift
Normal file
56
TigerDine/Views/Fragments/MailView.swift
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// MailView.swift
|
||||||
|
// TigerDine
|
||||||
|
//
|
||||||
|
// Created by Campbell on 2/16/26.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import MessageUI
|
||||||
|
|
||||||
|
// More gross yucky UIKit code :(
|
||||||
|
// Unfortunately there's no native SwiftUI MailView.
|
||||||
|
struct MailView: UIViewControllerRepresentable {
|
||||||
|
@Environment(\.dismiss) var dismiss
|
||||||
|
@Binding var result: Result<MFMailComposeResult, Error>?
|
||||||
|
|
||||||
|
class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
|
||||||
|
var parent: MailView
|
||||||
|
|
||||||
|
init(_ parent: MailView) {
|
||||||
|
self.parent = parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
|
||||||
|
defer {
|
||||||
|
parent.dismiss()
|
||||||
|
}
|
||||||
|
if let error = error {
|
||||||
|
parent.result = .failure(error)
|
||||||
|
} else {
|
||||||
|
parent.result = .success(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> MFMailComposeViewController {
|
||||||
|
let vc = MFMailComposeViewController()
|
||||||
|
vc.mailComposeDelegate = context.coordinator
|
||||||
|
vc.setToRecipients(["campbell@ninjacheetah.dev"])
|
||||||
|
vc.setSubject("TigerDine Feedback")
|
||||||
|
//vc.setMessageBody("", isHTML: false)
|
||||||
|
return vc
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: MFMailComposeViewController, context: Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static func canSendMail() -> Bool {
|
||||||
|
return MFMailComposeViewController.canSendMail()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user