Skip to content

Commit

Permalink
Merge branch 'main' into anli/09-17-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
anli5005 committed Jan 21, 2024
2 parents 38a13ba + d19c818 commit 9ed39ca
Show file tree
Hide file tree
Showing 11 changed files with 335 additions and 58 deletions.
12 changes: 8 additions & 4 deletions PennMobile.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
CF29A1771FB788820067D946 /* OnboardingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF29A1671FB7887E0067D946 /* OnboardingController.swift */; };
CF29A1781FB788820067D946 /* PageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF29A1681FB7887E0067D946 /* PageCell.swift */; };
CF7FCA761FAFCD9E0052F0A9 /* RoomSelectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF7FCA751FAFCD9E0052F0A9 /* RoomSelectionViewController.swift */; };
E735C9422AF81498000F7376 /* DiningSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E735C9412AF81498000F7376 /* DiningSettingsView.swift */; };
EF23946423EF4117005BA55F /* GSRGroupInviteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF23946323EF4117005BA55F /* GSRGroupInviteCell.swift */; };
EF30077223EE1380006C9CF0 /* HomeGroupInvitesCellItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF30077123EE1380006C9CF0 /* HomeGroupInvitesCellItem.swift */; };
EF30077423EE139F006C9CF0 /* HomeGroupInvitesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF30077323EE139F006C9CF0 /* HomeGroupInvitesCell.swift */; };
Expand Down Expand Up @@ -706,6 +707,7 @@
CF29A1671FB7887E0067D946 /* OnboardingController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingController.swift; sourceTree = "<group>"; };
CF29A1681FB7887E0067D946 /* PageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageCell.swift; sourceTree = "<group>"; };
CF7FCA751FAFCD9E0052F0A9 /* RoomSelectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSelectionViewController.swift; sourceTree = "<group>"; };
E735C9412AF81498000F7376 /* DiningSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiningSettingsView.swift; sourceTree = "<group>"; };
EF23946323EF4117005BA55F /* GSRGroupInviteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GSRGroupInviteCell.swift; sourceTree = "<group>"; };
EF30077123EE1380006C9CF0 /* HomeGroupInvitesCellItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeGroupInvitesCellItem.swift; sourceTree = "<group>"; };
EF30077323EE139F006C9CF0 /* HomeGroupInvitesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeGroupInvitesCell.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1428,6 +1430,7 @@
6CC88D5627B1BF50006896F6 /* DiningViewControllerSwiftUI.swift */,
6CC88D5527B1BF50006896F6 /* DiningViewModelSwiftUI.swift */,
6CC88D3527B1BF50006896F6 /* Views */,
E735C9412AF81498000F7376 /* DiningSettingsView.swift */,
);
path = SwiftUI;
sourceTree = "<group>";
Expand Down Expand Up @@ -2560,6 +2563,7 @@
89913EAD2AE44FCE00AE30C9 /* CalendarCardView.swift in Sources */,
2190FD351EC625BB00EC683C /* Protocols.swift in Sources */,
2189C0A82027CE4B00771C1F /* ThumbLayer.swift in Sources */,
E735C9422AF81498000F7376 /* DiningSettingsView.swift in Sources */,
21B653B92245EB67001A97C5 /* PennAuthRequestable.swift in Sources */,
89E0DE682AE38A8800E918FF /* HomeView.swift in Sources */,
421B03CA29E22035003AE6DC /* FitnessRoomRow.swift in Sources */,
Expand Down Expand Up @@ -2722,7 +2726,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CF_BUNDLE_LONG_VERSION_STRING = 6700;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.8;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.9;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
Expand Down Expand Up @@ -2784,7 +2788,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CF_BUNDLE_LONG_VERSION_STRING = 6700;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.8;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.9;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
Expand Down Expand Up @@ -2842,7 +2846,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = navigation;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.8;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.9;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = PennMobile/PennMobile.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
Expand Down Expand Up @@ -2884,7 +2888,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = navigation;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.8;
CF_BUNDLE_SHORT_VERSION_STRING = 7.3.9;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = PennMobile/PennMobile.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution";
Expand Down
32 changes: 14 additions & 18 deletions PennMobile/Auth/PennLoginController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,28 +76,24 @@ class PennLoginController: UIViewController, WKUIDelegate, WKNavigationDelegate
// Webview has redirected to desired site.
self.handleSuccessfulNavigation(webView, decisionHandler: decisionHandler)
} else {
if url.absoluteString.contains("password") {
webView.evaluateJavaScript("document.getElementById('pennname').value;") { (result, _) in
if let pennkey = result as? String {
webView.evaluateJavaScript("document.getElementById('password').value;") { (result, _) in
if let password = result as? String {
if !pennkey.isEmpty && !password.isEmpty {
self.pennkey = pennkey
self.password = password
if pennkey == "root" && password == "root" {
self.handleDefaultLogin(decisionHandler: decisionHandler)
return
}
webView.evaluateJavaScript("document.querySelector('input[name=j_username]').value;") { (result, _) in
if let pennkey = result as? String {
webView.evaluateJavaScript("document.querySelector('input[name=j_password]').value;") { (result, _) in
if let password = result as? String {
if !pennkey.isEmpty && !password.isEmpty {
self.pennkey = pennkey
self.password = password
if pennkey == "root" && password == "root" {
self.handleDefaultLogin(decisionHandler: decisionHandler)
return
}
}
decisionHandler(.allow)
}
} else {
decisionHandler(.allow)
}
} else {
decisionHandler(.allow)
}
} else {
decisionHandler(.allow)
}
}
}
Expand All @@ -123,7 +119,7 @@ class PennLoginController: UIViewController, WKUIDelegate, WKNavigationDelegate
return
}

if url.absoluteString.contains("twostep") {
if url.absoluteString.contains("prompt") {
guard let pennkey = pennkey, let password = password else { return }
if password != KeychainAccessible.instance.getPassword() {
UserDBManager.shared.updateAnonymizationKeys()
Expand All @@ -138,7 +134,7 @@ class PennLoginController: UIViewController, WKUIDelegate, WKNavigationDelegate

func autofillCredentials() {
guard let pennkey = pennkey else { return }
webView.evaluateJavaScript("document.getElementById('pennname').value = '\(pennkey)'") { (_, _) in
webView.evaluateJavaScript("document.getElementById('username').value = '\(pennkey)'") { (_, _) in
}
guard let password = password else { return }
webView.evaluateJavaScript("document.getElementById('password').value = '\(password)'") { (_, _) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//
import Foundation
import SwiftyJSON
import PennMobileShared

struct Response: Decodable {
let message: String
Expand All @@ -25,6 +26,7 @@ class CourseAlertNetworkManager: NSObject, Requestable {
let settingsURL = "https://penncoursealert.com/accounts/me/"
let coursesURL = "https://penncoursealert.com/api/base/"
let registrationsURL = "https://penncoursealert.com/api/alert/registrations/"
let pathRegistrationURL = "https://penncourseplan.com/api/plan/schedules/path/"

func getSearchedCourses(searchText: String, _ callback: @escaping (_ results: [CourseSection]?) -> Void) {

Expand Down Expand Up @@ -158,6 +160,26 @@ class CourseAlertNetworkManager: NSObject, Requestable {
}
}

func updatePathRegistration(srcdb: String, crns: [String]) async throws {
let params: [String: Any] = ["semester": srcdb, "sections": crns.map { ["id": $0] }]

return try await withCheckedThrowingContinuation { continuation in
makeAuthenticatedRequest(url: pathRegistrationURL, requestType: RequestType.PUT, params: params) { (data, response, error) in
if let error {
continuation.resume(throwing: error)
return
}

guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
continuation.resume(throwing: NetworkingError.serverError)
return
}

continuation.resume(returning: ())
}
}
}

}

// MARK: - General Networking Functions
Expand Down Expand Up @@ -233,10 +255,10 @@ extension CourseAlertNetworkManager {
if let CSRFDict = (UserDefaults.standard.dictionary(forKey: "cookies"))?["csrftokenplatform.pennlabs.org"] as? [String: Any] {
if let csrfToken = CSRFDict["Value"] as? String {
callback(csrfToken)
} else {
callback(nil)
return
}
}

callback(nil)
}

Expand Down
2 changes: 1 addition & 1 deletion PennMobile/Courses/Views/CoursesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ struct CoursesView: View {
.foregroundColor(.red)
.padding()
.onAppear {
if case PathAtPennError.noTokenFound = error {
if case PathAtPennError.noTokenFound(_) = error {
isPresentingLoginSheet = true
}
}
Expand Down
2 changes: 1 addition & 1 deletion PennMobile/Dining/Controllers/DiningLoginController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class DiningLoginController: UIViewController, WKUIDelegate, WKNavigationDelegat

if url.absoluteString.contains("https://weblogin.pennkey.upenn.edu/") {
guard let pennkey = KeychainAccessible.instance.getPennKey(), let password = KeychainAccessible.instance.getPassword() else { return }
webView.evaluateJavaScript("document.getElementById('pennname').value = '\(pennkey)'") { (_, _) in
webView.evaluateJavaScript("document.getElementById('username').value = '\(pennkey)'") { (_, _) in
webView.evaluateJavaScript("document.getElementById('password').value = '\(password)'") { (_, _) in
}
}
Expand Down
34 changes: 29 additions & 5 deletions PennMobile/Dining/SwiftUI/DiningAnalyticsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ struct DiningAnalyticsView: View {
@State var showMissingDiningTokenAlert = false
@State var showDiningLoginView = false
@State var notLoggedInAlertShowing = false
@State var showSettingsSheet = false
@Environment(\.presentationMode) var presentationMode
func showCorrectAlert () -> Alert {
if !Account.isLoggedIn {
Expand All @@ -30,17 +31,33 @@ struct DiningAnalyticsView: View {
let dollarHistory = $diningAnalyticsViewModel.dollarHistory
let swipeHistory = $diningAnalyticsViewModel.swipeHistory
HStack {
Spacer()
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
showSettingsSheet.toggle()
}) {
Image(systemName: "gear")
.imageScale(.large)
}
}
}
if Account.isLoggedIn, let diningExpiration = UserDefaults.standard.getDiningTokenExpiration(), Date() <= diningExpiration {
if dollarHistory.wrappedValue.isEmpty && swipeHistory.wrappedValue.isEmpty {
ZStack {
Image("DiningAnalyticsBackground")
.resizable()
.ignoresSafeArea()
Text("No Dining\nPlan Found\n ")
.multilineTextAlignment(.center)
.font(.system(size: 48, weight: .regular))
.foregroundColor(.black)
.opacity(0.6)
VStack(spacing: 24) {
Text("No Dining Plan Found")
.font(.system(size: 48, weight: .regular))
Text("Dining Analytics may not appear until the day after the semester begins.")
}
.frame(maxWidth: 280)
.padding(.bottom, 64)
.multilineTextAlignment(.center)
.foregroundColor(.black)
.opacity(0.6)
}
} else {
ScrollView {
Expand Down Expand Up @@ -78,6 +95,9 @@ struct DiningAnalyticsView: View {
.environmentObject(diningAnalyticsViewModel)
}
.navigationTitle(Text("Dining Analytics"))
.sheet(isPresented: $showSettingsSheet) {
DiningSettingsView(viewModel: diningAnalyticsViewModel) // Replace with your settings view
}
} else {
let dollarXYHistory = Binding(
get: {
Expand Down Expand Up @@ -139,6 +159,10 @@ struct DiningAnalyticsView: View {
DiningLoginNavigationView()
.environmentObject(diningAnalyticsViewModel)
}
.navigationTitle("Analytics")
.sheet(isPresented: $showSettingsSheet) {
DiningSettingsView(viewModel: diningAnalyticsViewModel)
}
}
}
}
Expand Down
73 changes: 73 additions & 0 deletions PennMobile/Dining/SwiftUI/DiningSettingsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// DiningSettingsView.swift
// PennMobile
//
// Created by Christina Qiu on 11/5/23.
// Copyright © 2023 PennLabs. All rights reserved.
//

import SwiftUI
import PennMobileShared

struct DiningSettingsView: View {
@ObservedObject var viewModel: DiningAnalyticsViewModel

@Environment(\.presentationMode) var presentationMode
@State private var totalData = false
private let options = ["All data",
"Smart calculation",
"Weighted average"]

var body: some View {
if #available(iOS 16.0, *) {
NavigationView {
Form {
Picker(selection: $viewModel.selectedOptionIndex, label: Text("Slope Calculation")) {
ForEach(0..<options.count, id: \.self) { index in
Text(options[index]).tag(index)
}
}
.pickerStyle(MenuPickerStyle())

// Toggle("Include guest swipes", isOn: $totalData)
}
.navigationBarTitle("Dining Analytics Settings", displayMode: .inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
.presentationDetents([.medium])
} else {
NavigationView {
Form {
Picker(selection: $viewModel.selectedOptionIndex, label: Text("Slope Calculation")) {
ForEach(0..<options.count, id: \.self) { index in
Text(options[index]).tag(index)
}
}
.pickerStyle(MenuPickerStyle())

// Toggle("Include guest swipes", isOn: $totalData)
}
.navigationBarTitle("Dining Analytics Settings", displayMode: .inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Text("Done")
}
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
}
}
2 changes: 1 addition & 1 deletion PennMobile/Login/LabsLoginController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class LabsLoginController: PennLoginController, IndicatorEnabled, Requestable, S
}

override var shouldLoadCookies: Bool {
return false
return true
}

private let codeVerifier = String.randomString(length: 64)
Expand Down
Loading

0 comments on commit 9ed39ca

Please sign in to comment.