Consolidate snackbar state into a SnackbarOperation struct
This commit is contained in:
@ -62,7 +62,7 @@ struct InnerRootView: View {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
.snackBar(isShowing: $viewModel.showSnackbar, message: viewModel.snackbarMessage, undoAction: viewModel.snackBarUndoAction)
|
||||
.snackBar(isShowing: $viewModel.showSnackbar, operation: viewModel.snackbarOperation)
|
||||
// Schedule the dismissal every time we present the snackbar.
|
||||
.onChange(of: viewModel.showSnackbar) { newValue in
|
||||
if newValue {
|
||||
@ -93,15 +93,15 @@ struct InnerRootView: View {
|
||||
#if os(iOS)
|
||||
.onReceive(NSNotification.operationSuccessPublisher) { notification in
|
||||
if let message = notification.userInfo?["message"] as? String {
|
||||
viewModel.snackbarMessage = message
|
||||
viewModel.snackBarUndoAction = notification.userInfo?["undoAction"] as? (() -> Void)
|
||||
viewModel.snackbarOperation = SnackbarOperation(message: message,
|
||||
undoAction: notification.userInfo?["undoAction"] as? SnackbarUndoAction)
|
||||
viewModel.showSnackbar = true
|
||||
}
|
||||
}
|
||||
.onReceive(NSNotification.operationFailedPublisher) { notification in
|
||||
if let message = notification.userInfo?["message"] as? String {
|
||||
viewModel.showSnackbar = true
|
||||
viewModel.snackbarMessage = message
|
||||
viewModel.snackbarOperation = SnackbarOperation(message: message, undoAction: nil)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -17,10 +17,9 @@ public final class RootViewModel: ObservableObject {
|
||||
@Published public var showNewFeaturePrimer = false
|
||||
@AppStorage(UserDefaultKey.shouldShowNewFeaturePrimer.rawValue) var shouldShowNewFeaturePrimer = false
|
||||
|
||||
@Published var snackbarMessage: String?
|
||||
@Published var showMiniPlayer = false
|
||||
@Published var showSnackbar = false
|
||||
@Published var snackBarUndoAction: (() -> Void)?
|
||||
@Published var showMiniPlayer = true
|
||||
@Published var snackbarOperation: SnackbarOperation?
|
||||
|
||||
public init() {
|
||||
registerFonts()
|
||||
|
||||
@ -1,24 +1,32 @@
|
||||
import SwiftUI
|
||||
|
||||
public typealias SnackbarUndoAction = (() -> Void)
|
||||
|
||||
public struct SnackbarOperation {
|
||||
let message: String
|
||||
let undoAction: SnackbarUndoAction?
|
||||
|
||||
public init(message: String, undoAction: SnackbarUndoAction?) {
|
||||
self.message = message
|
||||
self.undoAction = undoAction
|
||||
}
|
||||
}
|
||||
|
||||
public struct Snackbar: View {
|
||||
@Binding var isShowing: Bool
|
||||
private let presentingView: AnyView
|
||||
private let text: Text
|
||||
|
||||
private let undoAction: (() -> Void)?
|
||||
private let operation: SnackbarOperation
|
||||
|
||||
@Environment(\.colorScheme) private var colorScheme: ColorScheme
|
||||
|
||||
init<PresentingView>(
|
||||
isShowing: Binding<Bool>,
|
||||
presentingView: PresentingView,
|
||||
text: Text,
|
||||
undoAction: (() -> Void)?
|
||||
operation: SnackbarOperation
|
||||
) where PresentingView: View {
|
||||
self._isShowing = isShowing
|
||||
self.presentingView = AnyView(presentingView)
|
||||
self.text = text
|
||||
self.undoAction = undoAction
|
||||
self.operation = operation
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
@ -27,13 +35,13 @@ public struct Snackbar: View {
|
||||
presentingView
|
||||
VStack {
|
||||
Spacer()
|
||||
if self.isShowing {
|
||||
if isShowing {
|
||||
HStack {
|
||||
self.text
|
||||
Text(operation.message)
|
||||
.font(.appCallout)
|
||||
.foregroundColor(self.colorScheme == .light ? .white : .appTextDefault)
|
||||
Spacer()
|
||||
if let undoAction = undoAction {
|
||||
if let undoAction = operation.undoAction {
|
||||
Button("Undo", action: undoAction)
|
||||
.font(.system(size: 16, weight: .bold))
|
||||
}
|
||||
@ -53,7 +61,11 @@ public struct Snackbar: View {
|
||||
}
|
||||
|
||||
public extension View {
|
||||
func snackBar(isShowing: Binding<Bool>, message: String?, undoAction: (() -> Void)?) -> some View {
|
||||
Snackbar(isShowing: isShowing, presentingView: self, text: Text(message ?? ""), undoAction: undoAction)
|
||||
func snackBar(isShowing: Binding<Bool>, operation: SnackbarOperation?) -> some View {
|
||||
if let operation = operation {
|
||||
return AnyView(Snackbar(isShowing: isShowing, presentingView: self, operation: operation))
|
||||
} else {
|
||||
return AnyView(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user