Impressia/Vernissage/Widgets/ActionButton.swift

57 lines
1.4 KiB
Swift
Raw Normal View History

//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
2023-03-28 10:35:38 +02:00
// Licensed under the Apache License 2.0.
//
import SwiftUI
2023-01-22 17:41:11 +01:00
struct ActionButton<Label>: View where Label: View {
2023-02-18 14:17:18 +01:00
@State public var showLoader: Bool
@State private var isDuringAction = false
private let action: () async -> Void
private let label: () -> Label
2023-02-18 14:17:18 +01:00
public init(showLoader: Bool = true, action: @escaping () async -> Void, @ViewBuilder label: @escaping () -> Label) {
self.action = action
self.label = label
2023-02-18 14:17:18 +01:00
self.showLoader = showLoader
}
var body: some View {
Button {
Task {
2023-02-19 12:49:44 +01:00
HapticService.shared.fireHaptic(of: .buttonPress)
withAnimation {
self.isDuringAction = true
}
await action()
2023-02-18 13:43:22 +01:00
withAnimation {
self.isDuringAction = false
}
}
} label: {
2023-02-18 14:17:18 +01:00
if self.showLoader {
withLoader()
} else {
label()
}
}.disabled(isDuringAction)
}
2023-02-18 14:17:18 +01:00
@ViewBuilder
private func withLoader() -> some View {
if isDuringAction {
LoadingIndicator(isVisible: .constant(true))
.transition(.opacity)
} else {
label()
.transition(.opacity)
}
}
}