diff options
| author | Christian Cleberg <[email protected]> | 2026-04-11 11:48:40 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-11 11:48:40 -0500 |
| commit | fcf864a15b70e4ecb5bd789b1db3116221c34394 (patch) | |
| tree | f15315324b9f95286b6bf7392dd0ccaee210c2de /Rune/Views/Domains/ForwardAddView.swift | |
| parent | cf587aa0573ac4f34e1effe70108a9eca82093ac (diff) | |
| download | rune-fcf864a15b70e4ecb5bd789b1db3116221c34394.tar.gz rune-fcf864a15b70e4ecb5bd789b1db3116221c34394.tar.bz2 rune-fcf864a15b70e4ecb5bd789b1db3116221c34394.zip | |
add FUNDING.yml
Diffstat (limited to 'Rune/Views/Domains/ForwardAddView.swift')
| -rw-r--r-- | Rune/Views/Domains/ForwardAddView.swift | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/Rune/Views/Domains/ForwardAddView.swift b/Rune/Views/Domains/ForwardAddView.swift new file mode 100644 index 0000000..222ab86 --- /dev/null +++ b/Rune/Views/Domains/ForwardAddView.swift @@ -0,0 +1,111 @@ +import SwiftUI + +struct ForwardAddView: View { + let domainName: String + @ObservedObject var viewModel: DomainViewModel + let client: NjallaClient + + @Environment(\.dismiss) private var dismiss + + @State private var from = "" + @State private var to = "" + + var body: some View { + Form { + Section { + TextField("From", text: $from) + .textInputAutocapitalization(.never) + .autocorrectionDisabled() + TextField("To", text: $to) + .textInputAutocapitalization(.never) + .keyboardType(.emailAddress) + .autocorrectionDisabled() + } header: { + Text("Forward") + } footer: { + Text("Creates \(trimmedFrom)@\(domainName) -> \(trimmedTo)") + } + + Section { + Button("Save") { + Task { + await save() + } + } + .disabled(viewModel.isSaving || !canSubmit) + } + } + .navigationTitle("Add Forward") + .navigationBarTitleDisplayMode(.inline) + .overlay { + if viewModel.isSaving { + ProgressView() + .controlSize(.large) + } + } + .toolbar { + ToolbarItem(placement: .cancellationAction) { + Button("Cancel", role: .cancel) { + dismiss() + } + .disabled(viewModel.isSaving) + } + } + .interactiveDismissDisabled(viewModel.isSaving) + .alert("Request Failed", isPresented: mutationErrorBinding) { + Button("OK", role: .cancel) {} + } message: { + Text(viewModel.mutationErrorMessage ?? "") + } + } + + private var trimmedFrom: String { + from.trimmingCharacters(in: .whitespacesAndNewlines) + } + + private var trimmedTo: String { + to.trimmingCharacters(in: .whitespacesAndNewlines) + } + + private var canSubmit: Bool { + !trimmedFrom.isEmpty && !trimmedTo.isEmpty + } + + private func save() async { + guard !viewModel.isSaving, canSubmit else { + return + } + + let forward = EmailForward(domain: domainName, from: trimmedFrom, to: trimmedTo) + + debugLog("Creating forward \(forward.from)@\(forward.domain) -> \(forward.to)") + do { + try await viewModel.addForward(forward, client: client) + debugLog("Created forward \(forward.from)@\(forward.domain) -> \(forward.to)") + dismiss() + } catch is CancellationError { + debugLog("Create cancelled for \(forward.from)@\(forward.domain) -> \(forward.to)") + return + } catch { + debugLog("Create failed for \(forward.from)@\(forward.domain) -> \(forward.to): \(error.localizedDescription)") + return + } + } + + private var mutationErrorBinding: Binding<Bool> { + Binding( + get: { viewModel.mutationErrorMessage != nil }, + set: { newValue in + if !newValue { + viewModel.dismissMutationError() + } + } + ) + } + + private func debugLog(_ message: String) { + #if DEBUG + debugPrint("[ForwardAddView]", message) + #endif + } +} |
