4 changed files with 118 additions and 1 deletions
@ -0,0 +1,61 @@
|
||||
use crate::prelude::*; |
||||
use std::collections::HashSet; |
||||
use yew::worker::{Agent, AgentLink, Context, HandlerId}; |
||||
|
||||
pub struct Bus { |
||||
link: AgentLink<Bus>, |
||||
subscribers: HashSet<HandlerId>, |
||||
} |
||||
|
||||
pub enum Request { |
||||
Primary(String), |
||||
Secondary(String), |
||||
Success(String), |
||||
Danger(String), |
||||
Warning(String), |
||||
Info(String), |
||||
Clear, |
||||
} |
||||
|
||||
impl Into<Option<(Color, String)>> for &Request { |
||||
fn into(self) -> Option<(Color, String)> { |
||||
use Request::*; |
||||
match self { |
||||
Primary(alert) => Some((Color::Primary, alert.clone())), |
||||
Secondary(alert) => Some((Color::Secondary, alert.clone())), |
||||
Success(alert) => Some((Color::Success, alert.clone())), |
||||
Danger(alert) => Some((Color::Danger, alert.clone())), |
||||
Warning(alert) => Some((Color::Warning, alert.clone())), |
||||
Info(alert) => Some((Color::Info, alert.clone())), |
||||
Clear => None, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl Agent for Bus { |
||||
type Reach = Context<Self>; |
||||
type Message = (); |
||||
type Input = Request; |
||||
type Output = Option<(Color, String)>; |
||||
|
||||
fn create(link: AgentLink<Self>) -> Self { |
||||
let subscribers = HashSet::new(); |
||||
Self { link, subscribers } |
||||
} |
||||
|
||||
fn update(&mut self, _: Self::Message) {} |
||||
|
||||
fn handle_input(&mut self, input: Self::Input, _id: HandlerId) { |
||||
for sub in self.subscribers.iter() { |
||||
self.link.respond(*sub, (&input).into()); |
||||
} |
||||
} |
||||
|
||||
fn connected(&mut self, id: HandlerId) { |
||||
self.subscribers.insert(id); |
||||
} |
||||
|
||||
fn disconnected(&mut self, id: HandlerId) { |
||||
self.subscribers.remove(&id); |
||||
} |
||||
} |
@ -0,0 +1,52 @@
|
||||
use super::{Alert, Bus}; |
||||
use crate::prelude::*; |
||||
use yew::prelude::*; |
||||
|
||||
pub struct AlertSubscriber { |
||||
link: ComponentLink<Self>, |
||||
alert: Option<(Color, String)>, |
||||
_producer: Box<dyn Bridge<Bus>>, |
||||
} |
||||
|
||||
impl Component for AlertSubscriber { |
||||
type Message = Option<(Color, String)>; |
||||
type Properties = (); |
||||
|
||||
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { |
||||
let _producer = Bus::bridge(link.callback(|msg| msg)); |
||||
let alert = None; |
||||
Self { |
||||
link, |
||||
alert, |
||||
_producer, |
||||
} |
||||
} |
||||
|
||||
fn update(&mut self, msg: Self::Message) -> ShouldRender { |
||||
if self.alert == msg { |
||||
false |
||||
} else { |
||||
self.alert = msg; |
||||
true |
||||
} |
||||
} |
||||
|
||||
fn change(&mut self, _: Self::Properties) -> ShouldRender { |
||||
false |
||||
} |
||||
|
||||
fn view(&self) -> Html { |
||||
if let Some((color, message)) = self.alert.as_ref() { |
||||
html! { |
||||
<Alert |
||||
on_close=self.link.callback(|_| None) |
||||
color=color |
||||
> |
||||
{ message } |
||||
</Alert> |
||||
} |
||||
} else { |
||||
html! {} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue