toast.rs
| 1 | use std::time::Duration; |
| 2 | |
| 3 | use leptos::prelude::*; |
| 4 | use wasm_bindgen_futures::spawn_local; |
| 5 | |
| 6 | /// Context type: read/write access to the current toast message. |
| 7 | #[derive(Copy, Clone)] |
| 8 | pub struct ToastMsg(pub RwSignal<Option<String>>); |
| 9 | |
| 10 | pub fn provide_toast() -> ToastMsg { |
| 11 | let toast = RwSignal::new(Option::<String>::None); |
| 12 | let t = ToastMsg(toast); |
| 13 | provide_context(t); |
| 14 | t |
| 15 | } |
| 16 | |
| 17 | /// Show a toast that disappears after ~3 seconds. |
| 18 | pub fn show(toast: ToastMsg, msg: impl Into<String>) { |
| 19 | let msg = msg.into(); |
| 20 | toast.0.set(Some(msg.clone())); |
| 21 | spawn_local(async move { |
| 22 | gloo_timers::future::sleep(Duration::from_secs(3)).await; |
| 23 | if toast.0.get().as_deref() == Some(msg.as_str()) { |
| 24 | toast.0.set(None); |
| 25 | } |
| 26 | }); |
| 27 | } |
| 28 | |
| 29 | #[component] |
| 30 | pub fn ToastView(toast: ToastMsg) -> impl IntoView { |
| 31 | view! { |
| 32 | <Show when=move || toast.0.get().is_some()> |
| 33 | <div class="toast">{move || toast.0.get().unwrap_or_default()}</div> |
| 34 | </Show> |
| 35 | } |
| 36 | } |
| 37 |