summaryrefslogtreecommitdiff
path: root/Rune/Views/Domains/DomainEditView.swift
blob: 3f197e343d662a20fc28c733a98fe4703e213882 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import SwiftUI

struct DomainEditView: View {
    let domain: Domain
    @ObservedObject var viewModel: DomainViewModel
    let client: NjallaClient

    @Environment(\.dismiss) private var dismiss

    @State private var autorenew: Bool
    @State private var mailforwarding: Bool
    @State private var dnssec: Bool
    @State private var lock: Bool
    @State private var nameserversText: String
    @State private var localErrorMessage: String?

    init(domain: Domain, viewModel: DomainViewModel, client: NjallaClient) {
        self.domain = domain
        self.viewModel = viewModel
        self.client = client
        _autorenew = State(initialValue: domain.autorenew ?? false)
        _mailforwarding = State(initialValue: domain.mailforwarding ?? false)
        _dnssec = State(initialValue: domain.dnssec ?? false)
        _lock = State(initialValue: domain.lock ?? false)
        _nameserversText = State(initialValue: (domain.nameservers ?? []).joined(separator: "\n"))
    }

    var body: some View {
        Form {
            Section("Settings") {
                Toggle("Autorenew", isOn: $autorenew)
                Toggle("Mail Forwarding", isOn: $mailforwarding)
                Toggle("DNSSEC", isOn: $dnssec)
                Toggle("Registrar Lock", isOn: $lock)
            }

            Section {
                TextEditor(text: $nameserversText)
                    .frame(minHeight: 120)
            } header: {
                Text("Nameservers")
            } footer: {
                Text("Enter one nameserver per line. Leave blank to use Njalla defaults.")
            }

            Section {
                Button("Save") {
                    Task {
                        await save()
                    }
                }
                .disabled(viewModel.isSaving)
            }
        }
        .navigationTitle("Edit Domain")
        .navigationBarTitleDisplayMode(.inline)
        .alert("API Error", isPresented: localErrorBinding) {
            Button("OK", role: .cancel) {}
        } message: {
            Text(localErrorMessage ?? "")
        }
    }

    private func save() async {
        let request = DomainUpdateRequest(
            autorenew: autorenew,
            mailforwarding: mailforwarding,
            dnssec: dnssec,
            lock: lock,
            nameservers: nameserversText
                .split(whereSeparator: \.isNewline)
                .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
                .filter { !$0.isEmpty }
        )

        do {
            try await viewModel.updateDomain(named: domain.name, request: request, client: client)
            dismiss()
        } catch is CancellationError {
            return
        } catch {
            if (error as? URLError)?.code == .cancelled {
                return
            }
            localErrorMessage = error.localizedDescription
        }
    }

    private var localErrorBinding: Binding<Bool> {
        Binding(
            get: { localErrorMessage != nil },
            set: { newValue in
                if !newValue {
                    localErrorMessage = nil
                }
            }
        )
    }
}