krz/rune

an ios client for njalla

clone: git clone https://gitbay.org/krz/rune.git

v1.0.0: Rune/ViewModels/TokenViewModel.swift · raw

 1import Combine
 2import Foundation
 3
 4@MainActor
 5final class TokenViewModel: ObservableObject {
 6    @Published private(set) var tokens: [APIToken] = []
 7    @Published private(set) var isLoading = false
 8    @Published private(set) var isSaving = false
 9    @Published var errorMessage: String?
10
11    func reset() {
12        tokens = []
13        isLoading = false
14        isSaving = false
15        errorMessage = nil
16    }
17
18    func loadTokens(client: NjallaClient) async {
19        isLoading = true
20        defer {
21            isLoading = false
22        }
23
24        do {
25            tokens = try await client.listTokens().sorted {
26                tokenLabel(for: $0).localizedCaseInsensitiveCompare(tokenLabel(for: $1)) == .orderedAscending
27            }
28            errorMessage = nil
29        } catch is CancellationError {
30            return
31        } catch {
32            if (error as? URLError)?.code == .cancelled {
33                return
34            }
35            errorMessage = error.localizedDescription
36        }
37    }
38
39    func addToken(request: TokenCreateRequest, client: NjallaClient) async -> Bool {
40        isSaving = true
41        defer {
42            isSaving = false
43        }
44
45        do {
46            try await client.addToken(request: request)
47            tokens = try await client.listTokens()
48            errorMessage = nil
49            return true
50        } catch is CancellationError {
51            return false
52        } catch {
53            if (error as? URLError)?.code == .cancelled {
54                return false
55            }
56            errorMessage = error.localizedDescription
57            return false
58        }
59    }
60
61    func removeToken(_ token: APIToken, client: NjallaClient) async -> Bool {
62        isSaving = true
63        defer {
64            isSaving = false
65        }
66
67        do {
68            try await client.removeToken(key: token.key)
69            tokens.removeAll { $0.key == token.key }
70            errorMessage = nil
71            return true
72        } catch is CancellationError {
73            return false
74        } catch {
75            if (error as? URLError)?.code == .cancelled {
76                return false
77            }
78            errorMessage = error.localizedDescription
79            return false
80        }
81    }
82
83    func tokenLabel(for token: APIToken) -> String {
84        let trimmedComment = token.comment?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
85        if !trimmedComment.isEmpty {
86            return trimmedComment
87        }
88
89        return String(token.key.prefix(8))
90    }
91}