yew_notifications/notification/
mod.rs

1mod component;
2pub mod component_factory;
3
4pub use component::{NotificationComponent, NotificationComponentProps};
5pub use component_factory::NotificationFactory;
6use time::{Duration, OffsetDateTime};
7use uuid::Uuid;
8use yew::{classes, Classes};
9
10use crate::Notifiable;
11
12/// Standard notification type.
13#[derive(Debug, Clone, PartialEq, Default)]
14pub enum NotificationType {
15    /// Represents some informative message for the user.
16    #[default]
17    Info,
18
19    /// Represents some warning.
20    Warn,
21
22    /// Represents some error message.
23    Error,
24
25    /// Custom notification type.
26    ///
27    /// You can use this option when you want to set the custom style of your notification
28    /// but don't want to write an entire custom component from scratch.
29    Custom(Classes),
30}
31
32impl From<&str> for NotificationType {
33    fn from(data: &str) -> Self {
34        match data {
35            "info" => Self::Info,
36            "warn" => Self::Warn,
37            "error" => Self::Error,
38            data => Self::Custom(data.to_owned().into()),
39        }
40    }
41}
42
43impl From<&NotificationType> for Classes {
44    fn from(notification_type: &NotificationType) -> Self {
45        match notification_type {
46            NotificationType::Info => classes!("info"),
47            NotificationType::Warn => classes!("warn"),
48            NotificationType::Error => classes!("error"),
49            NotificationType::Custom(classes) => classes.clone(),
50        }
51    }
52}
53
54/// Standard notification.
55#[derive(Debug, Clone, PartialEq)]
56pub struct Notification {
57    pub(crate) id: Uuid,
58    pub(crate) notification_type: NotificationType,
59    pub(crate) title: Option<String>,
60    pub(crate) text: String,
61
62    pub(crate) spawn_time: OffsetDateTime,
63    pub(crate) lifetime: Duration,
64    pub(crate) full_lifetime: Duration,
65    pub(crate) paused: bool,
66}
67
68impl Notification {
69    pub const NOTIFICATION_LIFETIME: Duration = Duration::seconds(3);
70
71    /// Creates a new standard notification from notification type, title, text, and lifetime duration.
72    pub fn new(
73        notification_type: NotificationType,
74        title: impl Into<String>,
75        text: impl Into<String>,
76        lifetime: Duration,
77    ) -> Self {
78        Self {
79            id: Uuid::new_v4(),
80            notification_type,
81            title: Some(title.into()),
82            text: text.into(),
83
84            spawn_time: OffsetDateTime::now_local().expect("Can not acquire local current time"),
85            lifetime,
86            full_lifetime: lifetime,
87            paused: false,
88        }
89    }
90
91    /// Creates a new standard notification from notification type and text.
92    ///
93    /// Title will be omitted. Notification lifetime is equal to the [`Self::NOTIFICATION_LIFETIME`].
94    pub fn from_description_and_type(notification_type: NotificationType, text: impl Into<String>) -> Self {
95        Self {
96            id: Uuid::new_v4(),
97            notification_type,
98            title: None,
99            text: text.into(),
100
101            spawn_time: OffsetDateTime::now_local().expect("Can not acquire local current time"),
102            lifetime: Self::NOTIFICATION_LIFETIME,
103            full_lifetime: Self::NOTIFICATION_LIFETIME,
104            paused: false,
105        }
106    }
107
108    /// Set the title for the notification.
109    pub fn with_title(self, new_title: impl Into<String>) -> Self {
110        let Notification {
111            id,
112            notification_type,
113            title: _,
114            text: description,
115
116            spawn_time,
117            lifetime,
118            full_lifetime,
119            paused,
120        } = self;
121
122        Self {
123            id,
124            notification_type,
125            title: Some(new_title.into()),
126            text: description,
127
128            spawn_time,
129            lifetime,
130            full_lifetime,
131            paused,
132        }
133    }
134
135    /// Set the type for the notification.
136    pub fn with_type(self, new_notification_type: NotificationType) -> Self {
137        let Notification {
138            id,
139            notification_type: _,
140            title,
141            text: description,
142
143            spawn_time,
144            lifetime,
145            full_lifetime,
146            paused,
147        } = self;
148
149        Self {
150            id,
151            notification_type: new_notification_type,
152            title,
153            text: description,
154
155            spawn_time,
156            lifetime,
157            full_lifetime,
158            paused,
159        }
160    }
161
162    /// Set the text for the notification.
163    pub fn with_text(self, new_text: impl Into<String>) -> Self {
164        let Notification {
165            id,
166            notification_type,
167            title,
168            text: _,
169
170            spawn_time,
171            lifetime,
172            full_lifetime,
173            paused,
174        } = self;
175
176        Self {
177            id,
178            notification_type,
179            title,
180            text: new_text.into(),
181
182            spawn_time,
183            lifetime,
184            full_lifetime,
185            paused,
186        }
187    }
188
189    /// Resets notification lifetime.
190    ///
191    /// It means that after this method invocation, the lifetime of the notification will be equal to the start value.
192    pub fn reset_lifetime(self) -> Self {
193        let Notification {
194            id,
195            notification_type,
196            title,
197            text,
198
199            spawn_time,
200            lifetime: _,
201            full_lifetime,
202            paused,
203        } = self;
204
205        Self {
206            id,
207            notification_type,
208            title,
209            text,
210
211            spawn_time,
212            lifetime: full_lifetime,
213            full_lifetime,
214            paused,
215        }
216    }
217}
218
219impl Notifiable for Notification {
220    fn id(&self) -> Uuid {
221        self.id
222    }
223
224    fn apply_tick(&mut self, time: Duration) {
225        self.lifetime = self.lifetime.checked_sub(time).unwrap_or_default();
226    }
227
228    fn is_alive(&self) -> bool {
229        self.lifetime != Duration::default()
230    }
231
232    fn mouse_in(&mut self) {
233        self.paused = true;
234    }
235
236    fn mouse_out(&mut self) {
237        self.paused = false;
238        self.lifetime = self.full_lifetime;
239    }
240
241    fn is_paused(&self) -> bool {
242        self.paused
243    }
244}