forked from shadowfacts/Tusker
parent
39b244384b
commit
93828830a9
|
@ -22,8 +22,8 @@ public final class Account: AccountProtocol, Decodable {
|
||||||
public let url: URL
|
public let url: URL
|
||||||
public let avatar: URL
|
public let avatar: URL
|
||||||
public let avatarStatic: URL
|
public let avatarStatic: URL
|
||||||
public let header: URL
|
public let header: URL?
|
||||||
public let headerStatic: URL
|
public let headerStatic: URL?
|
||||||
public private(set) var emojis: [Emoji]
|
public private(set) var emojis: [Emoji]
|
||||||
public let moved: Bool?
|
public let moved: Bool?
|
||||||
public let movedTo: Account?
|
public let movedTo: Account?
|
||||||
|
@ -46,8 +46,8 @@ public final class Account: AccountProtocol, Decodable {
|
||||||
self.url = try container.decode(URL.self, forKey: .url)
|
self.url = try container.decode(URL.self, forKey: .url)
|
||||||
self.avatar = try container.decode(URL.self, forKey: .avatar)
|
self.avatar = try container.decode(URL.self, forKey: .avatar)
|
||||||
self.avatarStatic = try container.decode(URL.self, forKey: .avatarStatic)
|
self.avatarStatic = try container.decode(URL.self, forKey: .avatarStatic)
|
||||||
self.header = try container.decode(URL.self, forKey: .header)
|
self.header = try? container.decode(URL.self, forKey: .header)
|
||||||
self.headerStatic = try container.decode(URL.self, forKey: .headerStatic)
|
self.headerStatic = try? container.decode(URL.self, forKey: .headerStatic)
|
||||||
self.emojis = try container.decode([Emoji].self, forKey: .emojis)
|
self.emojis = try container.decode([Emoji].self, forKey: .emojis)
|
||||||
self.fields = (try? container.decode([Field].self, forKey: .fields)) ?? []
|
self.fields = (try? container.decode([Field].self, forKey: .fields)) ?? []
|
||||||
self.bot = try? container.decode(Bool.self, forKey: .bot)
|
self.bot = try? container.decode(Bool.self, forKey: .bot)
|
||||||
|
|
|
@ -10,9 +10,10 @@ import Foundation
|
||||||
|
|
||||||
public class LoginSettings: Decodable {
|
public class LoginSettings: Decodable {
|
||||||
public let accessToken: String
|
public let accessToken: String
|
||||||
private let scope: String
|
private let scope: String?
|
||||||
|
|
||||||
public var scopes: [Scope] {
|
public var scopes: [Scope] {
|
||||||
|
guard let scope = scope else { return [] }
|
||||||
return scope.components(separatedBy: .whitespaces).compactMap(Scope.init)
|
return scope.components(separatedBy: .whitespaces).compactMap(Scope.init)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ public protocol AccountProtocol {
|
||||||
var note: String { get }
|
var note: String { get }
|
||||||
var url: URL { get }
|
var url: URL { get }
|
||||||
var avatar: URL { get }
|
var avatar: URL { get }
|
||||||
var header: URL { get }
|
var header: URL? { get }
|
||||||
var moved: Bool? { get }
|
var moved: Bool? { get }
|
||||||
var bot: Bool? { get }
|
var bot: Bool? { get }
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,25 @@ public class RegisteredApplication: Decodable {
|
||||||
public let clientID: String
|
public let clientID: String
|
||||||
public let clientSecret: String
|
public let clientSecret: String
|
||||||
|
|
||||||
|
public required init(from decoder: Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
|
||||||
|
// Pixelfed API returns id/client_id as numbers instead of strings
|
||||||
|
func decodeStringOrInt(key: CodingKeys) throws -> String {
|
||||||
|
if let str = try? container.decode(String.self, forKey: key) {
|
||||||
|
return str
|
||||||
|
} else if let int = try? container.decode(Int.self, forKey: key) {
|
||||||
|
return int.description
|
||||||
|
} else {
|
||||||
|
throw DecodingError.typeMismatch(String.self, DecodingError.Context(codingPath: container.codingPath + [CodingKeys.id], debugDescription: ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.id = try decodeStringOrInt(key: .id)
|
||||||
|
self.clientID = try decodeStringOrInt(key: .clientID)
|
||||||
|
self.clientSecret = try container.decode(String.self, forKey: .clientSecret)
|
||||||
|
}
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case id
|
case id
|
||||||
case clientID = "client_id"
|
case clientID = "client_id"
|
||||||
|
|
|
@ -27,7 +27,7 @@ public final class AccountMO: NSManagedObject, AccountProtocol {
|
||||||
@NSManaged private var fieldsData: Data?
|
@NSManaged private var fieldsData: Data?
|
||||||
@NSManaged public var followersCount: Int
|
@NSManaged public var followersCount: Int
|
||||||
@NSManaged public var followingCount: Int
|
@NSManaged public var followingCount: Int
|
||||||
@NSManaged public var header: URL
|
@NSManaged public var header: URL?
|
||||||
@NSManaged public var id: String
|
@NSManaged public var id: String
|
||||||
@NSManaged public var locked: Bool
|
@NSManaged public var locked: Bool
|
||||||
@NSManaged public var movedCD: Bool
|
@NSManaged public var movedCD: Bool
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<attribute name="fieldsData" optional="YES" attributeType="Binary"/>
|
<attribute name="fieldsData" optional="YES" attributeType="Binary"/>
|
||||||
<attribute name="followersCount" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="followersCount" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="followingCount" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="followingCount" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="header" attributeType="URI"/>
|
<attribute name="header" optional="YES" attributeType="URI"/>
|
||||||
<attribute name="id" attributeType="String"/>
|
<attribute name="id" attributeType="String"/>
|
||||||
<attribute name="locked" attributeType="Boolean" usesScalarValueType="YES"/>
|
<attribute name="locked" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||||
<attribute name="movedCD" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
<attribute name="movedCD" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
|
||||||
|
|
|
@ -113,13 +113,15 @@ class ProfileHeaderView: UIView {
|
||||||
self.avatarImageView.image = UIImage(data: data)
|
self.avatarImageView.image = UIImage(data: data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
headerRequest = ImageCache.headers.get(account.header) { [weak self] (data) in
|
if let header = account.header {
|
||||||
|
headerRequest = ImageCache.headers.get(header) { [weak self] (data) in
|
||||||
guard let self = self, let data = data, self.accountID == accountID else { return }
|
guard let self = self, let data = data, self.accountID == accountID else { return }
|
||||||
self.headerRequest = nil
|
self.headerRequest = nil
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.headerImageView.image = UIImage(data: data)
|
self.headerImageView.image = UIImage(data: data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if #available(iOS 14.0, *) {
|
if #available(iOS 14.0, *) {
|
||||||
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForProfile(accountID: accountID, sourceView: moreButton))
|
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForProfile(accountID: accountID, sourceView: moreButton))
|
||||||
|
@ -205,16 +207,17 @@ class ProfileHeaderView: UIView {
|
||||||
|
|
||||||
@objc func avatarPressed() {
|
@objc func avatarPressed() {
|
||||||
guard let account = mastodonController.persistentContainer.account(for: accountID) else {
|
guard let account = mastodonController.persistentContainer.account(for: accountID) else {
|
||||||
fatalError("Missing cached account \(accountID!)")
|
return
|
||||||
}
|
}
|
||||||
delegate?.showLoadingLargeImage(url: account.avatar, cache: .avatars, description: nil, animatingFrom: avatarImageView)
|
delegate?.showLoadingLargeImage(url: account.avatar, cache: .avatars, description: nil, animatingFrom: avatarImageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func headerPressed() {
|
@objc func headerPressed() {
|
||||||
guard let account = mastodonController.persistentContainer.account(for: accountID) else {
|
guard let account = mastodonController.persistentContainer.account(for: accountID),
|
||||||
fatalError("Missing cached account \(accountID!)")
|
let header = account.header else {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
delegate?.showLoadingLargeImage(url: account.header, cache: .headers, description: nil, animatingFrom: headerImageView)
|
delegate?.showLoadingLargeImage(url: header, cache: .headers, description: nil, animatingFrom: headerImageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func postsSegmentedControlChanged(_ sender: UISegmentedControl) {
|
@IBAction func postsSegmentedControlChanged(_ sender: UISegmentedControl) {
|
||||||
|
|
|
@ -270,7 +270,7 @@ struct XCBActions {
|
||||||
"following": account.followingCount.description,
|
"following": account.followingCount.description,
|
||||||
"url": account.url.absoluteString,
|
"url": account.url.absoluteString,
|
||||||
"avatarURL": account.avatar.absoluteString,
|
"avatarURL": account.avatar.absoluteString,
|
||||||
"headerURL": account.header.absoluteString
|
"headerURL": account.header?.absoluteString
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ struct XCBActions {
|
||||||
"following": account.followingCount.description,
|
"following": account.followingCount.description,
|
||||||
"url": account.url.absoluteString,
|
"url": account.url.absoluteString,
|
||||||
"avatarURL": account.avatar.absoluteString,
|
"avatarURL": account.avatar.absoluteString,
|
||||||
"headerURL": account.header.absoluteString
|
"headerURL": account.header?.absoluteString
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue