@@ -30,18 +30,52 @@ public extension DependencyValues {
3030 set { self [ ToastControllerDependencyKey . self] = newValue }
3131 }
3232
33- var toast : ( String , ToastType ) -> Void { toastController. toast }
33+ var toast : ( String , ToastType ) -> Void {
34+ return { content, type in
35+ toastController. toast ( content: content, type: type, namespace: nil )
36+ }
37+ }
38+
39+ var namespacedToast : ( String , ToastType , String ) -> Void {
40+ return {
41+ content, type, namespace in
42+ toastController. toast ( content: content, type: type, namespace: namespace)
43+ }
44+ }
3445}
3546
3647public class ToastController : ObservableObject {
3748 public struct Message : Identifiable , Equatable {
49+ public struct MessageButton : Equatable {
50+ public static func == ( lhs: Self , rhs: Self ) -> Bool {
51+ lhs. label == rhs. label
52+ }
53+
54+ public var label : Text
55+ public var action : ( ) -> Void
56+ public init ( label: Text , action: @escaping ( ) -> Void ) {
57+ self . label = label
58+ self . action = action
59+ }
60+ }
61+
62+ public var namespace : String ?
3863 public var id : UUID
3964 public var type : ToastType
4065 public var content : Text
41- public init ( id: UUID , type: ToastType , content: Text ) {
66+ public var buttons : [ MessageButton ]
67+ public init (
68+ id: UUID ,
69+ type: ToastType ,
70+ namespace: String ? = nil ,
71+ content: Text ,
72+ buttons: [ MessageButton ] = [ ]
73+ ) {
74+ self . namespace = namespace
4275 self . id = id
4376 self . type = type
4477 self . content = content
78+ self . buttons = buttons
4579 }
4680 }
4781
@@ -51,16 +85,35 @@ public class ToastController: ObservableObject {
5185 self . messages = messages
5286 }
5387
54- public func toast( content: String , type: ToastType ) {
88+ public func toast(
89+ content: String ,
90+ type: ToastType ,
91+ namespace: String ? = nil ,
92+ buttons: [ Message . MessageButton ] = [ ] ,
93+ duration: TimeInterval = 4
94+ ) {
5595 let id = UUID ( )
56- let message = Message ( id: id, type: type, content: Text ( content) )
96+ let message = Message (
97+ id: id,
98+ type: type,
99+ namespace: namespace,
100+ content: Text ( content) ,
101+ buttons: buttons. map { b in
102+ Message . MessageButton ( label: b. label, action: { [ weak self] in
103+ b. action ( )
104+ withAnimation ( . easeInOut( duration: 0.2 ) ) {
105+ self ? . messages. removeAll { $0. id == id }
106+ }
107+ } )
108+ }
109+ )
57110
58111 Task { @MainActor in
59112 withAnimation ( . easeInOut( duration: 0.2 ) ) {
60113 messages. append ( message)
61114 messages = messages. suffix ( 3 )
62115 }
63- try await Task . sleep ( nanoseconds: 4_000_000_000 )
116+ try await Task . sleep ( nanoseconds: UInt64 ( duration * 1_000_000_000 ) )
64117 withAnimation ( . easeInOut( duration: 0.2 ) ) {
65118 messages. removeAll { $0. id == id }
66119 }
@@ -85,7 +138,7 @@ public struct Toast {
85138 public enum Action : Equatable {
86139 case start
87140 case updateMessages( [ Message ] )
88- case toast( String , ToastType )
141+ case toast( String , ToastType , String ? )
89142 }
90143
91144 @Dependency ( \. toastController) var toastController
@@ -94,7 +147,7 @@ public struct Toast {
94147
95148 public init ( ) { }
96149
97- public var body : some Reducer < State , Action > {
150+ public var body : some ReducerOf < Self > {
98151 Reduce { state, action in
99152 switch action {
100153 case . start:
@@ -117,8 +170,8 @@ public struct Toast {
117170 case let . updateMessages( messages) :
118171 state. messages = messages
119172 return . none
120- case let . toast( content, type) :
121- toastController. toast ( content: content, type: type)
173+ case let . toast( content, type, namespace ) :
174+ toastController. toast ( content: content, type: type, namespace : namespace )
122175 return . none
123176 }
124177 }
0 commit comments