mirror of
https://github.com/NinjaCheetah/RIT-Dining.git
synced 2025-12-02 01:21:35 -05:00
Compare commits
No commits in common. "6613630aa253432ae30063ded6a76b86fecda093" and "32203033b6d192087af1cfc8b50ac0879e27c3bf" have entirely different histories.
6613630aa2
...
32203033b6
@ -1,2 +0,0 @@
|
||||
# Privacy Policy for TigerDine
|
||||
TigerDine does not collect, store, or share any personal data.
|
||||
@ -265,7 +265,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 19;
|
||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@ -300,7 +300,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 21;
|
||||
CURRENT_PROJECT_VERSION = 19;
|
||||
DEVELOPMENT_TEAM = 5GF7GKNTK4;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 167 KiB |
@ -1,37 +0,0 @@
|
||||
{
|
||||
"fill" : {
|
||||
"automatic-gradient" : "gray:0.90568,1.00000"
|
||||
},
|
||||
"groups" : [
|
||||
{
|
||||
"layers" : [
|
||||
{
|
||||
"glass" : false,
|
||||
"image-name" : "TigerDine Temp Logo Emblem.png",
|
||||
"name" : "TigerDine Temp Logo Emblem",
|
||||
"position" : {
|
||||
"scale" : 0.9,
|
||||
"translation-in-points" : [
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"shadow" : {
|
||||
"kind" : "neutral",
|
||||
"opacity" : 0.5
|
||||
},
|
||||
"translucency" : {
|
||||
"enabled" : true,
|
||||
"value" : 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"supported-platforms" : {
|
||||
"circles" : [
|
||||
"watchOS"
|
||||
],
|
||||
"squares" : "shared"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 140 KiB |
@ -1,17 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "TigerDine Temp Logo-iOS-Default-1024x1024@1x.png",
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "TigerDine Temp Logo-iOS-Dark-1024x1024@1x.png",
|
||||
"filename" : "RIT Dining Temp Logo.png",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
||||
BIN
RIT Dining/Assets.xcassets/Icon.imageset/RIT Dining Temp Logo.png
vendored
Normal file
BIN
RIT Dining/Assets.xcassets/Icon.imageset/RIT Dining Temp Logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 140 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 784 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 MiB |
@ -24,9 +24,9 @@ func parseFDMealPlannerMenu(menu: FDMealsParser) -> [FDMenuItem] {
|
||||
// englishAlternateName holds the proper name of the item, but it's blank for some items for some reason. If that's the
|
||||
// case, then we should fall back on componentName, which is less user-friendly but works as a backup.
|
||||
let realName = if recipe.englishAlternateName != "" {
|
||||
recipe.englishAlternateName.trimmingCharacters(in: .whitespaces)
|
||||
recipe.englishAlternateName
|
||||
} else {
|
||||
recipe.componentName.trimmingCharacters(in: .whitespaces)
|
||||
recipe.componentName
|
||||
}
|
||||
let allergens = recipe.allergenName != "" ? recipe.allergenName.components(separatedBy: ",") : []
|
||||
// Get the list of dietary markers (Vegan, Vegetarian, Pork, Beef), and drop "Vegetarian" if "Vegan" is also included since
|
||||
|
||||
@ -7,31 +7,10 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class MenuDietaryRestrictionsModel: ObservableObject {
|
||||
@Observable
|
||||
class MenuDietaryRestrictionsModel {
|
||||
var filteredDietaryMarkers: Set<String> = []
|
||||
var dietaryRestrictions = DietaryRestrictions()
|
||||
|
||||
// I thought these could be @AppStorage keys but apparently not, because SwiftUI would subscribe to updates from those if
|
||||
// they aren't being used directly inside the view.
|
||||
@Published var isVegetarian: Bool {
|
||||
didSet { UserDefaults.standard.set(isVegetarian, forKey: "isVegetarian") }
|
||||
}
|
||||
|
||||
@Published var isVegan: Bool {
|
||||
didSet { UserDefaults.standard.set(isVegan, forKey: "isVegan") }
|
||||
}
|
||||
|
||||
@Published var noBeef: Bool {
|
||||
didSet { UserDefaults.standard.set(noBeef, forKey: "noBeef") }
|
||||
}
|
||||
|
||||
@Published var noPork: Bool {
|
||||
didSet { UserDefaults.standard.set(noPork, forKey: "noPork") }
|
||||
}
|
||||
|
||||
init() {
|
||||
self.isVegetarian = UserDefaults.standard.bool(forKey: "isVegetarian")
|
||||
self.isVegan = UserDefaults.standard.bool(forKey: "isVegan")
|
||||
self.noBeef = UserDefaults.standard.bool(forKey: "noBeef")
|
||||
self.noPork = UserDefaults.standard.bool(forKey: "noPork")
|
||||
}
|
||||
var isVegetarian: Bool = false
|
||||
var isVegan: Bool = false
|
||||
}
|
||||
|
||||
@ -20,42 +20,35 @@ struct AboutView: View {
|
||||
.clipShape(RoundedRectangle(cornerRadius: 20))
|
||||
Text("TigerDine")
|
||||
.font(.title)
|
||||
.fontWeight(.bold)
|
||||
Text("An unofficial RIT Dining app")
|
||||
.font(.subheadline)
|
||||
Text("Version \(appVersionString) (\(buildNumber))")
|
||||
.foregroundStyle(.secondary)
|
||||
.padding(.bottom, 2)
|
||||
VStack(alignment: .leading, spacing: 10) {
|
||||
Text("Dining locations, their descriptions, and their opening hours are sourced from the RIT student-run TigerCenter API. Building occupancy information is sourced from the official RIT maps API. Menu and nutritional information is sourced from the data provided to FD MealPlanner by RIT Dining through the FD MealPlanner API.")
|
||||
Text("Dining locations, their descriptions, and their opening hours are sourced from the RIT student-run TigerCenter API. Building occupancy information is sourced from the official RIT maps API.")
|
||||
Text("This app is not affiliated, associated, authorized, endorsed by, or in any way officially connected with the Rochester Institute of Technology. This app is student created and maintained.")
|
||||
VStack(alignment: .center, spacing: 8) {
|
||||
HStack(spacing: 8) {
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://github.com/NinjaCheetah/TigerDine")!)
|
||||
}) {
|
||||
Label("Source Code", systemImage: "network")
|
||||
}
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://tigercenter.rit.edu/")!)
|
||||
}) {
|
||||
Label("TigerCenter", systemImage: "fork.knife.circle")
|
||||
}
|
||||
HStack {
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://github.com/NinjaCheetah/TigerDine")!)
|
||||
}) {
|
||||
Text("Source Code")
|
||||
}
|
||||
HStack(spacing: 8) {
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://maps.rit.edu/")!)
|
||||
}) {
|
||||
Label("Official RIT Map", systemImage: "map")
|
||||
}
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://fdmealplanner.com/")!)
|
||||
}) {
|
||||
Label("FD MealPlanner", systemImage: "menucard")
|
||||
}
|
||||
Text("•")
|
||||
.foregroundStyle(.secondary)
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://tigercenter.rit.edu/")!)
|
||||
}) {
|
||||
Text("TigerCenter")
|
||||
}
|
||||
Text("•")
|
||||
.foregroundStyle(.secondary)
|
||||
Button(action: {
|
||||
openURL(URL(string: "https://maps.rit.edu/")!)
|
||||
}) {
|
||||
Text("Official RIT Map")
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
|
||||
@ -9,16 +9,38 @@ import SwiftUI
|
||||
|
||||
struct MenuDietaryRestrictionsSheet: View {
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@ObservedObject var dietaryRestrictionsModel: MenuDietaryRestrictionsModel
|
||||
@Binding var dietaryRestrictionsModel: MenuDietaryRestrictionsModel
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
Form {
|
||||
Section(header: Text("Diet")) {
|
||||
Toggle(isOn: $dietaryRestrictionsModel.noBeef) {
|
||||
Toggle(isOn: Binding(
|
||||
get: {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.contains("Beef")
|
||||
},
|
||||
set: { isOn in
|
||||
if isOn {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.insert("Beef")
|
||||
} else {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.remove("Beef")
|
||||
}
|
||||
} )
|
||||
) {
|
||||
Text("No Beef")
|
||||
}
|
||||
Toggle(isOn: $dietaryRestrictionsModel.noPork) {
|
||||
Toggle(isOn: Binding(
|
||||
get: {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.contains("Pork")
|
||||
},
|
||||
set: { isOn in
|
||||
if isOn {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.insert("Pork")
|
||||
} else {
|
||||
dietaryRestrictionsModel.filteredDietaryMarkers.remove("Pork")
|
||||
}
|
||||
} )
|
||||
) {
|
||||
Text("No Pork")
|
||||
}
|
||||
Toggle(isOn: $dietaryRestrictionsModel.isVegetarian) {
|
||||
|
||||
@ -17,7 +17,7 @@ struct MenuView: View {
|
||||
@State private var rotationDegrees: Double = 0
|
||||
@State private var selectedMealPeriod: Int = 0
|
||||
@State private var openPeriods: [Int] = []
|
||||
@StateObject private var dietaryRestrictionsModel = MenuDietaryRestrictionsModel()
|
||||
@State private var dietaryRestrictionsModel = MenuDietaryRestrictionsModel()
|
||||
@State private var showingDietaryRestrictionsSheet: Bool = false
|
||||
|
||||
private var animation: Animation {
|
||||
@ -65,6 +65,17 @@ struct MenuView: View {
|
||||
|
||||
private var filteredMenuItems: [FDMenuItem] {
|
||||
var newItems = menuItems
|
||||
// Filter out dietary restrictions, starting with pork/beef since those are tagged.
|
||||
if !dietaryRestrictionsModel.filteredDietaryMarkers.isEmpty {
|
||||
newItems = newItems.filter { item in
|
||||
for marker in dietaryRestrictionsModel.filteredDietaryMarkers {
|
||||
if item.dietaryMarkers.contains(marker) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
// Filter out allergens.
|
||||
newItems = newItems.filter { item in
|
||||
if !item.allergens.isEmpty {
|
||||
@ -89,17 +100,6 @@ struct MenuView: View {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// Filter out pork/beef.
|
||||
if dietaryRestrictionsModel.noBeef {
|
||||
newItems = newItems.filter { item in
|
||||
item.dietaryMarkers.contains("Beef") == false
|
||||
}
|
||||
}
|
||||
if dietaryRestrictionsModel.noPork {
|
||||
newItems = newItems.filter { item in
|
||||
item.dietaryMarkers.contains("Pork") == false
|
||||
}
|
||||
}
|
||||
// Filter down to search contents.
|
||||
newItems = newItems.filter { item in
|
||||
let searchedLocations = searchText.isEmpty || item.name.localizedCaseInsensitiveContains(searchText)
|
||||
@ -225,7 +225,7 @@ struct MenuView: View {
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $showingDietaryRestrictionsSheet) {
|
||||
MenuDietaryRestrictionsSheet(dietaryRestrictionsModel: dietaryRestrictionsModel)
|
||||
MenuDietaryRestrictionsSheet(dietaryRestrictionsModel: $dietaryRestrictionsModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user