148 lines
5.7 KiB
Swift
148 lines
5.7 KiB
Swift
//
|
|
// SetupView.swift
|
|
// meterios
|
|
//
|
|
// (c) 2025 Martin "maride" Dessauer
|
|
//
|
|
|
|
import SwiftUI
|
|
import OSLog
|
|
|
|
struct SetupView: View {
|
|
@State private var tmpAddress: String = "mete.chaosdorf.space"
|
|
@State private var tmpUsers: Array<MeteClientUser> = []
|
|
@State private var selectedUserID: Int = 0
|
|
|
|
@FocusState private var connectionFieldFocused: Bool
|
|
@State private var connectionStatus: String?
|
|
@State private var connectionStatusColor: Color?
|
|
@State private var connectionStatusIcon: String?
|
|
@State private var connectionStatusVisible: Bool = false
|
|
@State private var connectionStatusProgressVisible: Bool = false
|
|
|
|
@State private var userListVisible: Bool = false
|
|
@State private var saveButtonEnabled: Bool = false
|
|
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
func tryConnect() {
|
|
// If there was a previous connection attempt, the user list and save button might still be visible - hide them again
|
|
userListVisible = false
|
|
saveButtonEnabled = false
|
|
|
|
// Update status
|
|
updateConnStatus(String(format: String(localized: "CONNECTING_TO_FMT"), tmpAddress), statusIcon: "network", progressVisible: true)
|
|
|
|
// Connect to the server asynchronously
|
|
Task {
|
|
// Un-Focus the address field to hide keyboard
|
|
connectionFieldFocused = false
|
|
|
|
// Create test connector
|
|
do {
|
|
// Try out the connection
|
|
let tmpConnector = MeteClient(address: tmpAddress, userID: -1)
|
|
tmpUsers = try await tmpConnector.GetUsers()
|
|
updateConnStatus(String(localized: "CONNECTION_SUCCESSFUL"), statusIcon: "checkmark.icloud.fill", color: .green, progressVisible: false)
|
|
userListVisible = true
|
|
} catch {
|
|
updateConnStatus(error.localizedDescription, statusIcon: "bolt.horizontal.circle.fill", color: .red, progressVisible: false)
|
|
let _ = Logger().error("Failed to connect to new backend \(tmpAddress): \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func updateConnStatus(_ statusText: String, statusIcon: String = "", color: Color = .blue, progressVisible: Bool = true) {
|
|
connectionStatus = statusText
|
|
connectionStatusIcon = statusIcon
|
|
connectionStatusColor = color
|
|
connectionStatusProgressVisible = progressVisible
|
|
connectionStatusVisible = statusText != ""
|
|
}
|
|
|
|
var body: some View {
|
|
// Meterios banner
|
|
ZStack {
|
|
// Background color
|
|
Color(.sRGB, red: 0, green: 57/255, blue: 132/255)
|
|
.ignoresSafeArea()
|
|
.frame(maxHeight: 200)
|
|
|
|
// Logo and text
|
|
HStack {
|
|
Image(uiImage: UIImage(named: "mete-transparent")!)
|
|
.resizable()
|
|
.aspectRatio(contentMode: .fit)
|
|
.frame(maxWidth: 100, maxHeight: 100)
|
|
.contentMargins(32.0)
|
|
.fixedSize()
|
|
Spacer()
|
|
VStack(alignment: .leading) {
|
|
Text(String(localized: "METERIOS")).font(.title).fontWeight(.heavy).foregroundStyle(.white)
|
|
Text(String(localized: "METERIOS_SLOGAN")).font(.title2).foregroundStyle(.white)
|
|
}.fixedSize()
|
|
}.fixedSize()
|
|
}
|
|
|
|
// Input fields
|
|
Form {
|
|
// Connection
|
|
Section(content: {
|
|
// Address field
|
|
TextField(text: $tmpAddress, label: { Text(tmpAddress) })
|
|
.textInputAutocapitalization(.never)
|
|
.disableAutocorrection(true)
|
|
.focused($connectionFieldFocused)
|
|
.onSubmit {
|
|
tryConnect()
|
|
}
|
|
|
|
Button(String(localized: "CONNECT"), action: {
|
|
tryConnect()
|
|
})
|
|
}, header: {
|
|
Text(String(localized: "CONNECTION"))
|
|
}, footer: {
|
|
// Status bar
|
|
if connectionStatusVisible {
|
|
HStack {
|
|
// Status text
|
|
Label(
|
|
connectionStatus ?? "",
|
|
systemImage: connectionStatusIcon ?? "questionmark.diamond.fill"
|
|
).foregroundStyle(connectionStatusColor ?? .red)
|
|
// Progress indicator
|
|
if connectionStatusProgressVisible {
|
|
ProgressView().frame(width: 8, height: 8)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
// User selection
|
|
if userListVisible {
|
|
Picker(String(localized: "ACCOUNT"), selection: $selectedUserID, content: {
|
|
ForEach(tmpUsers, id: \.self.meteID) { (user: MeteClientUser) in
|
|
Text(user.displayName).tag(user.displayName)
|
|
}
|
|
})
|
|
.onChange(of: selectedUserID, {
|
|
saveButtonEnabled = true
|
|
})
|
|
}
|
|
|
|
// Save button
|
|
Section {
|
|
Button(action: {
|
|
let newAcc = Account(address: tmpAddress, userID: selectedUserID)
|
|
AccountManager.default.AddAccount(newAcc)
|
|
AccountManager.default.SelectAccount(newAcc)
|
|
dismiss()
|
|
}) {
|
|
Text(String(localized: "SAVE_CONNECTION_SETTINGS")).frame(maxWidth: .infinity)
|
|
}.tint(.green).disabled(!saveButtonEnabled)
|
|
}
|
|
}
|
|
}
|
|
}
|