Skip to content

Commit

Permalink
Development: Release 9.0.0 (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
nityanandaz authored Feb 11, 2024
1 parent 7159036 commit b5b5a72
Show file tree
Hide file tree
Showing 16 changed files with 190 additions and 134 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ In Project Settings, on the tab "Package Dependencies", click "+" and add <https
1. Add a dependency in Package.swift:
```swift
dependencies: [
.package(url: "https://github.com/ls1intum/artemis-ios-core-modules", .upToNextMajor(from: "8.0.0")),
.package(url: "https://github.com/ls1intum/artemis-ios-core-modules", .upToNextMajor(from: "9.0.0")),
]
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"images" : [
{
"filename" : "favicon.svg",
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "android-chrome-512x512.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions Sources/Login/Resources/Media.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
21 changes: 11 additions & 10 deletions Sources/Login/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// MARK: LoginView
// MARK: - General
"ok" = "OK";
"select" = "Select";
"done" = "Done";

// MARK: - LoginView
"account_screen_title" = "Welcome to Artemis!";
"account_screen_subtitle" = "Interactive Learning with Individual Feedback";
"login_please_sign_in_account" = "Please sign in with your %@ account.";
Expand All @@ -11,20 +16,16 @@
"account_change_artemis_instance_label" = "Select university";
"login_forgot_password_label" = "Did you forget your password?";
"login_username_validation_tum_info_label" = "If you are a TUM student, your username should have the format ab12xyz. Do not include '@mytum.de' or '@tum.de'.";
// captcha

// MARK: Captcha
"account_captcha_title" = "You have entered your password incorrectly too many times :-(";
"account_captcha_message" = "Please go to [%@](%@), sign in with your account and solve the [CAPTCHA](%@). After you have solved it, try to log in again here.";
"account_captcha_alert_message" = "You entered your password incorrectly. Solve the capture to continue.";

// MARK: InstanceSelectionView
"account_select_artemis_instance_select_text" = "Please select your university:";
// MARK: - InstanceSelectionView
"account_select_artemis_instance_select_title" = "Please Select Your University";
"account_select_artemis_instance_custom_instance" = "Your custom Artemis instance URL";
"account_select_artemis_instance_error" = "The URL is incorrect or does not link to an Artemis instance!";

// MARK: Errors
// MARK: - Errors
"account_session_expired_error" = "Your session expired. Please login again!";

// MARK: General
"ok" = "OK";
"select" = "Select";
"done" = "Done";
1 change: 0 additions & 1 deletion Sources/Login/Services/LoginService/LoginService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Created by Sven Andabaka on 09.01.23.
//

import Foundation
import Common

public protocol LoginService {
Expand Down
5 changes: 2 additions & 3 deletions Sources/Login/Services/LoginService/LoginServiceImpl.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
// Created by Sven Andabaka on 09.01.23.
//

import Foundation
import Account
import APIClient
import UserStore
import Common
import PushNotifications
import Account
import SharedServices
import UserStore

class LoginServiceImpl: LoginService {
private let client = APIClient()
Expand Down
12 changes: 6 additions & 6 deletions Sources/Login/ViewModels/LoginViewModel.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Foundation
import APIClient
import Common
import UserStore
import Combine
import Common
import Foundation
import ProfileInfo
import SharedModels
import UserStore

@MainActor
open class LoginViewModel: ObservableObject {
Expand Down Expand Up @@ -33,7 +33,7 @@ open class LoginViewModel: ObservableObject {
@Published public var usernamePattern: String?
@Published public var showUsernameWarning = false

@Published public var instituiton: InstitutionIdentifier = .tum
@Published public var institution: InstitutionIdentifier = .tum

private var cancellables: Set<AnyCancellable> = Set()

Expand All @@ -43,14 +43,14 @@ open class LoginViewModel: ObservableObject {
self?.username = UserSession.shared.username ?? ""
self?.password = UserSession.shared.password ?? ""
self?.loginExpired = UserSession.shared.tokenExpired
self?.instituiton = UserSession.shared.institution ?? .tum
self?.institution = UserSession.shared.institution ?? .tum
}
}.store(in: &cancellables)

username = UserSession.shared.username ?? ""
password = UserSession.shared.password ?? ""
loginExpired = UserSession.shared.tokenExpired
instituiton = UserSession.shared.institution ?? .tum
institution = UserSession.shared.institution ?? .tum
}

public func login() async {
Expand Down
151 changes: 76 additions & 75 deletions Sources/Login/Views/InstitutionSelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,42 @@
// Created by Sven Andabaka on 01.03.23.
//

import SwiftUI
import UserStore
import DesignLibrary
import ProfileInfo
import SwiftUI
import UserStore

public struct InstitutionSelectionView: View {

@Binding var institution: InstitutionIdentifier

var handleProfileInfoCompletion: @MainActor (ProfileInfo?) -> Void

public init(institution: Binding<InstitutionIdentifier>, handleProfileInfoCompletion: @escaping @MainActor (ProfileInfo?) -> Void) {
public init(
institution: Binding<InstitutionIdentifier>,
handleProfileInfoCompletion: @escaping @MainActor (ProfileInfo?) -> Void
) {
self._institution = institution
self.handleProfileInfoCompletion = handleProfileInfoCompletion
}

public var body: some View {
List {
Text(R.string.localizable.account_select_artemis_instance_select_text())
.font(.headline)
ForEach(InstitutionIdentifier.allCases) { institutionIdentifier in
Group {
if case .custom = institutionIdentifier {
CustomInstanceCell(currentInstitution: $institution,
institution: institutionIdentifier,
handleProfileInfoCompletion: handleProfileInfoCompletion)
} else {
InstanceCell(currentInstitution: $institution,
institution: institutionIdentifier,
handleProfileInfoCompletion: handleProfileInfoCompletion)
}
List(InstitutionIdentifier.allCases) { institutionIdentifier in
Group {
if case .custom = institutionIdentifier {
CustomInstanceCell(
currentInstitution: $institution,
institution: institutionIdentifier,
handleProfileInfoCompletion: handleProfileInfoCompletion)
} else {
InstanceCell(
currentInstitution: $institution,
institution: institutionIdentifier,
handleProfileInfoCompletion: handleProfileInfoCompletion)
}
.listRowSeparator(.hidden)
}
.listRowSeparator(.hidden)
}
.listStyle(PlainListStyle())
.listStyle(.plain)
}
}

Expand All @@ -54,7 +54,6 @@ private struct CustomInstanceCell: View {
@State private var isLoading = false

var institution: InstitutionIdentifier

var handleProfileInfoCompletion: @MainActor (ProfileInfo?) -> Void

var body: some View {
Expand All @@ -75,33 +74,10 @@ private struct CustomInstanceCell: View {
.textFieldStyle(ArtemisTextField())
.keyboardType(.URL)
.background(Color.gray.opacity(0.2))
Button(R.string.localizable.select()) {
guard let url = URL(string: customUrl) else {
showErrorAlert = true
return
}
UserSession.shared.saveInstitution(identifier: .custom(url))

isLoading = true

Task {
let result = await ProfileInfoServiceFactory.shared.getProfileInfo()
isLoading = false
switch result {
case .loading:
isLoading = true
case .failure:
showErrorAlert = true
UserSession.shared.saveInstitution(identifier: .tum)
case .done(let response):
handleProfileInfoCompletion(response)
dismiss()
}
}
}
.buttonStyle(ArtemisButton())
.loadingIndicator(isLoading: $isLoading)
.alert(R.string.localizable.account_select_artemis_instance_error(), isPresented: $showErrorAlert, actions: { })
Button(R.string.localizable.select(), action: select)
.buttonStyle(ArtemisButton())
.loadingIndicator(isLoading: $isLoading)
.alert(R.string.localizable.account_select_artemis_instance_error(), isPresented: $showErrorAlert, actions: { })
}
.frame(maxWidth: .infinity)
.padding(.l)
Expand All @@ -110,16 +86,42 @@ private struct CustomInstanceCell: View {
if case .custom(let url) = institution {
customUrl = url?.absoluteString ?? ""
}
}.onAppear {
}
.onAppear {
if case .custom(let url) = currentInstitution {
customUrl = url?.absoluteString ?? ""
}
}
}

@MainActor
func select() {
guard let url = URL(string: customUrl) else {
showErrorAlert = true
return
}
UserSession.shared.saveInstitution(identifier: .custom(url))

isLoading = true

Task {
let result = await ProfileInfoServiceFactory.shared.getProfileInfo()
isLoading = false
switch result {
case .loading:
isLoading = true
case .failure:
showErrorAlert = true
UserSession.shared.saveInstitution(identifier: .tum)
case .done(let response):
handleProfileInfoCompletion(response)
dismiss()
}
}
}
}

private struct InstanceCell: View {

@Environment(\.dismiss) var dismiss

@Binding var currentInstitution: InstitutionIdentifier
Expand All @@ -128,7 +130,6 @@ private struct InstanceCell: View {
@State private var isLoading = false

var institution: InstitutionIdentifier

var handleProfileInfoCompletion: @MainActor (ProfileInfo?) -> Void

var body: some View {
Expand All @@ -148,33 +149,35 @@ private struct InstanceCell: View {
.cardModifier()
.loadingIndicator(isLoading: $isLoading)
.alert(R.string.localizable.account_select_artemis_instance_error(), isPresented: $showErrorAlert, actions: { })
.onTapGesture {
UserSession.shared.saveInstitution(identifier: institution)
Task {
let result = await ProfileInfoServiceFactory.shared.getProfileInfo()
isLoading = false
switch result {
case .loading:
isLoading = true
case .failure:
showErrorAlert = true
UserSession.shared.saveInstitution(identifier: .tum)
case .done(let response):
handleProfileInfoCompletion(response)
dismiss()
}
.onTapGesture(perform: select)
}

@MainActor
func select() {
UserSession.shared.saveInstitution(identifier: institution)
Task {
let result = await ProfileInfoServiceFactory.shared.getProfileInfo()
isLoading = false
switch result {
case .loading:
isLoading = true
case .failure:
showErrorAlert = true
UserSession.shared.saveInstitution(identifier: .tum)
case .done(let response):
handleProfileInfoCompletion(response)
dismiss()
}
}
}
}

struct InstitutionLogo: View {

private struct InstitutionLogo: View {
var institution: InstitutionIdentifier

var body: some View {
if institution.logo == nil {
Image("Artemis-Logo")
Image("Artemis-Logo", bundle: .module)
.resizable()
.scaledToFit()
} else {
Expand All @@ -187,7 +190,7 @@ struct InstitutionLogo: View {
.resizable()
.scaledToFit()
case .failure:
Image("Artemis-Logo")
Image("Artemis-Logo", bundle: .module)
.resizable()
.scaledToFit()
@unknown default:
Expand All @@ -198,12 +201,10 @@ struct InstitutionLogo: View {
}
}

extension InstitutionIdentifier {
// MARK: - InstitutionIdentifier+Logo

extension InstitutionIdentifier {
var logo: URL? {
switch self {
default:
return URL(string: "public/images/logo.png", relativeTo: self.baseURL)
}
URL(string: "public/images/logo.png", relativeTo: self.baseURL)
}
}
Loading

0 comments on commit b5b5a72

Please sign in to comment.