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}