diff options
Diffstat (limited to 'Hotline/macOS/AccountManagerView.swift')
| -rw-r--r-- | Hotline/macOS/AccountManagerView.swift | 117 |
1 files changed, 62 insertions, 55 deletions
diff --git a/Hotline/macOS/AccountManagerView.swift b/Hotline/macOS/AccountManagerView.swift index 57682cc..84ae6dc 100644 --- a/Hotline/macOS/AccountManagerView.swift +++ b/Hotline/macOS/AccountManagerView.swift @@ -2,20 +2,20 @@ import SwiftUI struct AccountManagerView: View { @Environment(Hotline.self) private var model: Hotline - + @State private var accounts: [HotlineAccount] = [] @State private var selection: HotlineAccount? @State private var loading: Bool = true - + @State private var pendingName: String = "" @State private var pendingLogin: String = "" @State private var pendingPassword: String = "" @State private var pendingAccess = HotlineUserAccessOptions.defaultAccess - + @State private var toDelete: HotlineAccount? - + let placeholderPassword = "xxxxxxxxxxxxxxxxxx" - + var body: some View { HStack(spacing: 0) { ZStack { @@ -26,8 +26,7 @@ struct AccountManagerView: View { } if selection != nil { accountDetails - } - else { + } else { ZStack(alignment: .center) { Text("No Account Selected") .font(.title) @@ -50,8 +49,9 @@ struct AccountManagerView: View { .toolbar { ToolbarItem(placement: .primaryAction) { Button { - let newAccount = HotlineAccount("unnamed", "unnamed", HotlineUserAccessOptions.defaultAccess) - + let newAccount = HotlineAccount( + "unnamed", "unnamed", HotlineUserAccessOptions.defaultAccess) + pendingPassword = HotlineAccount.randomPassword() accounts.append(newAccount) selection = newAccount @@ -61,7 +61,7 @@ struct AccountManagerView: View { .help("Create a new account") .disabled(model.access?.contains(.canCreateUsers) != true) } - + ToolbarItem(placement: .destructiveAction) { Button { toDelete = selection @@ -73,7 +73,7 @@ struct AccountManagerView: View { } } } - + var accountDetails: some View { VStack(alignment: .center, spacing: 0) { ScrollView(.vertical) { @@ -92,7 +92,7 @@ struct AccountManagerView: View { } .textFieldStyle(.roundedBorder) .controlSize(.large) - + Section("File System Maintenance") { Toggle("Can Download Files", isOn: $pendingAccess.bind(.canDownloadFiles)) .disabled(model.access?.contains(.canDownloadFiles) == false) @@ -127,7 +127,7 @@ struct AccountManagerView: View { Toggle("Can Make Aliases", isOn: $pendingAccess.bind(.canMakeAliases)) .disabled(model.access?.contains(.canMakeAliases) == false) } - + Section("User Maintenance") { Toggle("Can Create Accounts", isOn: $pendingAccess.bind(.canCreateUsers)) .disabled(model.access?.contains(.canCreateUsers) == false) @@ -139,20 +139,20 @@ struct AccountManagerView: View { .disabled(model.access?.contains(.canModifyUsers) == false) Toggle("Can Get User Info", isOn: $pendingAccess.bind(.canGetClientInfo)) .disabled(model.access?.contains(.canGetClientInfo) == false) - + Toggle("Can Disconnect Users", isOn: $pendingAccess.bind(.canDisconnectUsers)) .disabled(model.access?.contains(.canDisconnectUsers) == false) Toggle("Cannot be Disconnected", isOn: $pendingAccess.bind(.cantBeDisconnected)) .disabled(model.access?.contains(.cantBeDisconnected) == false) } - + Section("Messaging") { Toggle("Can Send Messages", isOn: $pendingAccess.bind(.canSendMessages)) .disabled(model.access?.contains(.canSendMessages) == false) Toggle("Can Broadcast", isOn: $pendingAccess.bind(.canBroadcast)) .disabled(model.access?.contains(.canBroadcast) == false) } - + Section("News") { Toggle("Can Read Articles", isOn: $pendingAccess.bind(.canReadMessageBoard)) .disabled(model.access?.contains(.canReadMessageBoard) == false) @@ -169,7 +169,7 @@ struct AccountManagerView: View { Toggle("Can Delete News Bundles", isOn: $pendingAccess.bind(.canDeleteNewsFolders)) .disabled(model.access?.contains(.canDeleteNewsFolders) == false) } - + Section("Chat") { Toggle("Can Initiate Private Chat", isOn: $pendingAccess.bind(.canCreateChat)) .disabled(model.access?.contains(.canCreateChat) == false) @@ -178,7 +178,7 @@ struct AccountManagerView: View { Toggle("Can Send Chat", isOn: $pendingAccess.bind(.canSendChat)) .disabled(model.access?.contains(.canSendChat) == false) } - + Section("Miscellaneous") { Toggle("Can Use Any Name", isOn: $pendingAccess.bind(.canUseAnyName)) .disabled(model.access?.contains(.canUseAnyName) == false) @@ -193,7 +193,7 @@ struct AccountManagerView: View { pendingName = selection.name pendingLogin = selection.login pendingAccess = selection.access - + if selection.persisted { if selection.password == nil { pendingPassword = "" @@ -203,12 +203,12 @@ struct AccountManagerView: View { } } } - .onAppear() { + .onAppear { if let selection { pendingName = selection.name pendingLogin = selection.login pendingAccess = selection.access - + if selection.persisted { if selection.password == nil { pendingPassword = "" @@ -216,22 +216,22 @@ struct AccountManagerView: View { pendingPassword = placeholderPassword } } else { - pendingPassword = HotlineAccount.randomPassword() + pendingPassword = HotlineAccount.randomPassword() } } } } .frame(maxWidth: .infinity) - + Divider() - - HStack() { + + HStack { Button("Revert") { if let selection { pendingAccess = selection.access pendingName = selection.name pendingLogin = selection.login - + if selection.password != nil { pendingPassword = selection.password! } @@ -240,46 +240,52 @@ struct AccountManagerView: View { .controlSize(.large) .frame(minWidth: 75) .disabled(!self.isSaveable()) -// .padding() - + // .padding() + Spacer() - - Button("Save"){ + + Button("Save") { guard let selection else { return } - + // Update existing account if selection.persisted == true { if pendingPassword == placeholderPassword { Task { @MainActor in - model.client.sendSetUser(name: pendingName, login: pendingLogin, newLogin: nil, password: nil, access: pendingAccess.rawValue) + model.client.sendSetUser( + name: pendingName, login: pendingLogin, newLogin: nil, password: nil, + access: pendingAccess.rawValue) } } else { Task { @MainActor in - model.client.sendSetUser(name: pendingName, login: pendingLogin, newLogin: nil, password: pendingPassword, access: pendingAccess.rawValue) + model.client.sendSetUser( + name: pendingName, login: pendingLogin, newLogin: nil, password: pendingPassword, + access: pendingAccess.rawValue) } } } else { // Create new existing account Task { @MainActor in - model.client.sendCreateUser(name: pendingName, login: pendingLogin, password: pendingPassword, access: pendingAccess.rawValue) + model.client.sendCreateUser( + name: pendingName, login: pendingLogin, password: pendingPassword, + access: pendingAccess.rawValue) } self.selection?.password = pendingPassword pendingPassword = placeholderPassword } - + var account = HotlineAccount(pendingName, pendingLogin, pendingAccess) account.persisted = true account.password = placeholderPassword - + accounts = accounts.filter { $0.persisted == true && $0.login != selection.login } - + // Add new account to list accounts.append(account) - + // Re-sort accounts accounts.sort { $0.login < $1.login } self.selection = account @@ -291,9 +297,9 @@ struct AccountManagerView: View { } .padding() } - + } - + var accountList: some View { List(accounts, id: \.self, selection: $selection) { account in HStack(spacing: 5) { @@ -304,8 +310,7 @@ struct AccountManagerView: View { // .padding(.leading, 4) Text(account.login) .foregroundStyle(Color.hotlineRed) - } - else if account.access.rawValue == 0 { + } else if account.access.rawValue == 0 { Image("User") .frame(width: 16, height: 16) // .padding(.leading, 4) @@ -333,65 +338,67 @@ struct AccountManagerView: View { .frame(width: 250) .sheet(item: $toDelete) { item in Form { - HStack{ + HStack { Image(systemName: "exclamationmark.triangle") .font(.system(size: 30)) Text("Delete account \"\(item.name)\" and all associated files?") .lineSpacing(4) } } - .frame(minWidth: 300, idealWidth: 450, maxWidth: .infinity, minHeight: 100, idealHeight: 100, maxHeight: .infinity) + .frame( + minWidth: 300, idealWidth: 450, maxWidth: .infinity, minHeight: 100, idealHeight: 100, + maxHeight: .infinity + ) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { toDelete = nil } } - + ToolbarItem(placement: .primaryAction) { Button("Delete") { guard let userToDelete = toDelete else { return } - + self.toDelete = nil self.selection = nil - + if userToDelete.persisted { Task { @MainActor in model.client.sendDeleteUser(login: userToDelete.login) } } - + accounts = accounts.filter { $0.login != userToDelete.login } - + } } } } } - - + private func isSaveable() -> Bool { guard let selection else { return false } - + // Disable save if login field is cleared if pendingLogin == "" { return false } - + // If the account initial has a password and it was updated if selection.password != nil && pendingPassword != placeholderPassword { return true } - + // If the account initial has no password, but was updated to have one if selection.password == nil && pendingPassword != "" { return true } - + // If the access bits or user name have been changed return pendingAccess.rawValue != selection.access.rawValue || selection.name != pendingName } |