This commit is contained in:
Daniel Arantes Loverde
2026-07-07 15:11:31 -03:00
parent 8b9ebdcb44
commit e51c99973f
293 changed files with 457 additions and 4919 deletions

View File

@@ -0,0 +1,94 @@
import Foundation
import SwiftUI
extension Notification.Name {
static let snackbarDidChange = Notification.Name("snackbarDidChange")
}
@MainActor
final class SnackbarCenter: ObservableObject {
static let shared = SnackbarCenter()
@Published var current: SnackbarMessage?
private var dismissTask: Task<Void, Never>?
func show(
title: String,
style: SnackbarStyle = .info,
icon: String? = nil,
duration: TimeInterval = 3.5,
isPersistent: Bool = false,
action: (() -> Void)? = nil
) {
dismissTask?.cancel()
dismissTask = nil
current = SnackbarMessage(
title: title,
style: style,
iconSystemName: icon,
duration: duration,
isPersistent: isPersistent,
action: action
)
guard isPersistent == false else { return }
dismissTask = Task { [weak self] in
let nanos = UInt64(max(0.2, duration) * 1_000_000_000)
try? await Task.sleep(nanoseconds: nanos)
guard !Task.isCancelled else { return }
self?.dismiss(animated: true)
}
}
func handleTap() {
guard current?.isPersistent != true else { return }
let action = current?.action
dismiss(animated: true)
action?()
}
func dismiss(animated: Bool) {
dismissTask?.cancel()
dismissTask = nil
if animated {
withAnimation(.spring(response: 0.3, dampingFraction: 0.9)) {
current = nil
}
} else {
current = nil
}
}
func dismissPersistent() {
guard current?.isPersistent == true else { return }
dismiss(animated: true)
}
}
enum SnackbarStyle: Sendable {
case info
case success
case warning
case error
var backgroundColor: Color {
switch self {
case .info: return Color(hex: "#3B93F7")
case .success: return Color(hex: "#2E7D32")
case .warning: return Color(hex: "#C77700")
case .error: return Color(hex: "#C62828")
}
}
}
struct SnackbarMessage: Identifiable {
let id = UUID()
let title: String
let style: SnackbarStyle
let iconSystemName: String?
let duration: TimeInterval
let isPersistent: Bool
let action: (() -> Void)?
}