use crate::{class::Class, format_class};
use dioxus::prelude::*;
use std::{borrow::Cow, time::Duration};
use zino_core::error::Error;
pub fn Message<'a>(cx: Scope<'a, MessageProps<'a>>) -> Element {
let Some(value) = cx.props.future.value() else {
return None;
};
let close_message = use_state(cx, || false);
if *close_message.get() {
return None;
}
let duration = cx.props.duration;
cx.spawn({
to_owned![close_message];
async move {
tokio::time::sleep(Duration::from_millis(duration)).await;
close_message.set(true);
}
});
let class = format_class!(cx, "message");
let close_class = format_class!(cx, close_class, "delete");
let title = cx.props.title.as_deref().unwrap_or_default();
match value {
Ok(()) => {
render! {
div {
class: "{class} is-success",
if !title.is_empty() {
rsx!(div {
class: "message-header",
span { "{title}" }
button {
class: "{close_class}",
onclick: move |event| {
if let Some(handler) = cx.props.on_close.as_ref() {
handler.call(event);
}
close_message.set(true);
}
}
})
}
div {
class: "message-body",
"{cx.props.success}"
}
}
}
}
Err(err) => {
render! {
div {
class: "{class} is-danger",
if !title.is_empty() {
rsx!(div {
class: "message-header",
span { "{title}" }
button {
class: "{close_class}",
onclick: move |event| {
if let Some(handler) = cx.props.on_close.as_ref() {
handler.call(event);
}
close_message.set(true);
}
}
})
}
div {
class: "message-body",
span { "{cx.props.error}" }
span { "{err}" }
}
}
}
}
}
}
#[derive(Props)]
pub struct MessageProps<'a> {
#[props(into)]
pub class: Option<Class<'a>>,
#[props(into)]
pub close_class: Option<Class<'a>>,
pub future: &'a UseFuture<Result<(), Error>>,
pub on_close: Option<EventHandler<'a, MouseEvent>>,
#[props(into)]
pub title: Option<Cow<'a, str>>,
#[props(into)]
pub success: Cow<'a, str>,
#[props(into)]
pub error: Cow<'a, str>,
#[props(default = 3000)]
pub duration: u64,
}