summaryrefslogtreecommitdiff
path: root/Rune/ViewModels/TokenViewModel.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-11 11:48:40 -0500
committerChristian Cleberg <[email protected]>2026-04-11 11:48:40 -0500
commitfcf864a15b70e4ecb5bd789b1db3116221c34394 (patch)
treef15315324b9f95286b6bf7392dd0ccaee210c2de /Rune/ViewModels/TokenViewModel.swift
parentcf587aa0573ac4f34e1effe70108a9eca82093ac (diff)
downloadrune-fcf864a15b70e4ecb5bd789b1db3116221c34394.tar.gz
rune-fcf864a15b70e4ecb5bd789b1db3116221c34394.tar.bz2
rune-fcf864a15b70e4ecb5bd789b1db3116221c34394.zip
add FUNDING.yml
Diffstat (limited to 'Rune/ViewModels/TokenViewModel.swift')
-rw-r--r--Rune/ViewModels/TokenViewModel.swift55
1 files changed, 40 insertions, 15 deletions
diff --git a/Rune/ViewModels/TokenViewModel.swift b/Rune/ViewModels/TokenViewModel.swift
index 40495b4..eab3185 100644
--- a/Rune/ViewModels/TokenViewModel.swift
+++ b/Rune/ViewModels/TokenViewModel.swift
@@ -6,16 +6,20 @@ 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?
+ @Published var listErrorMessage: String?
+ @Published var mutationErrorMessage: String?
func reset() {
tokens = []
isLoading = false
isSaving = false
- errorMessage = nil
+ listErrorMessage = nil
+ mutationErrorMessage = nil
}
func loadTokens(client: NjallaClient) async {
+ guard !isLoading else { return }
+
isLoading = true
defer {
isLoading = false
@@ -25,61 +29,76 @@ final class TokenViewModel: ObservableObject {
tokens = try await client.listTokens().sorted {
tokenLabel(for: $0).localizedCaseInsensitiveCompare(tokenLabel(for: $1)) == .orderedAscending
}
- errorMessage = nil
+ listErrorMessage = nil
} catch is CancellationError {
return
} catch {
if (error as? URLError)?.code == .cancelled {
return
}
- errorMessage = error.localizedDescription
+ listErrorMessage = error.userFacingMessage
}
}
func addToken(request: TokenCreateRequest, client: NjallaClient) async -> Bool {
+ guard !isSaving else { return false }
+
isSaving = true
- defer {
- isSaving = false
- }
+ mutationErrorMessage = nil
do {
try await client.addToken(request: request)
- tokens = try await client.listTokens()
- errorMessage = nil
+ isSaving = false
+ Task {
+ await loadTokens(client: client)
+ }
return true
} catch is CancellationError {
+ isSaving = false
return false
} catch {
if (error as? URLError)?.code == .cancelled {
+ isSaving = false
return false
}
- errorMessage = error.localizedDescription
+ isSaving = false
+ mutationErrorMessage = error.userFacingMessage
return false
}
}
func removeToken(_ token: APIToken, client: NjallaClient) async -> Bool {
+ guard !isSaving else { return false }
+
isSaving = true
- defer {
- isSaving = false
- }
+ mutationErrorMessage = nil
do {
try await client.removeToken(key: token.key)
tokens.removeAll { $0.key == token.key }
- errorMessage = nil
+ isSaving = false
+ Task {
+ await loadTokens(client: client)
+ }
return true
} catch is CancellationError {
+ isSaving = false
return false
} catch {
if (error as? URLError)?.code == .cancelled {
+ isSaving = false
return false
}
- errorMessage = error.localizedDescription
+ isSaving = false
+ mutationErrorMessage = error.userFacingMessage
return false
}
}
+ func dismissMutationError() {
+ mutationErrorMessage = nil
+ }
+
func tokenLabel(for token: APIToken) -> String {
let trimmedComment = token.comment?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
if !trimmedComment.isEmpty {
@@ -88,4 +107,10 @@ final class TokenViewModel: ObservableObject {
return String(token.key.prefix(8))
}
+
+ private func sortedTokens(_ tokens: [APIToken]) -> [APIToken] {
+ tokens.sorted {
+ tokenLabel(for: $0).localizedCaseInsensitiveCompare(tokenLabel(for: $1)) == .orderedAscending
+ }
+ }
}