127 lines
3.8 KiB
Rust
127 lines
3.8 KiB
Rust
use gloo::timers::callback::Interval;
|
|
use std::rc::Rc;
|
|
use yew::prelude::*;
|
|
|
|
use crate::{graphql, stores};
|
|
|
|
pub enum Msg {
|
|
Remove,
|
|
}
|
|
|
|
#[derive(Clone, PartialEq)]
|
|
pub enum NotificationType {
|
|
Dark,
|
|
Primary,
|
|
Link,
|
|
Info,
|
|
Success,
|
|
Warning,
|
|
Danger,
|
|
}
|
|
|
|
pub fn class_from_notification_type(x: &NotificationType) -> &'static str {
|
|
match x {
|
|
NotificationType::Dark => "is-dark",
|
|
NotificationType::Primary => "is-primary",
|
|
NotificationType::Link => "is-link",
|
|
NotificationType::Info => "is-info",
|
|
NotificationType::Success => "is-success",
|
|
NotificationType::Warning => "is-warning",
|
|
NotificationType::Danger => "is-danger",
|
|
}
|
|
}
|
|
|
|
pub fn name_from_notification_type(x: &NotificationType) -> &'static str {
|
|
match x {
|
|
NotificationType::Dark => "Info",
|
|
NotificationType::Primary => "Info",
|
|
NotificationType::Link => "Info",
|
|
NotificationType::Info => "Info",
|
|
NotificationType::Success => "Success",
|
|
NotificationType::Warning => "Warning",
|
|
NotificationType::Danger => "Error",
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, PartialEq)]
|
|
pub enum NotificationMessage {
|
|
Text(Vec<String>),
|
|
GraphQLError(graphql::GraphQLError),
|
|
}
|
|
|
|
#[derive(Properties, PartialEq)]
|
|
pub struct Props {
|
|
pub notifications: Rc<stores::Notifications>,
|
|
pub index: usize,
|
|
pub remove: Rc<Callback<usize, ()>>,
|
|
}
|
|
|
|
pub struct Notification {
|
|
_interval: Interval,
|
|
}
|
|
|
|
impl Component for Notification {
|
|
type Message = Msg;
|
|
type Properties = Props;
|
|
|
|
fn create(ctx: &Context<Self>) -> Self {
|
|
Self {
|
|
_interval: {
|
|
let link = ctx.link().clone();
|
|
|
|
Interval::new(15_000, move || link.send_message(Msg::Remove))
|
|
},
|
|
}
|
|
}
|
|
|
|
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
|
|
match msg {
|
|
Msg::Remove => {
|
|
ctx.props().remove.emit(ctx.props().index);
|
|
|
|
true
|
|
}
|
|
}
|
|
}
|
|
|
|
fn view(&self, ctx: &Context<Self>) -> Html {
|
|
let notif = &ctx.props().notifications.notifications[&ctx.props().index];
|
|
|
|
html! {
|
|
<div class={classes!("block", "notification-slide-from-right")}>
|
|
<article class={classes!("message", class_from_notification_type(¬if.notification_type))}>
|
|
<div class={classes!("message-header")}>
|
|
<p>{ name_from_notification_type(¬if.notification_type) }</p>
|
|
<button
|
|
class={classes!("delete")}
|
|
aria-label="delete"
|
|
onclick={ctx.link().callback(|_| Msg::Remove)}
|
|
/>
|
|
</div>
|
|
<div class={classes!("message-body")}>
|
|
if let Some(message) = ¬if.message {
|
|
{
|
|
match message {
|
|
NotificationMessage::Text(x) => html! {
|
|
{
|
|
for x.iter().map(|s| html! {
|
|
<>
|
|
{ s }
|
|
<br />
|
|
</>
|
|
})
|
|
}
|
|
},
|
|
NotificationMessage::GraphQLError(x) => html! {
|
|
{ x }
|
|
},
|
|
}
|
|
}
|
|
}
|
|
</div>
|
|
</article>
|
|
</div>
|
|
}
|
|
}
|
|
}
|