From cf587aa0573ac4f34e1effe70108a9eca82093ac Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Tue, 24 Mar 2026 21:48:23 -0500 Subject: v1.0 --- Rune/ViewModels/TokenViewModel.swift | 91 ++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 Rune/ViewModels/TokenViewModel.swift (limited to 'Rune/ViewModels/TokenViewModel.swift') 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)) + } +} -- cgit v1.2.3