Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions Sources/ButtonKit/Button.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,23 +194,47 @@ public struct AsyncButton<P: TaskProgress, S: View>: View {
guard !(state?.isLoading ?? false), !isDisabled else {
return
}
state = .started(Task {
// Initialize progress
progress.reset()
await progress.started()
let completion: AsyncButtonCompletion
do {
try await action(progress)
completion = .completed
} catch {
latestError = error
numberOfFailures += 1
completion = .errored(error: error, numberOfFailures: numberOfFailures)
#if swift(>=6.2)
if #available(iOS 26.0, tvOS 26.0, watchOS 26.0, macOS 26.0, visionOS 26.0, *) {
var immediateTaskEnded = false
let immediateTask = Task.immediate {
let completion = await performAsyncAction()
state = .ended(completion)
immediateTaskEnded = true
}
if !immediateTaskEnded {
state = .started(immediateTask)
}
// Reset progress
await progress.ended()
} else {
state = .started(Task {
let completion = await performAsyncAction()
state = .ended(completion)
})
}
#else
state = .started(Task {
let completion = await performAsyncAction()
state = .ended(completion)
})
#endif
}

private func performAsyncAction() async -> AsyncButtonCompletion {
// Initialize progress
progress.reset()
await progress.started()
let completion: AsyncButtonCompletion
do {
try await action(progress)
completion = .completed
} catch {
latestError = error
numberOfFailures += 1
completion = .errored(error: error, numberOfFailures: numberOfFailures)
}
// Reset progress
await progress.ended()
return completion
}

private func cancel() {
Expand Down