krz/rune
an ios client for njalla
clone: git clone https://gitbay.org/krz/rune.git
v1.0.0: Rune/Views/Domains/DomainEditView.swift · raw
1import SwiftUI
2
3struct DomainEditView: View {
4 let domain: Domain
5 @ObservedObject var viewModel: DomainViewModel
6 let client: NjallaClient
7
8 @Environment(\.dismiss) private var dismiss
9
10 @State private var autorenew: Bool
11 @State private var mailforwarding: Bool
12 @State private var dnssec: Bool
13 @State private var lock: Bool
14 @State private var nameserversText: String
15 @State private var localErrorMessage: String?
16
17 init(domain: Domain, viewModel: DomainViewModel, client: NjallaClient) {
18 self.domain = domain
19 self.viewModel = viewModel
20 self.client = client
21 _autorenew = State(initialValue: domain.autorenew ?? false)
22 _mailforwarding = State(initialValue: domain.mailforwarding ?? false)
23 _dnssec = State(initialValue: domain.dnssec ?? false)
24 _lock = State(initialValue: domain.lock ?? false)
25 _nameserversText = State(initialValue: (domain.nameservers ?? []).joined(separator: "\n"))
26 }
27
28 var body: some View {
29 Form {
30 Section("Settings") {
31 Toggle("Autorenew", isOn: $autorenew)
32 Toggle("Mail Forwarding", isOn: $mailforwarding)
33 Toggle("DNSSEC", isOn: $dnssec)
34 Toggle("Registrar Lock", isOn: $lock)
35 }
36
37 Section {
38 TextEditor(text: $nameserversText)
39 .frame(minHeight: 120)
40 } header: {
41 Text("Nameservers")
42 } footer: {
43 Text("Enter one nameserver per line. Leave blank to use Njalla defaults.")
44 }
45
46 Section {
47 Button("Save") {
48 Task {
49 await save()
50 }
51 }
52 .disabled(viewModel.isSaving)
53 }
54 }
55 .navigationTitle("Edit Domain")
56 .navigationBarTitleDisplayMode(.inline)
57 .alert("API Error", isPresented: localErrorBinding) {
58 Button("OK", role: .cancel) {}
59 } message: {
60 Text(localErrorMessage ?? "")
61 }
62 }
63
64 private func save() async {
65 let request = DomainUpdateRequest(
66 autorenew: autorenew,
67 mailforwarding: mailforwarding,
68 dnssec: dnssec,
69 lock: lock,
70 nameservers: nameserversText
71 .split(whereSeparator: \.isNewline)
72 .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
73 .filter { !$0.isEmpty }
74 )
75
76 do {
77 try await viewModel.updateDomain(named: domain.name, request: request, client: client)
78 dismiss()
79 } catch is CancellationError {
80 return
81 } catch {
82 if (error as? URLError)?.code == .cancelled {
83 return
84 }
85 localErrorMessage = error.localizedDescription
86 }
87 }
88
89 private var localErrorBinding: Binding<Bool> {
90 Binding(
91 get: { localErrorMessage != nil },
92 set: { newValue in
93 if !newValue {
94 localErrorMessage = nil
95 }
96 }
97 )
98 }
99}