Skip to main content

kayrx_ui/widget/
toast.rs

1use serde::{Deserialize, Serialize};
2use std::time::Duration;
3use crate::fabric::{
4    prelude::*,
5    services::timeout::{TimeoutService, TimeoutTask},
6};
7
8pub enum Msg {
9    RemoveShow,
10}
11
12#[derive(Clone, Serialize, Deserialize)]
13pub enum ToastStatus {
14    Success,
15    Error,
16}
17
18impl std::fmt::Display for ToastStatus {
19    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20        let s = match self {
21            ToastStatus::Success => "success",
22            ToastStatus::Error => "error",
23        };
24        write!(f, "{}", s)
25    }
26}
27
28#[derive(Clone, Serialize, Deserialize)]
29pub struct ToastBody {
30    pub status: ToastStatus,
31    pub title: String,
32    pub delay: u64,
33}
34
35#[derive(Clone, Properties)]
36pub struct Props {
37    pub body: ToastBody,
38}
39
40pub struct Toast {
41    body: ToastBody,
42    #[allow(dead_code)]
43    timeout_task: Option<TimeoutTask>,
44    toast_show: bool,
45}
46
47impl Component for Toast {
48    type Message = Msg;
49    type Properties = Props;
50
51    fn create(props: Self::Properties, link: ComponentLink<Self>) -> Toast {
52        let mut timeout_service = TimeoutService::new();
53        let callback = link.callback(|_| Msg::RemoveShow);
54        let timeout_task = timeout_service.spawn(Duration::from_millis(500), callback);
55
56        Toast {
57            body: props.body,
58            timeout_task: Some(timeout_task),
59            toast_show: true,
60        }
61    }
62
63    fn update(&mut self, msg: Self::Message) -> ShouldRender {
64        match msg {
65            Msg::RemoveShow => {
66                self.toast_show = false;
67            }
68        }
69        true
70    }
71
72    fn view(&self) -> Html {
73        let toast_class = format!("toast toast-{} {}", self.body.status, self.toast_show());
74
75        html! {
76            <div class=toast_class>
77                <div class="toast-header">
78                    { self.body.title.clone() }
79                </div>
80            </div>
81        }
82    }
83}
84
85impl Toast {
86    fn toast_show(&self) -> &str {
87        if self.toast_show {
88            "toast-show"
89        } else {
90            ""
91        }
92    }
93}