Changed icon to new RIT-trademark-free one

Replaced the icon with a more generic tiger pawprint so that I'm not using an RIT trademark, so that I'm prepared for the first App Store release. Also added information about where menu information is being sourced from on the about screen, and fixed a bug where vegetarian/vegan/no beef/no pork toggles would not be written to UserDefaults.
This commit is contained in:
Campbell 2025-11-12 21:56:50 -05:00
parent 32203033b6
commit e5d87ca488
Signed by: NinjaCheetah
GPG Key ID: 39C2500E1778B156
15 changed files with 97 additions and 65 deletions

View File

@ -265,7 +265,7 @@
CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements"; CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19; CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@ -300,7 +300,7 @@
CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements"; CODE_SIGN_ENTITLEMENTS = "RIT Dining/RIT Dining.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19; CURRENT_PROJECT_VERSION = 20;
DEVELOPMENT_TEAM = 5GF7GKNTK4; DEVELOPMENT_TEAM = 5GF7GKNTK4;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;

View File

@ -1,7 +1,30 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "RIT Dining Temp Logo.png", "filename" : "TigerDine Temp Logo-iOS-Default-1024x1024@1x.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "TigerDine Temp Logo-iOS-Dark-1024x1024@1x.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"idiom" : "universal", "idiom" : "universal",
"platform" : "ios", "platform" : "ios",
"size" : "1024x1024" "size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "RIT Dining Temp Logo.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,7 +1,17 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "RIT Dining Temp Logo.png", "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",
"idiom" : "universal" "idiom" : "universal"
} }
], ],

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -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 // 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. // case, then we should fall back on componentName, which is less user-friendly but works as a backup.
let realName = if recipe.englishAlternateName != "" { let realName = if recipe.englishAlternateName != "" {
recipe.englishAlternateName recipe.englishAlternateName.trimmingCharacters(in: .whitespaces)
} else { } else {
recipe.componentName recipe.componentName.trimmingCharacters(in: .whitespaces)
} }
let allergens = recipe.allergenName != "" ? recipe.allergenName.components(separatedBy: ",") : [] 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 // Get the list of dietary markers (Vegan, Vegetarian, Pork, Beef), and drop "Vegetarian" if "Vegan" is also included since

View File

@ -7,10 +7,10 @@
import SwiftUI import SwiftUI
@Observable class MenuDietaryRestrictionsModel: ObservableObject {
class MenuDietaryRestrictionsModel {
var filteredDietaryMarkers: Set<String> = []
var dietaryRestrictions = DietaryRestrictions() var dietaryRestrictions = DietaryRestrictions()
var isVegetarian: Bool = false @AppStorage("isVegetarian") var isVegetarian: Bool = false
var isVegan: Bool = false @AppStorage("isVegan") var isVegan: Bool = false
@AppStorage("noBeef") var noBeef: Bool = false
@AppStorage("noPork") var noPork: Bool = false
} }

View File

@ -20,35 +20,42 @@ struct AboutView: View {
.clipShape(RoundedRectangle(cornerRadius: 20)) .clipShape(RoundedRectangle(cornerRadius: 20))
Text("TigerDine") Text("TigerDine")
.font(.title) .font(.title)
.fontWeight(.bold)
Text("An unofficial RIT Dining app") Text("An unofficial RIT Dining app")
.font(.subheadline) .font(.subheadline)
Text("Version \(appVersionString) (\(buildNumber))") Text("Version \(appVersionString) (\(buildNumber))")
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
.padding(.bottom, 2) .padding(.bottom, 2)
VStack(alignment: .leading, spacing: 10) { 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.") 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("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.") 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.")
HStack { VStack(alignment: .center, spacing: 8) {
Button(action: { HStack(spacing: 8) {
openURL(URL(string: "https://github.com/NinjaCheetah/TigerDine")!) Button(action: {
}) { openURL(URL(string: "https://github.com/NinjaCheetah/TigerDine")!)
Text("Source Code") }) {
Label("Source Code", systemImage: "network")
}
Button(action: {
openURL(URL(string: "https://tigercenter.rit.edu/")!)
}) {
Label("TigerCenter", systemImage: "fork.knife.circle")
}
} }
Text("") HStack(spacing: 8) {
.foregroundStyle(.secondary) Button(action: {
Button(action: { openURL(URL(string: "https://maps.rit.edu/")!)
openURL(URL(string: "https://tigercenter.rit.edu/")!) }) {
}) { Label("Official RIT Map", systemImage: "map")
Text("TigerCenter") }
} Button(action: {
Text("") openURL(URL(string: "https://fdmealplanner.com/")!)
.foregroundStyle(.secondary) }) {
Button(action: { Label("FD MealPlanner", systemImage: "menucard")
openURL(URL(string: "https://maps.rit.edu/")!) }
}) {
Text("Official RIT Map")
} }
} }
.frame(maxWidth: .infinity)
} }
Spacer() Spacer()
} }

View File

@ -15,32 +15,10 @@ struct MenuDietaryRestrictionsSheet: View {
NavigationView { NavigationView {
Form { Form {
Section(header: Text("Diet")) { Section(header: Text("Diet")) {
Toggle(isOn: Binding( Toggle(isOn: $dietaryRestrictionsModel.noBeef) {
get: {
dietaryRestrictionsModel.filteredDietaryMarkers.contains("Beef")
},
set: { isOn in
if isOn {
dietaryRestrictionsModel.filteredDietaryMarkers.insert("Beef")
} else {
dietaryRestrictionsModel.filteredDietaryMarkers.remove("Beef")
}
} )
) {
Text("No Beef") Text("No Beef")
} }
Toggle(isOn: Binding( Toggle(isOn: $dietaryRestrictionsModel.noPork) {
get: {
dietaryRestrictionsModel.filteredDietaryMarkers.contains("Pork")
},
set: { isOn in
if isOn {
dietaryRestrictionsModel.filteredDietaryMarkers.insert("Pork")
} else {
dietaryRestrictionsModel.filteredDietaryMarkers.remove("Pork")
}
} )
) {
Text("No Pork") Text("No Pork")
} }
Toggle(isOn: $dietaryRestrictionsModel.isVegetarian) { Toggle(isOn: $dietaryRestrictionsModel.isVegetarian) {

View File

@ -65,17 +65,6 @@ struct MenuView: View {
private var filteredMenuItems: [FDMenuItem] { private var filteredMenuItems: [FDMenuItem] {
var newItems = menuItems 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. // Filter out allergens.
newItems = newItems.filter { item in newItems = newItems.filter { item in
if !item.allergens.isEmpty { if !item.allergens.isEmpty {
@ -100,6 +89,17 @@ struct MenuView: View {
return false 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. // Filter down to search contents.
newItems = newItems.filter { item in newItems = newItems.filter { item in
let searchedLocations = searchText.isEmpty || item.name.localizedCaseInsensitiveContains(searchText) let searchedLocations = searchText.isEmpty || item.name.localizedCaseInsensitiveContains(searchText)