summaryrefslogtreecommitdiff
path: root/Rune/ViewModels/TokenViewModel.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-03-24 21:48:23 -0500
committerChristian Cleberg <[email protected]>2026-03-24 21:48:23 -0500
commitcf587aa0573ac4f34e1effe70108a9eca82093ac (patch)
tree833e6f4961522e35b08af01b5f012983f8e34678 /Rune/ViewModels/TokenViewModel.swift
downloadrune-1.0.0.tar.gz
rune-1.0.0.tar.bz2
rune-1.0.0.zip
v1.0v1.0.0
Diffstat (limited to 'Rune/ViewModels/TokenViewModel.swift')
-rw-r--r--Rune/ViewModels/TokenViewModel.swift91
1 files changed, 91 insertions, 0 deletions
diff --git a/Rune/ViewModels/TokenViewModel.swift b/Rune/ViewModels/TokenViewModel.swift
new file mode 100644
index 0000000..40495b4
--- /dev/null
+++ b/Rune/ViewModels/TokenViewModel.swift
@@ -0,0 +1,91 @@
+import Combine
+import Foundation
+
+@MainActor
+final class TokenViewModel: ObservableObject {
+ @Published private(set) var tokens: [APIToken] = []
+ @Published private(set) var isLoading = false
+ @Published private(set) var isSaving = false
+ @Published var errorMessage: String?
+
+ func reset() {
+ tokens = []
+ isLoading = false
+ isSaving = false
+ errorMessage = nil
+ }
+
+ func loadTokens(client: NjallaClient) async {
+ isLoading = true
+ defer {
+ isLoading = false
+ }
+
+ do {
+ tokens = try await client.listTokens().sorted {
+ tokenLabel(for: $0).localizedCaseInsensitiveCompare(tokenLabel(for: $1)) == .orderedAscending
+ }
+ errorMessage = nil
+ } catch is CancellationError {
+ return
+ } catch {
+ if (error as? URLError)?.code == .cancelled {
+ return
+ }
+ errorMessage = error.localizedDescription
+ }
+ }
+
+ func addToken(request: TokenCreateRequest, client: NjallaClient) async -> Bool {
+ isSaving = true
+ defer {
+ isSaving = false
+ }
+
+ do {
+ try await client.addToken(request: request)
+ tokens = try await client.listTokens()
+ errorMessage = nil
+ return true
+ } catch is CancellationError {
+ return false
+ } catch {
+ if (error as? URLError)?.code == .cancelled {
+ return false
+ }
+ errorMessage = error.localizedDescription
+ return false
+ }
+ }
+
+ func removeToken(_ token: APIToken, client: NjallaClient) async -> Bool {
+ isSaving = true
+ defer {
+ isSaving = false
+ }
+
+ do {
+ try await client.removeToken(key: token.key)
+ tokens.removeAll { $0.key == token.key }
+ errorMessage = nil
+ return true
+ } catch is CancellationError {
+ return false
+ } catch {
+ if (error as? URLError)?.code == .cancelled {
+ return false
+ }
+ errorMessage = error.localizedDescription
+ return false
+ }
+ }
+
+ func tokenLabel(for token: APIToken) -> String {
+ let trimmedComment = token.comment?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
+ if !trimmedComment.isEmpty {
+ return trimmedComment
+ }
+
+ return String(token.key.prefix(8))
+ }
+}