oncall-mobile-ios/ntfy/Views/Settings/UserEditorView.swift

129 lines
4.4 KiB
Swift

//
// UserEditorView.swift
// ntfy
//
// Created by Alek Michelson on 4/10/26.
//
import SwiftUI
struct UserEditorView: View {
@EnvironmentObject private var store: Store
let selectedUser: User?
let onSave: (String, String, String) -> Void
let onDelete: (User) -> Void
let onCancel: () -> Void
@State private var baseUrl: String
@State private var username: String
@State private var password: String
init(
selectedUser: User?,
onSave: @escaping (String, String, String) -> Void,
onDelete: @escaping (User) -> Void,
onCancel: @escaping () -> Void
) {
self.selectedUser = selectedUser
self.onSave = onSave
self.onDelete = onDelete
self.onCancel = onCancel
_baseUrl = State(initialValue: selectedUser?.baseUrl ?? "")
_username = State(initialValue: selectedUser?.username ?? "")
_password = State(initialValue: "")
}
var body: some View {
NavigationView {
Form {
Section(
footer: isNewUser
? Text("You can add a user here. All topics for the given server will use this user.")
: Text("Edit the username or password for \(shortUrl(url: baseUrl)) here. This user is used for all topics of this server. Leave the password blank to leave it unchanged.")
) {
if isNewUser {
TextField("Service URL, e.g. https://ntfy.home.io", text: $baseUrl)
.disableAutocapitalization()
.disableAutocorrection(true)
}
TextField("Username", text: $username)
.disableAutocapitalization()
.disableAutocorrection(true)
SecureField("Password", text: $password)
}
}
.navigationTitle(isNewUser ? "Add user" : "Edit user")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
if isNewUser {
Button("Cancel") {
onCancel()
}
} else {
Menu {
Button("Cancel") {
onCancel()
}
if #available(iOS 15.0, *) {
Button(role: .destructive) {
deleteAction()
} label: {
Text("Delete")
}
} else {
Button("Delete") {
deleteAction()
}
}
} label: {
Image(systemName: "ellipsis.circle")
.padding([.leading], 40)
}
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: saveAction) {
Text("Save")
}
.disabled(!isValid())
}
}
}
}
private var isNewUser: Bool {
selectedUser == nil
}
private func saveAction() {
let finalPassword: String
if let user = selectedUser, password.isEmpty {
finalPassword = user.password ?? "?"
} else {
finalPassword = password
}
onSave(baseUrl, username, finalPassword)
}
private func deleteAction() {
guard let selectedUser = selectedUser else { return }
onDelete(selectedUser)
}
private func isValid() -> Bool {
if isNewUser {
if baseUrl.range(of: "^https?://.+", options: .regularExpression, range: nil, locale: nil) == nil {
return false
} else if username.isEmpty || password.isEmpty {
return false
} else if store.getUser(baseUrl: baseUrl) != nil {
return false
}
} else if username.isEmpty {
return false
}
return true
}
}