Skip to main content

bt_toast/
lib.rs

1use dioxus::prelude::*;
2
3///Default Waiting Message if None is received at initialization
4const DEFAULT_WAITING_MSG: &str = "Please wait while your request is processed...";
5
6///The ToastMgr struct is used to manage toast notifications in a Dioxus application using Bootstrap. It has four properties:
7///    show_toast: A boolean indicating whether a toast notification should be shown.
8///    toast_message: A string containing the message to be displayed in the toast notification.
9///    toast_type: A character indicating the type of toast notification (I for info, S for success, W for waiting, C for caution/warning, E for error).
10///    wait_msg: A string containing the default waiting message.
11#[derive(Clone, PartialEq, Debug)]
12pub struct ToastMgr{
13    show_toast: bool,
14    toast_message: String,
15    toast_type: char,
16    wait_msg: String,
17}
18
19impl ToastMgr {
20    ///Creates a new instance of ToastMgr with an optional default waiting message. 
21    /// If no default waiting message is provided, it defaults to "Please wait while your request is processed...".
22    pub fn new(default_waiting_msg: Option<String>) -> Self{
23        ToastMgr{
24            show_toast: false,
25            toast_message: String::new(),
26            toast_type: 'N', //None
27            wait_msg: default_waiting_msg.unwrap_or(DEFAULT_WAITING_MSG.to_owned()),
28        }
29    }
30
31    ///Displays an info toast notification with the specified message.
32    pub fn show_info(&mut self, msg: String){
33        self.toast_message = msg;
34        self.toast_type = 'I'; //Info
35        self.show_toast = true;
36    }
37
38    ///Displays a success toast notification with the specified message.
39    pub fn show_success(&mut self, msg: String){
40        self.toast_message = msg;
41        self.toast_type = 'S'; //Success
42        self.show_toast = true;
43    }
44
45    ///Displays a warning toast notification with the specified message.
46    pub fn show_warning(&mut self, msg: String){
47        self.toast_message = msg;
48        self.toast_type = 'C'; //Caution / WARNING
49        self.show_toast = true;
50    }        
51
52    ///Displays an error toast notification with the specified message.
53    pub fn show_error(&mut self, msg: String){
54        self.toast_message = msg;
55        self.toast_type = 'E'; //Error
56        self.show_toast = true;
57    }    
58    
59    ///Displays a waiting toast notification with the predefined waiting message.
60    pub fn waiting_toast(&mut self){
61        self.toast_type = 'W'; //Waiting
62        self.show_toast = true;
63    }
64
65    ///Turns off any currently displayed toast notifications.
66    pub fn turn_off(&mut self){
67        if self.show_toast {
68            self.show_toast = false;
69        }
70        if self.toast_type != 'N'{
71            self.toast_type = 'N';
72        }
73    }
74
75    ///Returns a boolean indicating whether a toast notification is scheduled to be shown.
76    pub fn will_show(&self) -> bool{
77        self.show_toast && self.toast_type != 'N'
78    } 
79}
80
81
82#[component]
83pub fn Toast2(mut signal_manager: Signal<ToastMgr>) -> Element {
84    if !signal_manager.read().show_toast || signal_manager.read().toast_type == 'N'{
85        return rsx! {};
86    }
87
88    match signal_manager.read().toast_type {
89        'I' => {
90            return rsx! {
91                div { class: "toast-container position-fixed bottom-0 end-0 p-3",
92                    div {
93                        class: "toast align-items-center text-bg-info border-0 show",
94                        role: "alert",
95                        "aria-live": "assertive",
96                        "aria-atomic": "true",
97                        style: "min-width: 250px;",
98                        div { class: "d-flex",
99                            div { class: "toast-body", "{signal_manager.read().toast_message}" }
100                            button {
101                                r#type: "button",
102                                class: "btn-close btn-close-white me-2 m-auto",
103                                "aria-label": "Close",
104                                onclick: move |_| signal_manager.write().show_toast = false,
105                            }
106                        }
107                    }
108                }
109            }
110        },        
111        'S' => {
112            return rsx! {
113                div { class: "toast-container position-fixed bottom-0 end-0 p-3",
114                    div {
115                        class: "toast align-items-center text-bg-success border-0 show",
116                        role: "alert",
117                        "aria-live": "assertive",
118                        "aria-atomic": "true",
119                        style: "min-width: 250px;",
120                        div { class: "d-flex",
121                            div { class: "toast-body", "{signal_manager.read().toast_message}" }
122                            button {
123                                r#type: "button",
124                                class: "btn-close btn-close-white me-2 m-auto",
125                                "aria-label": "Close",
126                                onclick: move |_| signal_manager.write().show_toast = false,
127                            }
128                        }
129                    }
130                }
131            }
132        },
133        'W' => {
134            return rsx! {
135                div { class: "toast-container  position-fixed  bottom-0 end-0 p-3",
136                    div {
137                        class: "toast align-items-center text-bg-primary  border-0 show",
138                        role: "alert",
139                        "aria-live": "assertive",
140                        "aria-atomic": "true",
141                        style: "min-width: 250px;",
142                        div { class: "d-flex",
143                            div { class: "toast-body",
144                                div {
145                                    class: "spinner-border spinner-border-sm me-2",
146                                    role: "status",
147                                    "aria-hidden": "true",
148                                }
149                                "{signal_manager.read().wait_msg}"
150                            }
151                            button {
152                                r#type: "button",
153                                class: "btn-close btn-close-white me-2 m-auto",
154                                "aria-label": "Close",
155                                onclick: move |_| signal_manager.write().show_toast = false,
156                            }
157                        }
158                    }
159                }
160            }            
161        },
162        'C' => {
163            return rsx! {
164                div { class: "toast-container position-fixed bottom-0 end-0 p-3",
165                    div {
166                        class: "toast align-items-center text-bg-warning border-0 show",
167                        role: "alert",
168                        "aria-live": "assertive",
169                        "aria-atomic": "true",
170                        style: "min-width: 250px;",
171                        div { class: "d-flex",
172                            div { class: "toast-body", "{signal_manager.read().toast_message}" }
173                            button {
174                                r#type: "button",
175                                class: "btn-close btn-close-white me-2 m-auto",
176                                "aria-label": "Close",
177                                onclick: move |_| signal_manager.write().show_toast = false,
178                            }
179                        }
180                    }
181                }
182            }            
183        },        
184        'E' => {
185            return rsx! {
186                div { class: "toast-container position-fixed bottom-0 end-0 p-3",
187                    div {
188                        class: "toast align-items-center text-bg-danger border-0 show",
189                        role: "alert",
190                        "aria-live": "assertive",
191                        "aria-atomic": "true",
192                        style: "min-width: 250px;",
193                        div { class: "d-flex",
194                            div { class: "toast-body", "{signal_manager.read().toast_message}" }
195                            button {
196                                r#type: "button",
197                                class: "btn-close btn-close-white me-2 m-auto",
198                                "aria-label": "Close",
199                                onclick: move |_| signal_manager.write().show_toast = false,
200                            }
201                        }
202                    }
203                }
204            }            
205        },
206        _ => return rsx! {},
207    };
208}