yew_notifications/notification/
mod.rs1mod 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#[derive(Debug, Clone, PartialEq, Default)]
14pub enum NotificationType {
15 #[default]
17 Info,
18
19 Warn,
21
22 Error,
24
25 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#[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 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 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 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 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 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 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}