Add multi url support to stored server
This commit is contained in:
parent
a06ceb7453
commit
43090831cb
|
@ -19,7 +19,7 @@ struct PublicUserButton: View {
|
|||
var body: some View {
|
||||
VStack {
|
||||
if publicUser.primaryImageTag != nil {
|
||||
ImageView(src: URL(string: "\(SessionManager.main.currentLogin.server.uri)/Users/\(publicUser.id ?? "")/Images/Primary?width=500&quality=80&tag=\(publicUser.primaryImageTag!)")!)
|
||||
ImageView(src: URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Users/\(publicUser.id ?? "")/Images/Primary?width=500&quality=80&tag=\(publicUser.primaryImageTag!)")!)
|
||||
.frame(width: 250, height: 250)
|
||||
.cornerRadius(125.0)
|
||||
} else {
|
||||
|
|
|
@ -26,7 +26,7 @@ struct ServerDetailView: View {
|
|||
HStack {
|
||||
Text("URI")
|
||||
Spacer()
|
||||
Text(SessionManager.main.currentLogin.server.uri)
|
||||
Text(SessionManager.main.currentLogin.server.currentURI)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
|
|
|
@ -164,13 +164,13 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
// Item is being transcoded by request of server
|
||||
if let transcodiungUrl = mediaSource.transcodingUrl {
|
||||
item.videoType = .transcode
|
||||
streamURL = URL(string: "\(SessionManager.main.currentLogin.server.uri)\(transcodiungUrl)")!
|
||||
streamURL = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)\(transcodiungUrl)")!
|
||||
}
|
||||
// Item will be directly played by the client
|
||||
else {
|
||||
item.videoType = .directPlay
|
||||
// streamURL = URL(string: "\(SessionManager.main.currentLogin.server.uri)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&deviceId=\(SessionManager.current.deviceID)&api_key=\(SessionManager.current.accessToken)&Tag=\(mediaSource.eTag!)")!
|
||||
streamURL = URL(string: "\(SessionManager.main.currentLogin.server.uri)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
// streamURL = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&deviceId=\(SessionManager.current.deviceID)&api_key=\(SessionManager.current.accessToken)&Tag=\(mediaSource.eTag!)")!
|
||||
streamURL = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
}
|
||||
|
||||
item.videoUrl = streamURL
|
||||
|
@ -185,7 +185,7 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
var deliveryUrl: URL?
|
||||
|
||||
if stream.deliveryMethod == .external {
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.uri)\(stream.deliveryUrl!)")!
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)\(stream.deliveryUrl!)")!
|
||||
}
|
||||
|
||||
let subtitle = Subtitle(name: stream.displayTitle ?? "Unknown", id: Int32(stream.index!), url: deliveryUrl, delivery: stream.deliveryMethod!, codec: stream.codec ?? "webvtt", languageCode: stream.language ?? "")
|
||||
|
|
|
@ -11,7 +11,7 @@ import Stinsen
|
|||
|
||||
struct ConnectToServerView: View {
|
||||
|
||||
@StateObject var viewModel: ConnectToServerViewModel
|
||||
@ObservedObject var viewModel: ConnectToServerViewModel
|
||||
@State var uri = ""
|
||||
|
||||
var body: some View {
|
||||
|
@ -98,6 +98,14 @@ struct ConnectToServerView: View {
|
|||
message: Text(viewModel.errorMessage?.displayMessage ?? "Unknown Error"),
|
||||
dismissButton: .cancel())
|
||||
}
|
||||
.alert(item: $viewModel.addServerURIPayload) { _ in
|
||||
Alert(title: Text("Existing Server"),
|
||||
message: Text("Server \(viewModel.addServerURIPayload?.server.name ?? "") already exists. Add new URI?"),
|
||||
primaryButton: .default(Text("Existing Server"), action: {
|
||||
viewModel.addURIToServer(addServerURIPayload: viewModel.addServerURIPayload!)
|
||||
}),
|
||||
secondaryButton: .cancel())
|
||||
}
|
||||
.navigationTitle("Connect")
|
||||
.onAppear {
|
||||
viewModel.discoverServers()
|
||||
|
|
|
@ -26,7 +26,7 @@ struct ServerDetailView: View {
|
|||
HStack {
|
||||
Text("URI")
|
||||
Spacer()
|
||||
Text(SessionManager.main.currentLogin.server.uri)
|
||||
Text(SessionManager.main.currentLogin.server.currentURI)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ struct ServerListView: View {
|
|||
.font(.title2)
|
||||
.foregroundColor(.primary)
|
||||
|
||||
Text(server.uri)
|
||||
Text(server.currentURI)
|
||||
.font(.footnote)
|
||||
.disabled(true)
|
||||
.foregroundColor(.secondary)
|
||||
|
|
|
@ -549,7 +549,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
|||
let mediaSource = response.mediaSources!.first.self!
|
||||
if mediaSource.transcodingUrl != nil {
|
||||
// Item is being transcoded by request of server
|
||||
let streamURL = URL(string: "\(SessionManager.main.currentLogin.server.uri)\(mediaSource.transcodingUrl!)")
|
||||
let streamURL = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)\(mediaSource.transcodingUrl!)")
|
||||
let item = PlaybackItem()
|
||||
item.videoType = .transcode
|
||||
item.videoUrl = streamURL!
|
||||
|
@ -563,7 +563,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
|||
if stream.type == .subtitle {
|
||||
var deliveryUrl: URL?
|
||||
if stream.deliveryMethod == .external {
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.uri)\(stream.deliveryUrl ?? "")")!
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)\(stream.deliveryUrl ?? "")")!
|
||||
} else {
|
||||
deliveryUrl = nil
|
||||
}
|
||||
|
@ -597,8 +597,8 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
|||
} else {
|
||||
// TODO: todo
|
||||
// Item will be directly played by the client.
|
||||
let streamURL = URL(string: "\(SessionManager.main.currentLogin.server.uri)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
// URL(string: "\(SessionManager.main.currentLogin.server.uri)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&deviceId=\(SessionManager.current.deviceID)&api_key=\(SessionManager.current.accessToken)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
let streamURL = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
// URL(string: "\(SessionManager.main.currentLogin.server.currentURI)/Videos/\(manifest.id!)/stream?Static=true&mediaSourceId=\(manifest.id!)&deviceId=\(SessionManager.current.deviceID)&api_key=\(SessionManager.current.accessToken)&Tag=\(mediaSource.eTag ?? "")")!
|
||||
|
||||
let item = PlaybackItem()
|
||||
item.videoUrl = streamURL
|
||||
|
@ -613,7 +613,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
|
|||
if stream.type == .subtitle {
|
||||
var deliveryUrl: URL?
|
||||
if stream.deliveryMethod == .external {
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.uri)\(stream.deliveryUrl!)")!
|
||||
deliveryUrl = URL(string: "\(SessionManager.main.currentLogin.server.currentURI)\(stream.deliveryUrl!)")!
|
||||
} else {
|
||||
deliveryUrl = nil
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ extension PlayerViewController: GCKGenericChannelDelegate {
|
|||
"userId": SessionManager.main.currentLogin.user.id,
|
||||
// "deviceId": SessionManager.main.currentLogin.de.deviceID,
|
||||
"accessToken": SessionManager.main.currentLogin.user.accessToken,
|
||||
"serverAddress": SessionManager.main.currentLogin.server.uri,
|
||||
"serverAddress": SessionManager.main.currentLogin.server.currentURI,
|
||||
"serverId": SessionManager.main.currentLogin.server.id,
|
||||
"serverVersion": "10.8.0",
|
||||
"receiverName": castSessionManager.currentCastSession!.device.friendlyName!,
|
||||
|
|
|
@ -74,7 +74,7 @@ public extension BaseItemDto {
|
|||
|
||||
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
|
||||
let urlString =
|
||||
"\(SessionManager.main.currentLogin.server.uri)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
"\(SessionManager.main.currentLogin.server.currentURI)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
return URL(string: urlString)!
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ public extension BaseItemDto {
|
|||
|
||||
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
|
||||
let urlString =
|
||||
"\(SessionManager.main.currentLogin.server.uri)/Items/\(parentBackdropItemId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
"\(SessionManager.main.currentLogin.server.currentURI)/Items/\(parentBackdropItemId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
return URL(string: urlString)!
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ public extension BaseItemDto {
|
|||
let imageTag = seriesPrimaryImageTag ?? ""
|
||||
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
|
||||
let urlString =
|
||||
"\(SessionManager.main.currentLogin.server.uri)/Items/\(seriesId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
"\(SessionManager.main.currentLogin.server.currentURI)/Items/\(seriesId ?? "")/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
return URL(string: urlString)!
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ public extension BaseItemDto {
|
|||
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
|
||||
|
||||
let urlString =
|
||||
"\(SessionManager.main.currentLogin.server.uri)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
"\(SessionManager.main.currentLogin.server.currentURI)/Items/\(imageItemId)/Images/\(imageType)?maxWidth=\(String(Int(x)))&quality=96&tag=\(imageTag)"
|
||||
// print(urlString)
|
||||
return URL(string: urlString)!
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ extension BaseItemPerson {
|
|||
// MARK: PortraitImageStackable
|
||||
extension BaseItemPerson: PortraitImageStackable {
|
||||
public func imageURLContsructor(maxWidth: Int) -> URL {
|
||||
return self.getImage(baseURL: SessionManager.main.currentLogin.server.uri, maxWidth: maxWidth)
|
||||
return self.getImage(baseURL: SessionManager.main.currentLogin.server.currentURI, maxWidth: maxWidth)
|
||||
}
|
||||
|
||||
public var title: String {
|
||||
|
|
|
@ -34,16 +34,12 @@ final class SessionManager {
|
|||
guard let server = user.server, let accessToken = user.accessToken else { fatalError("No associated server or access token for last user?") }
|
||||
guard let existingServer = SwiftfinStore.dataStack.fetchExisting(server) else { return }
|
||||
|
||||
JellyfinAPI.basePath = server.uri
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
setAuthHeader(with: accessToken.value)
|
||||
currentLogin = (server: existingServer.state, user: user.state)
|
||||
}
|
||||
}
|
||||
|
||||
private func generateServerUserID(server: SwiftfinStore.Models.StoredServer, user: SwiftfinStore.Models.StoredUser) -> String {
|
||||
return "\(server.id)-\(user.id)"
|
||||
}
|
||||
|
||||
func fetchServers() -> [SwiftfinStore.State.Server] {
|
||||
let servers = try! SwiftfinStore.dataStack.fetchAll(From<SwiftfinStore.Models.StoredServer>())
|
||||
return servers.map({ $0.state })
|
||||
|
@ -79,7 +75,8 @@ final class SessionManager {
|
|||
let os = response.operatingSystem,
|
||||
let version = response.version else { throw JellyfinAPIError("Missing server data from network call") }
|
||||
|
||||
newServer.uri = uri
|
||||
newServer.uris = [uri]
|
||||
newServer.currentURI = uri
|
||||
newServer.name = name
|
||||
newServer.id = id
|
||||
newServer.os = os
|
||||
|
@ -103,11 +100,65 @@ final class SessionManager {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func addURIToServer(server: SwiftfinStore.State.Server, uri: String) -> AnyPublisher<SwiftfinStore.State.Server, Error> {
|
||||
return Just(server)
|
||||
.tryMap { server -> (SwiftfinStore.Models.StoredServer, UnsafeDataTransaction) in
|
||||
|
||||
let transaction = SwiftfinStore.dataStack.beginUnsafe()
|
||||
|
||||
guard let existingServer = try? SwiftfinStore.dataStack.fetchOne(From<SwiftfinStore.Models.StoredServer>(),
|
||||
[Where<SwiftfinStore.Models.StoredServer>("id == %@", server.id)]) else {
|
||||
fatalError("No stored server associated with given state server?")
|
||||
}
|
||||
|
||||
guard let editServer = transaction.edit(existingServer) else { fatalError("Can't get proxy for existing object?") }
|
||||
editServer.uris.insert(uri)
|
||||
|
||||
return (editServer, transaction)
|
||||
}
|
||||
.handleEvents(receiveOutput: { (server, transaction) in
|
||||
try? transaction.commitAndWait()
|
||||
})
|
||||
.map({ (server, _) in
|
||||
return server.state
|
||||
})
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func setServerCurrentURI(server: SwiftfinStore.State.Server, uri: String) -> AnyPublisher<SwiftfinStore.State.Server, Error> {
|
||||
return Just(server)
|
||||
.tryMap { server -> (SwiftfinStore.Models.StoredServer, UnsafeDataTransaction) in
|
||||
|
||||
let transaction = SwiftfinStore.dataStack.beginUnsafe()
|
||||
|
||||
guard let existingServer = try? SwiftfinStore.dataStack.fetchOne(From<SwiftfinStore.Models.StoredServer>(),
|
||||
[Where<SwiftfinStore.Models.StoredServer>("id == %@", server.id)]) else {
|
||||
fatalError("No stored server associated with given state server?")
|
||||
}
|
||||
|
||||
if !existingServer.uris.contains(uri) {
|
||||
fatalError("Attempting to set current uri while server doesn't contain it?")
|
||||
}
|
||||
|
||||
guard let editServer = transaction.edit(existingServer) else { fatalError("Can't get proxy for existing object?") }
|
||||
editServer.currentURI = uri
|
||||
|
||||
return (editServer, transaction)
|
||||
}
|
||||
.handleEvents(receiveOutput: { (server, transaction) in
|
||||
try? transaction.commitAndWait()
|
||||
})
|
||||
.map({ (server, _) in
|
||||
return server.state
|
||||
})
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
// Logs in a user with an associated server, storing if successful
|
||||
func loginUser(server: SwiftfinStore.State.Server, username: String, password: String) -> AnyPublisher<SwiftfinStore.State.User, Error> {
|
||||
setAuthHeader(with: "")
|
||||
|
||||
JellyfinAPI.basePath = server.uri
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
|
||||
return UserAPI.authenticateUserByName(authenticateUserByName: AuthenticateUserByName(username: username, pw: password))
|
||||
.tryMap({ response -> (SwiftfinStore.Models.StoredServer, SwiftfinStore.Models.StoredUser, UnsafeDataTransaction) in
|
||||
|
@ -163,7 +214,7 @@ final class SessionManager {
|
|||
}
|
||||
|
||||
func loginUser(server: SwiftfinStore.State.Server, user: SwiftfinStore.State.User) {
|
||||
JellyfinAPI.basePath = server.uri
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
SwiftfinStore.Defaults.suite[.lastServerUserID] = user.id
|
||||
setAuthHeader(with: user.accessToken)
|
||||
currentLogin = (server: server, user: user)
|
||||
|
|
|
@ -14,20 +14,22 @@ import Defaults
|
|||
enum SwiftfinStore {
|
||||
|
||||
// MARK: State
|
||||
// Safe, copyable representations of their underlying CoreStoredObject's
|
||||
// Safe, copyable representations of their underlying CoreStoredObject
|
||||
// Relationships are represented by the related object's IDs or value
|
||||
enum State {
|
||||
|
||||
struct Server {
|
||||
let uri: String
|
||||
let uris: Set<String>
|
||||
let currentURI: String
|
||||
let name: String
|
||||
let id: String
|
||||
let os: String
|
||||
let version: String
|
||||
let userIDs: [String]
|
||||
|
||||
fileprivate init(uri: String, name: String, id: String, os: String, version: String, usersIDs: [String]) {
|
||||
self.uri = uri
|
||||
fileprivate init(uris: Set<String>, currentURI: String, name: String, id: String, os: String, version: String, usersIDs: [String]) {
|
||||
self.uris = uris
|
||||
self.currentURI = currentURI
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.os = os
|
||||
|
@ -36,7 +38,13 @@ enum SwiftfinStore {
|
|||
}
|
||||
|
||||
static var sample: Server {
|
||||
return Server(uri: "https://www.notaurl.com", name: "Johnny's Tree", id: "123abc", os: "macOS", version: "1.1.1", usersIDs: ["1", "2"])
|
||||
return Server(uris: ["https://www.notaurl.com", "http://www.maybeaurl.org"],
|
||||
currentURI: "https://www.notaurl.com",
|
||||
name: "Johnny's Tree",
|
||||
id: "123abc",
|
||||
os: "macOS",
|
||||
version: "1.1.1",
|
||||
usersIDs: ["1", "2"])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +62,10 @@ enum SwiftfinStore {
|
|||
}
|
||||
|
||||
static var sample: User {
|
||||
return User(username: "JohnnyAppleseed", id: "123abc", serverID: "123abc", accessToken: "open-sesame")
|
||||
return User(username: "JohnnyAppleseed",
|
||||
id: "123abc",
|
||||
serverID: "123abc",
|
||||
accessToken: "open-sesame")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,8 +75,11 @@ enum SwiftfinStore {
|
|||
|
||||
final class StoredServer: CoreStoreObject {
|
||||
|
||||
@Field.Stored("uri")
|
||||
var uri: String = ""
|
||||
@Field.Coded("uris", coder: FieldCoders.Json.self)
|
||||
var uris: Set<String> = []
|
||||
|
||||
@Field.Stored("currentURI")
|
||||
var currentURI: String = ""
|
||||
|
||||
@Field.Stored("name")
|
||||
var name: String = ""
|
||||
|
@ -83,7 +97,8 @@ enum SwiftfinStore {
|
|||
var users: Set<StoredUser>
|
||||
|
||||
var state: State.Server {
|
||||
return State.Server(uri: uri,
|
||||
return State.Server(uris: uris,
|
||||
currentURI: currentURI,
|
||||
name: name,
|
||||
id: id,
|
||||
os: os,
|
||||
|
@ -143,11 +158,12 @@ enum SwiftfinStore {
|
|||
Entity<SwiftfinStore.Models.StoredUser>("User"),
|
||||
Entity<SwiftfinStore.Models.StoredAccessToken>("AccessToken")
|
||||
],
|
||||
versionLock: [
|
||||
"AccessToken": [0xa8c475e874494bb1, 0x79486e93449f0b3d, 0xa7dc4a0003541edb, 0x94183fae7580ef72],
|
||||
"Server": [0x39c64a826739077e, 0xa7ac63744fd7df32, 0xef3c9d4fe638fbfb, 0xdabd796256df14db],
|
||||
"User": [0x845de08a74bc53ed, 0xe95a406a29f3a5d0, 0x9eda732821a15ea9, 0xb5afa531e41ce8a]
|
||||
])
|
||||
versionLock: nil)
|
||||
// versionLock: [
|
||||
// "AccessToken": [0xa8c475e874494bb1, 0x79486e93449f0b3d, 0xa7dc4a0003541edb, 0x94183fae7580ef72],
|
||||
// "Server": [0x39c64a826739077e, 0xa7ac63744fd7df32, 0xef3c9d4fe638fbfb, 0xdabd796256df14db],
|
||||
// "User": [0x845de08a74bc53ed, 0xe95a406a29f3a5d0, 0x9eda732821a15ea9, 0xb5afa531e41ce8a]
|
||||
// ])
|
||||
|
||||
let _dataStack = DataStack(schema)
|
||||
try! _dataStack.addStorageAndWait(
|
||||
|
|
|
@ -12,11 +12,23 @@ import Foundation
|
|||
import JellyfinAPI
|
||||
import Stinsen
|
||||
|
||||
struct AddServerURIPayload: Identifiable {
|
||||
|
||||
let server: SwiftfinStore.State.Server
|
||||
let uri: String
|
||||
|
||||
var id: String {
|
||||
return server.id.appending(uri)
|
||||
}
|
||||
}
|
||||
|
||||
final class ConnectToServerViewModel: ViewModel {
|
||||
|
||||
@RouterObject var router: ConnectToServerCoodinator.Router?
|
||||
@Published var discoveredServers: Set<ServerDiscovery.ServerLookupResponse> = []
|
||||
@Published var searching = false
|
||||
@Published var addServerURIPayload: AddServerURIPayload?
|
||||
|
||||
private let discovery = ServerDiscovery()
|
||||
|
||||
var alertTitle: String {
|
||||
|
@ -40,8 +52,25 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
SessionManager.main.connectToServer(with: uri)
|
||||
.trackActivity(loading)
|
||||
.sink(receiveCompletion: { completion in
|
||||
self.handleAPIRequestError(displayMessage: "Unable to connect to server.", logLevel: .critical, tag: "connectToServer",
|
||||
completion: completion)
|
||||
// This is disgusting. ViewModel Error handling overall needs to be refactored
|
||||
switch completion {
|
||||
case .finished: ()
|
||||
case .failure(let error):
|
||||
switch error {
|
||||
case is SwiftfinStore.Errors:
|
||||
let swiftfinError = error as! SwiftfinStore.Errors
|
||||
switch swiftfinError {
|
||||
case .existingServer(let server):
|
||||
self.addServerURIPayload = AddServerURIPayload(server: server, uri: uri)
|
||||
default:
|
||||
self.handleAPIRequestError(displayMessage: "Unable to connect to server.", logLevel: .critical, tag: "connectToServer",
|
||||
completion: completion)
|
||||
}
|
||||
default:
|
||||
self.handleAPIRequestError(displayMessage: "Unable to connect to server.", logLevel: .critical, tag: "connectToServer",
|
||||
completion: completion)
|
||||
}
|
||||
}
|
||||
}, receiveValue: { server in
|
||||
LogManager.shared.log.debug("Connected to server at \"\(uri)\"", tag: "connectToServer")
|
||||
self.router?.route(to: \.userSignIn, server)
|
||||
|
@ -65,6 +94,17 @@ final class ConnectToServerViewModel: ViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
func addURIToServer(addServerURIPayload: AddServerURIPayload) {
|
||||
SessionManager.main.addURIToServer(server: addServerURIPayload.server, uri: addServerURIPayload.uri)
|
||||
.sink { completion in
|
||||
self.handleAPIRequestError(displayMessage: "Unable to connect to server.", logLevel: .critical, tag: "connectToServer",
|
||||
completion: completion)
|
||||
} receiveValue: { _ in
|
||||
print("Here")
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func cancelConnection() {
|
||||
for cancellable in cancellables {
|
||||
cancellable.cancel()
|
||||
|
|
|
@ -30,7 +30,7 @@ final class UserSignInViewModel: ViewModel {
|
|||
}
|
||||
|
||||
func login(username: String, password: String) {
|
||||
LogManager.shared.log.debug("Attempting to login to server at \"\(server.uri)\"", tag: "login")
|
||||
LogManager.shared.log.debug("Attempting to login to server at \"\(server.currentURI)\"", tag: "login")
|
||||
LogManager.shared.log.debug("username: \(username), password: \(password)", tag: "login")
|
||||
|
||||
SessionManager.main.loginUser(server: server, username: username, password: password)
|
||||
|
|
|
@ -32,7 +32,7 @@ struct NextUpWidgetProvider: TimelineProvider {
|
|||
let savedUser = currentLogin.user
|
||||
var tempCancellables = Set<AnyCancellable>()
|
||||
|
||||
JellyfinAPI.basePath = server.uri
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
TvShowsAPI.getNextUp(userId: savedUser.id, limit: 3,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
imageTypeLimit: 1, enableImageTypes: [.primary, .backdrop, .thumb])
|
||||
|
@ -78,7 +78,7 @@ struct NextUpWidgetProvider: TimelineProvider {
|
|||
|
||||
var tempCancellables = Set<AnyCancellable>()
|
||||
|
||||
JellyfinAPI.basePath = server.uri
|
||||
JellyfinAPI.basePath = server.currentURI
|
||||
TvShowsAPI.getNextUp(userId: savedUser.id, limit: 3,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
imageTypeLimit: 1, enableImageTypes: [.primary, .backdrop, .thumb])
|
||||
|
|
Loading…
Reference in New Issue