Luminate/Sources/Luminate/ServerSetupView.swift

78 lines
2.6 KiB
Swift

import Adwaita
import Foundation
import LuminateCore
public struct ServerSetupView: View {
@State private var serverURL = ""
@State private var username = ""
@State private var password = ""
@State private var isLoading = false
@State private var error: String?
public var onLogin: (JellyfinClient, String) -> Void
public init(onLogin: @escaping (JellyfinClient, String) -> Void) {
self.onLogin = onLogin
}
public var view: Body {
VStack {
StatusPage(
"Connect to Server",
icon: .custom(name: "dev.bscubed.Luminate"),
description: "Enter your Jellyfin server details"
) {
VStack(spacing: 16) {
PreferencesGroup("Server configuration") {
EntryRow("Server URL", text: $serverURL)
EntryRow("Username", text: $username)
PasswordEntryRow("Password", text: $password)
}
Button("Connect") {
connect()
}
.style("suggested-action")
if isLoading {
Spinner()
}
if let error {
Text(error)
.style("error")
}
}
.padding()
}
}
}
private func connect() {
var urlString = serverURL.trimmingCharacters(in: .whitespacesAndNewlines)
if !urlString.hasPrefix("http://") && !urlString.hasPrefix("https://") {
urlString = "https://" + urlString
}
urlString = urlString.trimmingCharacters(in: CharacterSet(charactersIn: "/"))
guard let url = URL(string: urlString), !username.isEmpty else {
error = "Please enter a valid server URL and username"
return
}
isLoading = true
error = nil
Task {
do {
let client = JellyfinClient(serverURL: url)
let result = try await client.authenticate(username: username, password: password)
let userId = result.user?.value1.id ?? ""
isLoading = false
onLogin(client, userId)
} catch (JellyfinError.httpError(let code)) {
isLoading = false
self.error = "Failed to login. HTTP code \(code)"
} catch {
isLoading = false
self.error = error.localizedDescription
print(error.localizedDescription)
}
}
}
}