Not has address
This commit is contained in:
99
pedi-foods/Sources/PediFoods/State/SnackbarCenter.swift
Normal file
99
pedi-foods/Sources/PediFoods/State/SnackbarCenter.swift
Normal file
@@ -0,0 +1,99 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
#if os(Android)
|
||||
@MainActor
|
||||
final class SnackbarCenter {
|
||||
static let shared = SnackbarCenter()
|
||||
var current: SnackbarMessage?
|
||||
|
||||
func show(
|
||||
title: String,
|
||||
style: SnackbarStyle = .info,
|
||||
icon: String? = nil,
|
||||
duration: TimeInterval = 3.5,
|
||||
action: (() -> Void)? = nil
|
||||
) {
|
||||
action?()
|
||||
}
|
||||
|
||||
func handleTap() {}
|
||||
func dismiss(animated: Bool) {}
|
||||
}
|
||||
#else
|
||||
@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,
|
||||
action: (() -> Void)? = nil
|
||||
) {
|
||||
dismissTask?.cancel()
|
||||
current = SnackbarMessage(
|
||||
title: title,
|
||||
style: style,
|
||||
iconSystemName: icon,
|
||||
duration: duration,
|
||||
action: action
|
||||
)
|
||||
|
||||
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() {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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 action: (() -> Void)?
|
||||
}
|
||||
Reference in New Issue
Block a user