mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 10:44:06 +00:00
Add settings for frontend instance URL
This commit is contained in:
@@ -2,41 +2,6 @@ import Defaults
|
||||
import Foundation
|
||||
|
||||
struct Account: Defaults.Serializable, Hashable, Identifiable {
|
||||
struct AccountsBridge: Defaults.Bridge {
|
||||
typealias Value = Account
|
||||
typealias Serializable = [String: String]
|
||||
|
||||
func serialize(_ value: Value?) -> Serializable? {
|
||||
guard let value = value else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return [
|
||||
"id": value.id,
|
||||
"instanceID": value.instanceID,
|
||||
"name": value.name ?? "",
|
||||
"url": value.url,
|
||||
"sid": value.sid
|
||||
]
|
||||
}
|
||||
|
||||
func deserialize(_ object: Serializable?) -> Value? {
|
||||
guard
|
||||
let object = object,
|
||||
let id = object["id"],
|
||||
let instanceID = object["instanceID"],
|
||||
let url = object["url"],
|
||||
let sid = object["sid"]
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let name = object["name"] ?? ""
|
||||
|
||||
return Account(id: id, instanceID: instanceID, name: name, url: url, sid: sid)
|
||||
}
|
||||
}
|
||||
|
||||
static var bridge = AccountsBridge()
|
||||
|
||||
let id: String
|
||||
@@ -46,7 +11,14 @@ struct Account: Defaults.Serializable, Hashable, Identifiable {
|
||||
let sid: String
|
||||
let anonymous: Bool
|
||||
|
||||
init(id: String? = nil, instanceID: String? = nil, name: String? = nil, url: String? = nil, sid: String? = nil, anonymous: Bool = false) {
|
||||
init(
|
||||
id: String? = nil,
|
||||
instanceID: String? = nil,
|
||||
name: String? = nil,
|
||||
url: String? = nil,
|
||||
sid: String? = nil,
|
||||
anonymous: Bool = false
|
||||
) {
|
||||
self.anonymous = anonymous
|
||||
|
||||
self.id = id ?? (anonymous ? "anonymous-\(instanceID!)" : UUID().uuidString)
|
||||
|
37
Model/Accounts/AccountsBridge.swift
Normal file
37
Model/Accounts/AccountsBridge.swift
Normal file
@@ -0,0 +1,37 @@
|
||||
import Defaults
|
||||
import Foundation
|
||||
|
||||
struct AccountsBridge: Defaults.Bridge {
|
||||
typealias Value = Account
|
||||
typealias Serializable = [String: String]
|
||||
|
||||
func serialize(_ value: Value?) -> Serializable? {
|
||||
guard let value = value else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return [
|
||||
"id": value.id,
|
||||
"instanceID": value.instanceID,
|
||||
"name": value.name ?? "",
|
||||
"apiURL": value.url,
|
||||
"sid": value.sid
|
||||
]
|
||||
}
|
||||
|
||||
func deserialize(_ object: Serializable?) -> Value? {
|
||||
guard
|
||||
let object = object,
|
||||
let id = object["id"],
|
||||
let instanceID = object["instanceID"],
|
||||
let url = object["apiURL"],
|
||||
let sid = object["sid"]
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let name = object["name"] ?? ""
|
||||
|
||||
return Account(id: id, instanceID: instanceID, name: name, url: url, sid: sid)
|
||||
}
|
||||
}
|
@@ -75,7 +75,7 @@ final class AccountsModel: ObservableObject {
|
||||
}
|
||||
|
||||
static func add(instance: Instance, name: String, sid: String) -> Account {
|
||||
let account = Account(instanceID: instance.id, name: name, url: instance.url, sid: sid)
|
||||
let account = Account(instanceID: instance.id, name: name, url: instance.apiURL, sid: sid)
|
||||
Defaults[.accounts].append(account)
|
||||
|
||||
return account
|
||||
|
@@ -2,51 +2,20 @@ import Defaults
|
||||
import Foundation
|
||||
|
||||
struct Instance: Defaults.Serializable, Hashable, Identifiable {
|
||||
struct InstancesBridge: Defaults.Bridge {
|
||||
typealias Value = Instance
|
||||
typealias Serializable = [String: String]
|
||||
|
||||
func serialize(_ value: Value?) -> Serializable? {
|
||||
guard let value = value else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return [
|
||||
"app": value.app.rawValue,
|
||||
"id": value.id,
|
||||
"name": value.name,
|
||||
"url": value.url
|
||||
]
|
||||
}
|
||||
|
||||
func deserialize(_ object: Serializable?) -> Value? {
|
||||
guard
|
||||
let object = object,
|
||||
let app = VideosApp(rawValue: object["app"] ?? ""),
|
||||
let id = object["id"],
|
||||
let url = object["url"]
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let name = object["name"] ?? ""
|
||||
|
||||
return Instance(app: app, id: id, name: name, url: url)
|
||||
}
|
||||
}
|
||||
|
||||
static var bridge = InstancesBridge()
|
||||
|
||||
let app: VideosApp
|
||||
let id: String
|
||||
let name: String
|
||||
let url: String
|
||||
let apiURL: String
|
||||
var frontendURL: String?
|
||||
|
||||
init(app: VideosApp, id: String? = nil, name: String, url: String) {
|
||||
init(app: VideosApp, id: String? = nil, name: String, apiURL: String, frontendURL: String? = nil) {
|
||||
self.app = app
|
||||
self.id = id ?? UUID().uuidString
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.apiURL = apiURL
|
||||
self.frontendURL = frontendURL
|
||||
}
|
||||
|
||||
var anonymous: VideosAPI {
|
||||
@@ -63,27 +32,26 @@ struct Instance: Defaults.Serializable, Hashable, Identifiable {
|
||||
}
|
||||
|
||||
var longDescription: String {
|
||||
name.isEmpty ? "\(app.name) - \(url)" : "\(app.name) - \(name) (\(url))"
|
||||
name.isEmpty ? "\(app.name) - \(apiURL)" : "\(app.name) - \(name) (\(apiURL))"
|
||||
}
|
||||
|
||||
var shortDescription: String {
|
||||
name.isEmpty ? url : name
|
||||
name.isEmpty ? apiURL : name
|
||||
}
|
||||
|
||||
var anonymousAccount: Account {
|
||||
Account(instanceID: id, name: "Anonymous", url: url, anonymous: true)
|
||||
Account(instanceID: id, name: "Anonymous", url: apiURL, anonymous: true)
|
||||
}
|
||||
|
||||
var urlComponents: URLComponents {
|
||||
URLComponents(string: url)!
|
||||
URLComponents(string: apiURL)!
|
||||
}
|
||||
|
||||
var frontendHost: String {
|
||||
// TODO: piped frontend link
|
||||
urlComponents.host!.replacingOccurrences(of: "api", with: "")
|
||||
URLComponents(string: frontendURL!)!.host!
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(url)
|
||||
hasher.combine(apiURL)
|
||||
}
|
||||
}
|
||||
|
38
Model/Accounts/InstancesBridge.swift
Normal file
38
Model/Accounts/InstancesBridge.swift
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
import Defaults
|
||||
import Foundation
|
||||
|
||||
struct InstancesBridge: Defaults.Bridge {
|
||||
typealias Value = Instance
|
||||
typealias Serializable = [String: String]
|
||||
|
||||
func serialize(_ value: Value?) -> Serializable? {
|
||||
guard let value = value else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return [
|
||||
"app": value.app.rawValue,
|
||||
"id": value.id,
|
||||
"name": value.name,
|
||||
"apiURL": value.apiURL,
|
||||
"frontendURL": value.frontendURL ?? ""
|
||||
]
|
||||
}
|
||||
|
||||
func deserialize(_ object: Serializable?) -> Value? {
|
||||
guard
|
||||
let object = object,
|
||||
let app = VideosApp(rawValue: object["app"] ?? ""),
|
||||
let id = object["id"],
|
||||
let apiURL = object["apiURL"]
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let name = object["name"] ?? ""
|
||||
|
||||
let frontendURL: String? = object["frontendURL"]!.isEmpty ? nil : object["frontendURL"]
|
||||
return Instance(app: app, id: id, name: name, apiURL: apiURL, frontendURL: frontendURL)
|
||||
}
|
||||
}
|
@@ -27,12 +27,21 @@ final class InstancesModel: ObservableObject {
|
||||
}
|
||||
|
||||
static func add(app: VideosApp, name: String, url: String) -> Instance {
|
||||
let instance = Instance(app: app, id: UUID().uuidString, name: name, url: url)
|
||||
let instance = Instance(app: app, id: UUID().uuidString, name: name, apiURL: url)
|
||||
Defaults[.instances].append(instance)
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
static func setFrontendURL(_ instance: Instance, _ url: String) {
|
||||
if let index = Defaults[.instances].firstIndex(where: { $0.id == instance.id }) {
|
||||
var instance = Defaults[.instances][index]
|
||||
instance.frontendURL = url
|
||||
|
||||
Defaults[.instances][index] = instance
|
||||
}
|
||||
}
|
||||
|
||||
static func remove(_ instance: Instance) {
|
||||
let accounts = InstancesModel.accounts(instance.id)
|
||||
if let index = Defaults[.instances].firstIndex(where: { $0.id == instance.id }) {
|
||||
|
@@ -263,7 +263,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
|
||||
}
|
||||
|
||||
static func proxiedAsset(instance: Instance, asset: AVURLAsset) -> AVURLAsset? {
|
||||
guard let instanceURLComponents = URLComponents(string: instance.url),
|
||||
guard let instanceURLComponents = URLComponents(string: instance.apiURL),
|
||||
var urlComponents = URLComponents(url: asset.url, resolvingAgainstBaseURL: false) else { return nil }
|
||||
|
||||
urlComponents.scheme = instanceURLComponents.scheme
|
||||
|
@@ -7,7 +7,7 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
@Published var account: Account!
|
||||
|
||||
var anonymousAccount: Account {
|
||||
.init(instanceID: account.instance.id, name: "Anonymous", url: account.instance.url)
|
||||
.init(instanceID: account.instance.id, name: "Anonymous", url: account.instance.apiURL)
|
||||
}
|
||||
|
||||
init(account: Account? = nil) {
|
||||
@@ -65,23 +65,23 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
||||
}
|
||||
|
||||
func trending(country: Country, category _: TrendingCategory? = nil) -> Resource {
|
||||
resource(baseURL: account.instance.url, path: "trending")
|
||||
resource(baseURL: account.instance.apiURL, path: "trending")
|
||||
.withParam("region", country.rawValue)
|
||||
}
|
||||
|
||||
func search(_ query: SearchQuery) -> Resource {
|
||||
resource(baseURL: account.instance.url, path: "search")
|
||||
resource(baseURL: account.instance.apiURL, path: "search")
|
||||
.withParam("q", query.query)
|
||||
.withParam("filter", "")
|
||||
}
|
||||
|
||||
func searchSuggestions(query: String) -> Resource {
|
||||
resource(baseURL: account.instance.url, path: "suggestions")
|
||||
resource(baseURL: account.instance.apiURL, path: "suggestions")
|
||||
.withParam("query", query.lowercased())
|
||||
}
|
||||
|
||||
func video(_ id: Video.ID) -> Resource {
|
||||
resource(baseURL: account.instance.url, path: "streams/\(id)")
|
||||
resource(baseURL: account.instance.apiURL, path: "streams/\(id)")
|
||||
}
|
||||
|
||||
var signedIn: Bool { false }
|
||||
|
@@ -51,6 +51,7 @@ extension VideosAPI {
|
||||
func shareURL(_ item: ContentItem) -> URL {
|
||||
var urlComponents = account.instance.urlComponents
|
||||
urlComponents.host = account.instance.frontendHost
|
||||
|
||||
switch item.contentType {
|
||||
case .video:
|
||||
urlComponents.path = "/watch"
|
||||
|
@@ -30,4 +30,8 @@ enum VideosApp: String, CaseIterable {
|
||||
var supportsUserPlaylists: Bool {
|
||||
self == .invidious
|
||||
}
|
||||
|
||||
var hasFrontendURL: Bool {
|
||||
self == .piped
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user