yattee/Model/Accounts/AccountsModel.swift

155 lines
4.2 KiB
Swift
Raw Normal View History

2021-10-16 22:48:58 +00:00
import Combine
import Defaults
import Foundation
final class AccountsModel: ObservableObject {
static let shared = AccountsModel()
2021-10-20 22:21:50 +00:00
@Published private(set) var current: Account!
2021-10-16 22:48:58 +00:00
2021-10-20 22:21:50 +00:00
@Published private var invidious = InvidiousAPI()
@Published private var piped = PipedAPI()
2022-12-09 00:15:19 +00:00
@Published private var peerTube = PeerTubeAPI()
2021-10-16 22:48:58 +00:00
@Published var publicAccount: Account?
2021-10-16 22:48:58 +00:00
private var cancellables = [AnyCancellable]()
2021-10-20 22:21:50 +00:00
var all: [Account] {
Defaults[.accounts]
}
2021-10-20 22:21:50 +00:00
var lastUsed: Account? {
guard let id = Defaults[.lastAccountID] else {
return nil
}
2023-04-22 13:08:33 +00:00
return Self.find(id)
2021-10-16 22:48:58 +00:00
}
2021-12-24 19:20:05 +00:00
var any: Account? {
lastUsed ?? all.randomElement()
}
2021-10-20 22:21:50 +00:00
var app: VideosApp {
2022-12-09 00:15:19 +00:00
current?.instance?.app ?? .local
2021-10-20 22:21:50 +00:00
}
2022-12-09 00:15:19 +00:00
var api: VideosAPI! {
switch app {
case .piped:
return piped
case .invidious:
return invidious
2022-12-09 00:15:19 +00:00
default:
2022-12-10 00:23:13 +00:00
return peerTube
}
2021-10-20 22:21:50 +00:00
}
2021-10-17 23:06:00 +00:00
var isEmpty: Bool {
current.isNil
2021-10-17 23:06:00 +00:00
}
2021-10-16 22:48:58 +00:00
var signedIn: Bool {
!isEmpty && !current.anonymous && api.signedIn
2021-10-16 22:48:58 +00:00
}
init() {
cancellables.append(
invidious.objectWillChange.sink { [weak self] _ in self?.objectWillChange.send() }
)
cancellables.append(
piped.objectWillChange.sink { [weak self] _ in self?.objectWillChange.send() }
)
}
func configureAccount() {
if let account = lastUsed ??
InstancesModel.shared.lastUsed?.anonymousAccount ??
InstancesModel.shared.all.first?.anonymousAccount
{
setCurrent(account)
}
}
2021-10-20 22:21:50 +00:00
func setCurrent(_ account: Account! = nil) {
guard account != current else {
2021-10-16 22:48:58 +00:00
return
}
current = account
2021-10-16 22:48:58 +00:00
2021-10-17 23:06:00 +00:00
guard !account.isNil else {
2022-11-11 19:34:20 +00:00
current = nil
2021-10-17 23:06:00 +00:00
return
}
2021-10-16 22:48:58 +00:00
switch account.instance.app {
2022-12-09 00:15:19 +00:00
case .local:
return
2021-10-16 22:48:58 +00:00
case .invidious:
invidious.setAccount(account)
case .piped:
piped.setAccount(account)
2022-12-09 00:15:19 +00:00
case .peerTube:
peerTube.setAccount(account)
2021-10-16 22:48:58 +00:00
}
Defaults[.lastAccountIsPublic] = account.isPublic
if !account.isPublic {
Defaults[.lastAccountID] = account.anonymous ? nil : account.id
Defaults[.lastInstanceID] = account.instanceID
}
}
2021-10-20 22:21:50 +00:00
static func find(_ id: Account.ID) -> Account? {
Defaults[.accounts].first { $0.id == id }
}
static func add(instance: Instance, name: String, username: String, password: String) -> Account {
2022-12-09 00:15:19 +00:00
let account = Account(instanceID: instance.id, name: name, urlString: instance.apiURLString)
Defaults[.accounts].append(account)
setCredentials(account, username: username, password: password)
return account
}
2021-10-20 22:21:50 +00:00
static func remove(_ account: Account) {
if let accountIndex = Defaults[.accounts].firstIndex(where: { $0.id == account.id }) {
let account = Defaults[.accounts][accountIndex]
KeychainModel.shared.removeAccountKeys(account)
Defaults[.accounts].remove(at: accountIndex)
}
2021-10-16 22:48:58 +00:00
}
static func setToken(_ account: Account, _ token: String) {
KeychainModel.shared.updateAccountKey(account, "token", token)
}
static func setCredentials(_ account: Account, username: String, password: String) {
KeychainModel.shared.updateAccountKey(account, "username", username)
KeychainModel.shared.updateAccountKey(account, "password", password)
}
static func getCredentials(_ account: Account) -> (String?, String?) {
(
KeychainModel.shared.getAccountKey(account, "username"),
KeychainModel.shared.getAccountKey(account, "password")
)
}
static func removeDefaultsCredentials(_ account: Account) {
if let accountIndex = Defaults[.accounts].firstIndex(where: { $0.id == account.id }) {
var account = Defaults[.accounts][accountIndex]
account.name = ""
account.username = ""
account.password = nil
Defaults[.accounts][accountIndex] = account
}
}
2021-10-16 22:48:58 +00:00
}