use std::time::Duration; use leptos::prelude::*; use wasm_bindgen_futures::spawn_local; /// Context type: read/write access to the current toast. /// /// The state is `(message, is_error)`: errors get their own styling so they /// do not read like routine confirmations. #[derive(Copy, Clone)] pub struct ToastMsg(pub RwSignal>); pub fn provide_toast() -> ToastMsg { let toast = RwSignal::new(Option::<(String, bool)>::None); let t = ToastMsg(toast); provide_context(t); t } /// Show a toast that disappears after ~3 seconds. pub fn show(toast: ToastMsg, msg: impl Into) { set(toast, msg.into(), false); } /// Show a failure toast (danger styling). pub fn show_error(toast: ToastMsg, msg: impl Into) { set(toast, msg.into(), true); } fn set(toast: ToastMsg, msg: String, is_error: bool) { toast.0.set(Some((msg.clone(), is_error))); spawn_local(async move { gloo_timers::future::sleep(Duration::from_secs(3)).await; if toast.0.get_untracked().as_ref().map(|(m, _)| m.as_str()) == Some(msg.as_str()) { toast.0.set(None); } }); } #[component] pub fn ToastView(toast: ToastMsg) -> impl IntoView { view! {
{move || toast.0.get().map(|(m, _)| m).unwrap_or_default()}
} }