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}