2021-10-16 22:48:58 +00:00
|
|
|
import Combine
|
|
|
|
import Defaults
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
final class AccountsModel: ObservableObject {
|
2022-11-24 20:36:05 +00:00
|
|
|
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()
|
2021-10-16 22:48:58 +00:00
|
|
|
|
2022-07-01 21:28:32 +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] {
|
2021-10-19 21:27:04 +00:00
|
|
|
Defaults[.accounts]
|
|
|
|
}
|
|
|
|
|
2021-10-20 22:21:50 +00:00
|
|
|
var lastUsed: Account? {
|
2021-10-19 21:27:04 +00:00
|
|
|
guard let id = Defaults[.lastAccountID] else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return AccountsModel.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 {
|
2021-11-12 20:46:15 +00:00
|
|
|
current?.instance?.app ?? .invidious
|
2021-10-20 22:21:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var api: VideosAPI {
|
2022-10-26 11:11:35 +00:00
|
|
|
switch app {
|
|
|
|
case .piped:
|
|
|
|
return piped
|
|
|
|
case .invidious:
|
|
|
|
return invidious
|
|
|
|
}
|
2021-10-20 22:21:50 +00:00
|
|
|
}
|
|
|
|
|
2021-10-17 23:06:00 +00:00
|
|
|
var isEmpty: Bool {
|
2021-10-19 21:27:04 +00:00
|
|
|
current.isNil
|
2021-10-17 23:06:00 +00:00
|
|
|
}
|
|
|
|
|
2021-10-16 22:48:58 +00:00
|
|
|
var signedIn: Bool {
|
2021-11-14 23:06:01 +00:00
|
|
|
!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() }
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-07-03 20:39:10 +00:00
|
|
|
func configureAccount() {
|
|
|
|
if let account = lastUsed ??
|
2022-11-24 20:36:05 +00:00
|
|
|
InstancesModel.shared.lastUsed?.anonymousAccount ??
|
|
|
|
InstancesModel.shared.all.first?.anonymousAccount
|
2022-07-03 20:39:10 +00:00
|
|
|
{
|
|
|
|
setCurrent(account)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-20 22:21:50 +00:00
|
|
|
func setCurrent(_ account: Account! = nil) {
|
2021-10-19 21:27:04 +00:00
|
|
|
guard account != current else {
|
2021-10-16 22:48:58 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-10-19 21:27:04 +00:00
|
|
|
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 {
|
|
|
|
case .invidious:
|
|
|
|
invidious.setAccount(account)
|
|
|
|
case .piped:
|
|
|
|
piped.setAccount(account)
|
|
|
|
}
|
2021-10-19 21:27:04 +00:00
|
|
|
|
2022-07-04 09:35:27 +00:00
|
|
|
Defaults[.lastAccountIsPublic] = account.isPublic
|
|
|
|
|
|
|
|
if !account.isPublic {
|
|
|
|
Defaults[.lastAccountID] = account.anonymous ? nil : account.id
|
|
|
|
Defaults[.lastInstanceID] = account.instanceID
|
|
|
|
}
|
2021-10-19 21:27:04 +00:00
|
|
|
}
|
|
|
|
|
2021-10-20 22:21:50 +00:00
|
|
|
static func find(_ id: Account.ID) -> Account? {
|
2021-10-19 21:27:04 +00:00
|
|
|
Defaults[.accounts].first { $0.id == id }
|
|
|
|
}
|
|
|
|
|
2022-08-25 23:36:46 +00:00
|
|
|
static func add(instance: Instance, name: String, username: String, password: String) -> Account {
|
|
|
|
let account = Account(instanceID: instance.id, name: name, url: instance.apiURL)
|
2021-10-19 21:27:04 +00:00
|
|
|
Defaults[.accounts].append(account)
|
|
|
|
|
2022-08-25 23:36:46 +00:00
|
|
|
setCredentials(account, username: username, password: password)
|
|
|
|
|
2021-10-19 21:27:04 +00:00
|
|
|
return account
|
|
|
|
}
|
|
|
|
|
2021-10-20 22:21:50 +00:00
|
|
|
static func remove(_ account: Account) {
|
2021-10-19 21:27:04 +00:00
|
|
|
if let accountIndex = Defaults[.accounts].firstIndex(where: { $0.id == account.id }) {
|
2022-08-25 23:36:46 +00:00
|
|
|
let account = Defaults[.accounts][accountIndex]
|
|
|
|
KeychainModel.shared.removeAccountKeys(account)
|
2021-10-19 21:27:04 +00:00
|
|
|
Defaults[.accounts].remove(at: accountIndex)
|
|
|
|
}
|
2021-10-16 22:48:58 +00:00
|
|
|
}
|
2022-08-25 23:36:46 +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
|
|
|
}
|