106 lines
2.7 KiB
Rust
106 lines
2.7 KiB
Rust
use gloo_timers::future::TimeoutFuture;
|
|
use log::debug;
|
|
use sycamore::{futures::spawn_local_scoped, prelude::*};
|
|
use wasm_bindgen_futures::spawn_local;
|
|
|
|
const MESSAGE_TIME: u32 = 5000;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Default)]
|
|
pub struct Message {
|
|
id: usize,
|
|
title: String,
|
|
text: String,
|
|
}
|
|
|
|
impl Message {
|
|
pub fn new(title: String, text: String) -> Self {
|
|
Self { id: 0, title, text }
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Default)]
|
|
pub struct Messenger {
|
|
counter: RcSignal<usize>,
|
|
messages: RcSignal<Vec<Message>>,
|
|
}
|
|
|
|
impl Messenger {
|
|
pub fn add_message(&self, mut message: Message) {
|
|
message.id = *self.counter.get_untracked();
|
|
self.counter.set(*self.counter.get_untracked() + 1);
|
|
self.messages.modify().push(message);
|
|
}
|
|
|
|
pub fn info(&self, title: impl Into<String>, text: impl Into<String>) {
|
|
self.add_message(Message::new(title.into(), text.into()));
|
|
}
|
|
|
|
pub fn add_result<T>(
|
|
&self,
|
|
result: anyhow::Result<T>,
|
|
success: Option<impl Into<String>>,
|
|
fail: Option<impl Into<String>>,
|
|
) {
|
|
match result {
|
|
Ok(_) => {
|
|
if let Some(success) = success {
|
|
self.add_message(Message::new(success.into(), String::new()))
|
|
}
|
|
}
|
|
Err(e) => {
|
|
if let Some(fail) = fail {
|
|
self.add_message(Message::new(fail.into(), e.to_string()))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn remove_message(&self) {
|
|
self.messages.modify().remove(0);
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
self.messages.get_untracked().len()
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
pub fn Messages<'a, G: Html>(cx: Scope<'a>) -> View<G> {
|
|
let messages = use_context::<Messenger>(cx);
|
|
|
|
create_effect(cx, move || {
|
|
messages.messages.track();
|
|
|
|
if messages.len() > 0 {
|
|
spawn_local_scoped(cx, async move {
|
|
debug!("Spawn");
|
|
TimeoutFuture::new(MESSAGE_TIME).await;
|
|
|
|
debug!("Remove");
|
|
messages.remove_message();
|
|
});
|
|
}
|
|
});
|
|
|
|
view! { cx,
|
|
div(class="messages") {
|
|
Keyed(
|
|
iterable=&messages.messages,
|
|
view=move |cx, message| {
|
|
view! { cx,
|
|
div(class="message") {
|
|
p(class="message-title") {
|
|
(message.title)
|
|
}
|
|
p(class="message-text") {
|
|
(message.text)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
key=|message| (message.id),
|
|
)
|
|
}
|
|
}
|
|
}
|