mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 18:54:11 +00:00
Add support for Piped accounts and subscriptions
This commit is contained in:
@@ -8,7 +8,9 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
|
||||
let instanceID: String
|
||||
var name: String?
|
||||
let url: String
|
||||
let sid: String
|
||||
let username: String
|
||||
let password: String?
|
||||
var token: String?
|
||||
let anonymous: Bool
|
||||
|
||||
init(
|
||||
@@ -16,7 +18,9 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
|
||||
instanceID: String? = nil,
|
||||
name: String? = nil,
|
||||
url: String? = nil,
|
||||
sid: String? = nil,
|
||||
username: String? = nil,
|
||||
password: String? = nil,
|
||||
token: String? = nil,
|
||||
anonymous: Bool = false
|
||||
) {
|
||||
self.anonymous = anonymous
|
||||
@@ -25,27 +29,29 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
|
||||
self.instanceID = instanceID ?? UUID().uuidString
|
||||
self.name = name
|
||||
self.url = url ?? ""
|
||||
self.sid = sid ?? ""
|
||||
self.username = username ?? ""
|
||||
self.token = token
|
||||
self.password = password ?? ""
|
||||
}
|
||||
|
||||
var instance: Instance! {
|
||||
Defaults[.instances].first { $0.id == instanceID }
|
||||
}
|
||||
|
||||
var anonymizedSID: String {
|
||||
guard sid.count > 3 else {
|
||||
return ""
|
||||
var shortUsername: String {
|
||||
guard username.count > 10 else {
|
||||
return username
|
||||
}
|
||||
|
||||
let index = sid.index(sid.startIndex, offsetBy: 4)
|
||||
return String(sid[..<index])
|
||||
let index = username.index(username.startIndex, offsetBy: 11)
|
||||
return String(username[..<index])
|
||||
}
|
||||
|
||||
var description: String {
|
||||
(name != nil && name!.isEmpty) ? "Unnamed (\(anonymizedSID))" : name!
|
||||
(name != nil && name!.isEmpty) ? shortUsername : name!
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(sid)
|
||||
hasher.combine(username)
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import SwiftUI
|
||||
final class AccountValidator: Service {
|
||||
let app: Binding<VideosApp>
|
||||
let url: String
|
||||
let account: Account?
|
||||
let account: Account!
|
||||
|
||||
var formObjectID: Binding<String>
|
||||
var isValid: Binding<Bool>
|
||||
@@ -46,7 +46,11 @@ final class AccountValidator: Service {
|
||||
return
|
||||
}
|
||||
|
||||
$0.headers["Cookie"] = self.cookieHeader
|
||||
$0.headers["Cookie"] = self.invidiousCookieHeader
|
||||
}
|
||||
|
||||
configure("/login", requestMethods: [.post]) {
|
||||
$0.headers["Content-Type"] = "application/json"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,20 +88,27 @@ final class AccountValidator: Service {
|
||||
}
|
||||
}
|
||||
|
||||
func validateInvidiousAccount() {
|
||||
func validateAccount() {
|
||||
reset()
|
||||
|
||||
feed
|
||||
.load()
|
||||
.onSuccess { _ in
|
||||
guard self.account!.sid == self.formObjectID.wrappedValue else {
|
||||
accountRequest
|
||||
.onSuccess { response in
|
||||
guard self.account!.username == self.formObjectID.wrappedValue else {
|
||||
return
|
||||
}
|
||||
|
||||
self.isValid.wrappedValue = true
|
||||
switch self.app.wrappedValue {
|
||||
case .invidious:
|
||||
self.isValid.wrappedValue = true
|
||||
case .piped:
|
||||
let error = response.json.dictionaryValue["error"]?.string
|
||||
let token = response.json.dictionaryValue["token"]?.string
|
||||
self.isValid.wrappedValue = error?.isEmpty ?? !(token?.isEmpty ?? true)
|
||||
self.error!.wrappedValue = error
|
||||
}
|
||||
}
|
||||
.onFailure { _ in
|
||||
guard self.account!.sid == self.formObjectID.wrappedValue else {
|
||||
guard self.account!.username == self.formObjectID.wrappedValue else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -109,6 +120,15 @@ final class AccountValidator: Service {
|
||||
}
|
||||
}
|
||||
|
||||
var accountRequest: Request {
|
||||
switch app.wrappedValue {
|
||||
case .invidious:
|
||||
return feed.load()
|
||||
case .piped:
|
||||
return login.request(.post, json: ["username": account.username, "password": account.password])
|
||||
}
|
||||
}
|
||||
|
||||
func reset() {
|
||||
isValid.wrappedValue = false
|
||||
isValidated.wrappedValue = false
|
||||
@@ -116,8 +136,12 @@ final class AccountValidator: Service {
|
||||
error?.wrappedValue = nil
|
||||
}
|
||||
|
||||
var cookieHeader: String {
|
||||
"SID=\(account!.sid)"
|
||||
var invidiousCookieHeader: String {
|
||||
"SID=\(account.username)"
|
||||
}
|
||||
|
||||
var login: Resource {
|
||||
resource("/login")
|
||||
}
|
||||
|
||||
var feed: Resource {
|
||||
|
@@ -15,7 +15,8 @@ struct AccountsBridge: Defaults.Bridge {
|
||||
"instanceID": value.instanceID,
|
||||
"name": value.name ?? "",
|
||||
"apiURL": value.url,
|
||||
"sid": value.sid
|
||||
"username": value.username,
|
||||
"password": value.password ?? ""
|
||||
]
|
||||
}
|
||||
|
||||
@@ -25,13 +26,14 @@ struct AccountsBridge: Defaults.Bridge {
|
||||
let id = object["id"],
|
||||
let instanceID = object["instanceID"],
|
||||
let url = object["apiURL"],
|
||||
let sid = object["sid"]
|
||||
let username = object["username"]
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let name = object["name"] ?? ""
|
||||
let password = object["password"]
|
||||
|
||||
return Account(id: id, instanceID: instanceID, name: name, url: url, sid: sid)
|
||||
return Account(id: id, instanceID: instanceID, name: name, url: url, username: username, password: password)
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ final class AccountsModel: ObservableObject {
|
||||
}
|
||||
|
||||
var signedIn: Bool {
|
||||
!isEmpty && !current.anonymous
|
||||
!isEmpty && !current.anonymous && api.signedIn
|
||||
}
|
||||
|
||||
init() {
|
||||
@@ -74,8 +74,14 @@ final class AccountsModel: ObservableObject {
|
||||
Defaults[.accounts].first { $0.id == id }
|
||||
}
|
||||
|
||||
static func add(instance: Instance, name: String, sid: String) -> Account {
|
||||
let account = Account(instanceID: instance.id, name: name, url: instance.apiURL, sid: sid)
|
||||
static func add(instance: Instance, name: String, username: String, password: String? = nil) -> Account {
|
||||
let account = Account(
|
||||
instanceID: instance.id,
|
||||
name: name,
|
||||
url: instance.apiURL,
|
||||
username: username,
|
||||
password: password
|
||||
)
|
||||
Defaults[.accounts].append(account)
|
||||
|
||||
return account
|
||||
|
Reference in New Issue
Block a user