Transform to multi-account support
This commit is contained in:
+53
-25
@@ -7,29 +7,34 @@
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import OSLog
|
||||
|
||||
/// **AccountManager** stores connection details and the corresponding client
|
||||
class AccountManager: ObservableObject {
|
||||
/// **AccountManager** holds multiple accounts and takes care of storing them on the device.
|
||||
@Observable class AccountManager {
|
||||
// default contains a ready-to-use instance of AccountManager, read from AppStorage
|
||||
static public var `default` = AccountManager()
|
||||
|
||||
// accounts holds all saved accounts
|
||||
@Published private(set) var Accounts: Array<AccountManagerEntry> = []
|
||||
private(set) var Accounts: Array<Account> = [] { didSet { writeToRaw() } }
|
||||
private var selectedAccount: Int? { didSet { writeToRaw() } }
|
||||
|
||||
// init creates a new AccountManager, reading saved account data from AppStorage
|
||||
init() {
|
||||
self.Accounts = AccountManager.readFromRaw()
|
||||
|
||||
// Read account selection
|
||||
@AppStorage("selectedAccount") var selectedAccount: Int?
|
||||
self.selectedAccount = selectedAccount
|
||||
}
|
||||
|
||||
// readFromRaw reads the current accounts from the stored data and transforms it to a handy Account Array
|
||||
static private func readFromRaw() -> Array<AccountManagerEntry> {
|
||||
static private func readFromRaw() -> Array<Account> {
|
||||
@AppStorage("accounts") var rawAccs = Data()
|
||||
do {
|
||||
let simpleAccs = try JSONDecoder().decode([Account].self, from: rawAccs)
|
||||
let richAccs = simpleAccs.map({ AccountManagerEntry($0) })
|
||||
return richAccs
|
||||
return try JSONDecoder().decode([Account].self, from: rawAccs)
|
||||
} catch {
|
||||
print("Error parsing stored accounts from JSON: \(error)")
|
||||
let _ = Logger().error("Error parsing stored accounts from JSON: \(error)")
|
||||
rawAccs = Data()
|
||||
return []
|
||||
}
|
||||
}
|
||||
@@ -38,47 +43,70 @@ class AccountManager: ObservableObject {
|
||||
private func writeToRaw() {
|
||||
@AppStorage("accounts") var rawAccs = Data()
|
||||
do {
|
||||
let simpleAccs = Accounts.map({ $0.GetAccount() })
|
||||
rawAccs = try JSONEncoder().encode(simpleAccs)
|
||||
rawAccs = try JSONEncoder().encode(Accounts)
|
||||
} catch {
|
||||
print("Error writing current accounts to JSON: \(error)")
|
||||
let _ = Logger().error("Error writing current accounts to JSON: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
// CurrentAccount returns the currently selected account if there is one
|
||||
func CurrentAccount() -> AccountManagerEntry? {
|
||||
if self.Accounts.count > 0 {
|
||||
return self.Accounts.first
|
||||
func CurrentAccount() -> Account? {
|
||||
if selectedAccount == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if Accounts.count > selectedAccount! {
|
||||
return Accounts[selectedAccount!]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectAccount sets the current main account as returned by CurrentAccount
|
||||
func SelectAccount(_ account: Account) {
|
||||
SelectAccount(IndexOfAccount(account))
|
||||
}
|
||||
|
||||
// SelectAccount sets the current main account as returned by CurrentAccount
|
||||
func SelectAccount(_ accountID: Int?) {
|
||||
self.selectedAccount = accountID
|
||||
|
||||
// Store account selection
|
||||
@AppStorage("selectedAccount") var selectedAccount: Int?
|
||||
selectedAccount = self.selectedAccount
|
||||
}
|
||||
|
||||
// AddAccount adds the given account if it doesn't exist yet
|
||||
func AddAccount(_ account: Account) {
|
||||
if IndexOfAccount(account) == nil {
|
||||
Accounts.append(AccountManagerEntry(account))
|
||||
writeToRaw()
|
||||
Accounts.append(account)
|
||||
}
|
||||
}
|
||||
|
||||
// IndexOfAccount returns the index of the specified account identified by address and user ID
|
||||
func IndexOfAccount(_ account: Account) -> Int? {
|
||||
return Accounts.firstIndex(where: {
|
||||
$0.GetAccount().GetAddress() == account.GetAddress() &&
|
||||
$0.GetAccount().GetUserID() == account.GetUserID()
|
||||
$0.address == account.address &&
|
||||
$0.userID == account.userID
|
||||
})
|
||||
}
|
||||
|
||||
// RemoveAccount removes the account specified by address and user ID of the given Account, if present
|
||||
// RemoveAccount removes the specified account
|
||||
func RemoveAccount(_ account: Account) {
|
||||
if IndexOfAccount(account) != nil {
|
||||
Accounts.remove(at: IndexOfAccount(account)!)
|
||||
writeToRaw()
|
||||
RemoveAccount(IndexOfAccount(account)!)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveAccount removes the account specified by address and user ID of the given AccountManagerEntry, if present
|
||||
func RemoveAccount(_ account: AccountManagerEntry) {
|
||||
RemoveAccount(account.GetAccount())
|
||||
|
||||
// RemoveAccount removes the account at the specified index
|
||||
func RemoveAccount(_ index: Int) {
|
||||
Accounts.remove(at: index)
|
||||
}
|
||||
|
||||
// RefreshAll refreshes all accounts held by this manager instance
|
||||
func RefreshAll() async {
|
||||
for acc in Accounts {
|
||||
await acc.Refresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user