support multiple servers

This commit is contained in:
Rasmus Krämer 2022-04-15 10:16:11 +02:00
parent 9a7b2e8172
commit 29fd29728a
No known key found for this signature in database
GPG key ID: EC9E510611BFDAA2
8 changed files with 68 additions and 38 deletions

View file

@ -10,6 +10,7 @@
CAP_PLUGIN(AbsDatabase, "AbsDatabase", CAP_PLUGIN(AbsDatabase, "AbsDatabase",
CAP_PLUGIN_METHOD(setCurrentServerConnectionConfig, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setCurrentServerConnectionConfig, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(logout, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getDeviceData, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getDeviceData, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(getLocalLibraryItems, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getLocalLibraryItems, CAPPluginReturnPromise);

View file

@ -51,18 +51,18 @@ public class AbsDatabase: CAPPlugin {
Store.serverConfig = config Store.serverConfig = config
call.resolve(convertServerConnectionConfigToJSON(config: config)) call.resolve(convertServerConnectionConfigToJSON(config: config))
} }
@objc func logout(_ call: CAPPluginCall) {
Store.serverConfig = nil
call.resolve()
}
@objc func getDeviceData(_ call: CAPPluginCall) { @objc func getDeviceData(_ call: CAPPluginCall) {
let configs = Database.getServerConnectionConfigs() let configs = Database.getServerConnectionConfigs()
let index = Database.getActiveServerConfigIndex() let index = Database.getLastActiveConfigIndex()
call.resolve([ call.resolve([
"serverConnectionConfigs": configs.map { config in "serverConnectionConfigs": configs.map { config in convertServerConnectionConfigToJSON(config: config) },
return convertServerConnectionConfigToJSON(config: config) "lastServerConnectionConfigId": configs.first { config in config.index == index }?.id,
},
"lastServerConnectionConfigId": index < 0 ? -1 : configs.first(where: {
(config: ServerConnectionConfig) -> Bool in
return config.index == index
})!.id,
// Luckily this isn't implemented yet // Luckily this isn't implemented yet
// "currentLocalPlaybackSession": nil, // "currentLocalPlaybackSession": nil,
]) ])

View file

@ -17,6 +17,11 @@ class ServerConnectionConfig: Object {
@Persisted var username: String @Persisted var username: String
@Persisted var token: String @Persisted var token: String
} }
class ServerConnectionConfigActiveIndex: Object {
// This could overflow, but you really would have to try
@Persisted var index: Int?
}
func convertServerConnectionConfigToJSON(config: ServerConnectionConfig) -> Dictionary<String, Any> { func convertServerConnectionConfigToJSON(config: ServerConnectionConfig) -> Dictionary<String, Any> {
return Database.realmQueue.sync { return Database.realmQueue.sync {

View file

@ -164,11 +164,11 @@ class AudioPlayer: NSObject {
// MARK: - Private // MARK: - Private
private func createAsset() -> AVAsset { private func createAsset() -> AVAsset {
let headers: [String: String] = [ let headers: [String: String] = [
"Authorization": "Bearer \(Store.serverConfig.token)" "Authorization": "Bearer \(Store.serverConfig!.token)"
] ]
debugPrint(activeAudioTrack) debugPrint(activeAudioTrack)
return AVURLAsset(url: URL(string: "\(Store.serverConfig.address)\(activeAudioTrack.contentUrl)")!, options: ["AVURLAssetHTTPHeaderFieldsKey": headers]) return AVURLAsset(url: URL(string: "\(Store.serverConfig!.address)\(activeAudioTrack.contentUrl)")!, options: ["AVURLAssetHTTPHeaderFieldsKey": headers])
} }
private func initAudioSession() { private func initAudioSession() {
do { do {

View file

@ -24,10 +24,10 @@ class ApiClient {
public static func postResource<T: Decodable>(endpoint: String, parameters: [String: String], decodable: T.Type = T.self, callback: ((_ param: T) -> Void)?) { public static func postResource<T: Decodable>(endpoint: String, parameters: [String: String], decodable: T.Type = T.self, callback: ((_ param: T) -> Void)?) {
let headers: HTTPHeaders = [ let headers: HTTPHeaders = [
"Authorization": "Bearer \(Store.serverConfig.token)" "Authorization": "Bearer \(Store.serverConfig!.token)"
] ]
AF.request("\(Store.serverConfig.address)/\(endpoint)", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default, headers: headers).responseDecodable(of: decodable) { response in AF.request("\(Store.serverConfig!.address)/\(endpoint)", method: .post, parameters: parameters, encoder: JSONParameterEncoder.default, headers: headers).responseDecodable(of: decodable) { response in
switch response.result { switch response.result {
case .success(let obj): case .success(let obj):
callback?(obj) callback?(obj)
@ -50,8 +50,8 @@ class ApiClient {
], decodable: PlaybackSession.self) { obj in ], decodable: PlaybackSession.self) { obj in
var session = obj var session = obj
session.serverConnectionConfigId = Store.serverConfig.id session.serverConnectionConfigId = Store.serverConfig!.id
session.serverAddress = Store.serverConfig.address session.serverAddress = Store.serverConfig!.address
callback(session) callback(session)
} }

View file

@ -9,23 +9,12 @@ import Foundation
import RealmSwift import RealmSwift
class Database { class Database {
public static let realmQueue = DispatchQueue(label: "realm-queue")
// All DB releated actions must be executed on "realm-queue" // All DB releated actions must be executed on "realm-queue"
public static let realmQueue = DispatchQueue(label: "realm-queue")
private static var instance: Realm = { private static var instance: Realm = {
// TODO: handle thread errors
try! Realm(queue: realmQueue) try! Realm(queue: realmQueue)
}() }()
public static func getActiveServerConfigIndex() -> Int {
return realmQueue.sync {
guard let config = instance.objects(ServerConnectionConfig.self).first else {
return -1
}
return config.index
}
}
public static func setServerConnectionConfig(config: ServerConnectionConfig) { public static func setServerConnectionConfig(config: ServerConnectionConfig) {
var refrence: ThreadSafeReference<ServerConnectionConfig>? var refrence: ThreadSafeReference<ServerConnectionConfig>?
if config.realm != nil { if config.realm != nil {
@ -35,6 +24,16 @@ class Database {
realmQueue.sync { realmQueue.sync {
let existing: ServerConnectionConfig? = instance.object(ofType: ServerConnectionConfig.self, forPrimaryKey: config.id) let existing: ServerConnectionConfig? = instance.object(ofType: ServerConnectionConfig.self, forPrimaryKey: config.id)
if config.index == 0 {
let lastConfig: ServerConnectionConfig? = instance.objects(ServerConnectionConfig.self).last
if lastConfig != nil {
config.index = lastConfig!.index + 1
} else {
config.index = 1
}
}
do { do {
try instance.write { try instance.write {
if existing != nil { if existing != nil {
@ -54,6 +53,8 @@ class Database {
NSLog("failed to save server config") NSLog("failed to save server config")
debugPrint(exception) debugPrint(exception)
} }
setLastActiveConfigIndex(index: config.index)
} }
} }
public static func getServerConnectionConfigs() -> [ServerConnectionConfig] { public static func getServerConnectionConfigs() -> [ServerConnectionConfig] {
@ -78,4 +79,30 @@ class Database {
return [] return []
} }
} }
public static func setLastActiveConfigIndexToNil() {
realmQueue.sync {
setLastActiveConfigIndex(index: nil)
}
}
public static func setLastActiveConfigIndex(index: Int?) {
let existing = instance.objects(ServerConnectionConfigActiveIndex.self)
let obj = ServerConnectionConfigActiveIndex()
obj.index = index
do {
try instance.write {
instance.delete(existing)
instance.add(obj)
}
} catch(let exception) {
NSLog("failed to save server config active index")
debugPrint(exception)
}
}
public static func getLastActiveConfigIndex() -> Int? {
return realmQueue.sync {
return instance.objects(ServerConnectionConfigActiveIndex.self).first?.index ?? nil
}
}
} }

View file

@ -37,7 +37,7 @@ class NowPlayingInfo {
} }
*/ */
guard let url = URL(string: "\(Store.serverConfig.address)/api/items/\(metadata.itemId)/cover?token=\(Store.serverConfig.token)") else { guard let url = URL(string: "\(Store.serverConfig!.address)/api/items/\(metadata.itemId)/cover?token=\(Store.serverConfig!.token)") else {
return return
} }

View file

@ -10,20 +10,17 @@ import RealmSwift
class Store { class Store {
@ThreadSafe private static var _serverConfig: ServerConnectionConfig? @ThreadSafe private static var _serverConfig: ServerConnectionConfig?
public static var serverConfig: ServerConnectionConfig { public static var serverConfig: ServerConnectionConfig? {
get { get {
if _serverConfig == nil { return _serverConfig
let index = Database.getActiveServerConfigIndex()
// TODO: change this when multiple configs are possible
_serverConfig = Database.getServerConnectionConfigs().first { config in
return config.index == index
}
}
return _serverConfig ?? ServerConnectionConfig()
} }
set(updated) { set(updated) {
Database.setServerConnectionConfig(config: updated) if updated != nil {
Database.setServerConnectionConfig(config: updated!)
} else {
Database.setLastActiveConfigIndexToNil()
}
_serverConfig = nil _serverConfig = nil
} }
} }