IceCubesApp/Packages/AppAccount/Sources/AppAccount/AppAccountViewModel.swift

78 lines
2.1 KiB
Swift
Raw Normal View History

import Combine
2023-02-12 15:29:41 +00:00
import DesignSystem
2022-12-30 07:36:22 +00:00
import Models
import Network
2023-01-17 10:36:01 +00:00
import SwiftUI
2022-12-30 07:36:22 +00:00
@MainActor
public class AppAccountViewModel: ObservableObject {
2023-02-09 06:36:23 +00:00
private static var avatarsCache: [String: UIImage] = [:]
private static var accountsCache: [String: Account] = [:]
2023-02-12 15:29:41 +00:00
var appAccount: AppAccount
2022-12-30 07:36:22 +00:00
let client: Client
let isCompact: Bool
2023-01-17 10:36:01 +00:00
@Published var account: Account? {
didSet {
if let account {
refreshAcct(account: account)
}
}
}
2023-02-18 06:26:48 +00:00
2023-02-09 06:36:23 +00:00
@Published var roundedAvatar: UIImage?
2023-02-12 15:29:41 +00:00
2023-01-10 05:58:50 +00:00
var acct: String {
2023-02-05 08:13:28 +00:00
if let acct = appAccount.accountName {
return acct
} else {
return "@\(account?.acct ?? "...")@\(appAccount.server)"
}
2023-01-10 05:58:50 +00:00
}
2023-01-17 10:36:01 +00:00
public init(appAccount: AppAccount, isCompact: Bool = false) {
2022-12-30 07:36:22 +00:00
self.appAccount = appAccount
self.isCompact = isCompact
2023-01-17 10:36:01 +00:00
client = .init(server: appAccount.server, oauthToken: appAccount.oauthToken)
2022-12-30 07:36:22 +00:00
}
2023-01-17 10:36:01 +00:00
2022-12-30 07:36:22 +00:00
func fetchAccount() async {
do {
account = Self.accountsCache[appAccount.id]
roundedAvatar = Self.avatarsCache[appAccount.id]
2023-02-18 06:26:48 +00:00
2022-12-30 07:36:22 +00:00
account = try await client.get(endpoint: Accounts.verifyCredentials)
Self.accountsCache[appAccount.id] = account
2023-02-18 06:26:48 +00:00
2023-02-16 07:38:34 +00:00
if let account {
await refreshAvatar(account: account)
}
2023-02-18 06:26:48 +00:00
} catch {}
}
2023-02-18 06:26:48 +00:00
private func refreshAcct(account: Account) {
do {
if appAccount.accountName == nil {
appAccount.accountName = "\(account.acct)@\(appAccount.server)"
try appAccount.save()
}
2023-02-18 06:26:48 +00:00
} catch {}
}
2023-02-18 06:26:48 +00:00
private func refreshAvatar(account: Account) async {
// Warning: Non-sendable type '(any URLSessionTaskDelegate)?' exiting main actor-isolated
// context in call to non-isolated instance method 'data(for:delegate:)' cannot cross actor
// boundary.
// This is on the defaulted-to-nil second parameter of `.data(from:delegate:)`.
// There is a Radar tracking this & others like it.
2023-02-16 07:38:34 +00:00
if let (data, _) = try? await URLSession.shared.data(from: account.avatar),
2023-02-18 06:26:48 +00:00
let image = UIImage(data: data)?.roundedImage
{
roundedAvatar = image
Self.avatarsCache[account.id] = image
}
2022-12-30 07:36:22 +00:00
}
}