gitea_pages/frontend/src/components/notification.rs

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(&notif.notification_type))}>
<div class={classes!("message-header")}>
<p>{ name_from_notification_type(&notif.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) = &notif.message {
{
match message {
NotificationMessage::Text(x) => html! {
{
for x.iter().map(|s| html! {
<>
{ s }
<br />
</>
})
}
},
NotificationMessage::GraphQLError(x) => html! {
{ x }
},
}
}
}
</div>
</article>
</div>
}
}
}