krz/rune
an ios client for njalla
clone: git clone https://gitbay.org/krz/rune.git
v1.0.0: Rune/ViewModels/DomainViewModel.swift · raw
1import Combine
2import Foundation
3
4@MainActor
5final class DomainViewModel: ObservableObject {
6 @Published private(set) var domains: [Domain] = []
7 @Published private(set) var selectedDomain: Domain?
8 @Published private(set) var records: [DNSRecord] = []
9 @Published private(set) var isLoadingDomains = false
10 @Published private(set) var isLoadingDetail = false
11 @Published private(set) var isLoadingRecords = false
12 @Published private(set) var isSaving = false
13 @Published var errorMessage: String?
14
15 func reset() {
16 domains = []
17 selectedDomain = nil
18 records = []
19 isLoadingDomains = false
20 isLoadingDetail = false
21 isLoadingRecords = false
22 isSaving = false
23 errorMessage = nil
24 }
25
26 func loadDomains(client: NjallaClient) async {
27 isLoadingDomains = true
28 defer {
29 isLoadingDomains = false
30 }
31
32 do {
33 domains = try await client.listDomains().sorted {
34 $0.name.localizedCaseInsensitiveCompare($1.name) == .orderedAscending
35 }
36 errorMessage = nil
37 } catch is CancellationError {
38 return
39 } catch {
40 if (error as? URLError)?.code == .cancelled {
41 return
42 }
43 errorMessage = error.localizedDescription
44 }
45 }
46
47 func loadDomainDetail(named name: String, client: NjallaClient) async {
48 isLoadingDetail = true
49 defer {
50 isLoadingDetail = false
51 }
52
53 do {
54 let domain = try await client.getDomain(named: name)
55 selectedDomain = domain
56 if let index = domains.firstIndex(where: { $0.name == name }) {
57 domains[index] = domain
58 }
59 errorMessage = nil
60 } catch is CancellationError {
61 return
62 } catch {
63 if (error as? URLError)?.code == .cancelled {
64 return
65 }
66 errorMessage = error.localizedDescription
67 }
68 }
69
70 func updateDomain(named name: String, request: DomainUpdateRequest, client: NjallaClient) async throws {
71 isSaving = true
72 defer {
73 isSaving = false
74 }
75
76 let updated = try await client.editDomain(named: name, request: request)
77 selectedDomain = updated
78 if let index = domains.firstIndex(where: { $0.name == updated.name }) {
79 domains[index] = updated
80 }
81 errorMessage = nil
82 }
83
84 func loadRecords(for domain: String, client: NjallaClient) async {
85 isLoadingRecords = true
86 defer {
87 isLoadingRecords = false
88 }
89
90 do {
91 records = try await client.listRecords(for: domain).sorted {
92 ($0.name, $0.type, $0.id) < ($1.name, $1.type, $1.id)
93 }
94 errorMessage = nil
95 } catch is CancellationError {
96 return
97 } catch {
98 if (error as? URLError)?.code == .cancelled {
99 return
100 }
101 errorMessage = error.localizedDescription
102 }
103 }
104
105 func addRecord(for domain: String, draft: DNSRecordDraft, client: NjallaClient) async throws {
106 isSaving = true
107 defer {
108 isSaving = false
109 }
110
111 _ = try await client.addRecord(for: domain, draft: draft)
112 try await reloadRecords(for: domain, client: client)
113 errorMessage = nil
114 }
115
116 func editRecord(for domain: String, recordID: String, draft: DNSRecordDraft, client: NjallaClient) async throws {
117 isSaving = true
118 defer {
119 isSaving = false
120 }
121
122 _ = try await client.editRecord(for: domain, id: recordID, draft: draft)
123 try await reloadRecords(for: domain, client: client)
124 errorMessage = nil
125 }
126
127 func removeRecord(_ record: DNSRecord, client: NjallaClient) async throws {
128 isSaving = true
129 defer {
130 isSaving = false
131 }
132
133 try await client.removeRecord(record)
134 try await reloadRecords(for: record.domain, client: client)
135 errorMessage = nil
136 }
137
138 private func reloadRecords(for domain: String, client: NjallaClient) async throws {
139 records = try await client.listRecords(for: domain).sorted {
140 ($0.name, $0.type, $0.id) < ($1.name, $1.type, $1.id)
141 }
142 }
143}