Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Profile Settings and Advanced #3135

Merged
merged 18 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Core/Core/Common/Extensions/UIKit/UIViewExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ extension UIView: ViewLoader {}
extension ViewLoader where Self: UIView {
/// Returns a newly initialized view controller.
/// This can assume the nib name matches the type name and the bundle contains the type.
public static func loadFromXib(nibName name: String = String(describing: Self.self)) -> Self {
public static func loadFromXib(nibName name: String = String(describing: Self.self)) -> Self {
guard let view = Bundle(for: self).loadNibNamed(name, owner: self, options: nil)?.first as? Self else {
fatalError("Could not create \(name) from a xib.")
}
Expand Down
43 changes: 27 additions & 16 deletions Core/Core/Features/People/APIUser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ struct APIUserDisplay: Codable, Equatable {
// https://canvas.instructure.com/doc/api/users.html#User
public struct APIUser: Codable, Equatable {
public let id: ID
let name: String
let sortable_name: String
let short_name: String
public let name: String
public let sortable_name: String
public let short_name: String
// let sis_user_id: String?
// let sis_import_id: String?
// let integration_id: String?
let login_id: String?
let avatar_url: APIURL?
let enrollments: [APIEnrollment]?
let email: String?
let effective_locale: String?
public let login_id: String?
public let avatar_url: APIURL?
public let enrollments: [APIEnrollment]?
public let email: String?
public let effective_locale: String?
// let last_login: Date?
// let time_zone: TimeZone
reabbotted marked this conversation as resolved.
Show resolved Hide resolved
let bio: String?
let pronouns: String?
public let time_zone: String?
public let bio: String?
public let pronouns: String?
public let root_account: String?

public let locale: String?
Expand All @@ -68,7 +68,8 @@ public struct APIUser: Codable, Equatable {
bio: String?,
pronouns: String?,
permissions: Permissions?,
root_account: String?
root_account: String?,
time_zone: String? = nil
) {
self.id = id
self.name = name
Expand All @@ -84,6 +85,7 @@ public struct APIUser: Codable, Equatable {
self.pronouns = pronouns
self.permissions = permissions
self.root_account = root_account
self.time_zone = time_zone
}

public init(from decoder: Decoder) throws {
Expand All @@ -102,6 +104,7 @@ public struct APIUser: Codable, Equatable {
pronouns = try container.decodeIfPresent(String.self, forKey: .pronouns)
permissions = try container.decodeIfPresent(Permissions.self, forKey: .permissions)
root_account = try container.decodeIfPresent(String.self, forKey: .root_account)
time_zone = try container.decodeIfPresent(String.self, forKey: .time_zone)
}
}

Expand Down Expand Up @@ -132,13 +135,15 @@ public struct APIProfile: Codable, Equatable {

public let id: ID
public let name: String
public let short_name: String?
public let primary_email: String?
public let locale: String?
public let login_id: String?
public let avatar_url: APIURL?
public let calendar: APICalendar?
public let pronouns: String?
public let k5_user: Bool?
public let default_time_zone: String?
}

#if DEBUG
Expand All @@ -157,7 +162,8 @@ extension APIUser {
bio: String? = nil,
pronouns: String? = nil,
permissions: Permissions? = .make(),
root_account: String? = nil
root_account: String? = nil,
time_zone: String? = nil
) -> APIUser {
return APIUser(
id: id,
Expand All @@ -173,7 +179,8 @@ extension APIUser {
bio: bio,
pronouns: pronouns,
permissions: permissions,
root_account: root_account
root_account: root_account,
time_zone: time_zone
)
}

Expand Down Expand Up @@ -225,24 +232,28 @@ extension APIProfile {
public static func make(
id: ID = "1",
name: String = "Bob",
short_name: String? = nil,
primary_email: String? = nil,
locale: String? = "en",
login_id: String? = nil,
avatar_url: URL? = nil,
calendar: APIProfile.APICalendar? = .make(),
pronouns: String? = nil,
k5_user: Bool? = nil
k5_user: Bool? = nil,
default_time_zone: String? = nil
) -> APIProfile {
return APIProfile(
id: id,
name: name,
short_name: short_name,
primary_email: primary_email,
locale: locale,
login_id: login_id,
avatar_url: avatar_url.flatMap(APIURL.make(rawValue:)),
calendar: calendar,
pronouns: pronouns,
k5_user: k5_user
k5_user: k5_user,
default_time_zone: default_time_zone
)
}
}
Expand Down
4 changes: 4 additions & 0 deletions Core/Core/Features/Profile/UserProfile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ import CoreData
public final class UserProfile: NSManagedObject {
@NSManaged public var id: String
@NSManaged public var name: String
@NSManaged public var shortName: String?
@NSManaged public var email: String?
@NSManaged public var locale: String?
@NSManaged public var loginID: String?
@NSManaged public var avatarURL: URL?
@NSManaged public var calendarURL: URL?
@NSManaged public var pronouns: String?
@NSManaged public var isK5User: Bool
@NSManaged public var defaultTimeZone: String?
}

extension UserProfile: WriteableModel {
Expand All @@ -37,13 +39,15 @@ extension UserProfile: WriteableModel {
let model: UserProfile = context.first(where: #keyPath(UserProfile.id), equals: item.id.value) ?? context.insert()
model.id = item.id.value
model.name = item.name
model.shortName = item.short_name
model.email = item.primary_email
model.locale = item.locale
model.loginID = item.login_id
model.avatarURL = item.avatar_url?.rawValue
model.calendarURL = item.calendar?.ics
model.pronouns = item.pronouns
model.isK5User = (item.k5_user == true)
model.defaultTimeZone = item.default_time_zone
return model
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,13 +1126,15 @@
<entity name="UserProfile" representedClassName="Core.UserProfile" syncable="YES">
<attribute name="avatarURL" optional="YES" attributeType="URI"/>
<attribute name="calendarURL" optional="YES" attributeType="URI"/>
<attribute name="defaultTimeZone" optional="YES" attributeType="String"/>
<attribute name="email" optional="YES" attributeType="String"/>
<attribute name="id" attributeType="String"/>
<attribute name="isK5User" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="locale" optional="YES" attributeType="String"/>
<attribute name="loginID" optional="YES" attributeType="String"/>
<attribute name="name" attributeType="String"/>
<attribute name="pronouns" optional="YES" attributeType="String"/>
<attribute name="shortName" optional="YES" attributeType="String"/>
</entity>
<entity name="UserSettings" representedClassName="Core.UserSettings" syncable="YES">
<attribute name="collapseGlobalNav" attributeType="Boolean" usesScalarValueType="YES"/>
Expand Down
Loading