use bounce::helmet::Helmet; use cynic::QueryBuilder; use yew::prelude::*; use yewdux::prelude::*; use crate::{ components, graphql::{self, ReqwestExt}, stores, }; #[derive(Properties, PartialEq)] pub struct Props { pub name: AttrValue, } pub enum Msg { Void, Done(graphql::GraphQLResult), } struct Repository { name: String, url: String, } pub struct User { notifications_dispatch: Dispatch, loading: bool, repositories: Vec, } impl Component for User { type Message = Msg; type Properties = Props; fn create(ctx: &Context) -> Self { let operation = graphql::queries::UserByName::build(graphql::queries::UserByNameVariables { name: ctx.props().name.to_string(), }); let client = graphql::client(None); ctx.link() .send_future(async move { Msg::Done(client.run_graphql(operation).await) }); Self { notifications_dispatch: Dispatch::subscribe(ctx.link().callback(|_| Msg::Void)), loading: true, repositories: vec![], } } fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { match msg { Msg::Void => false, Msg::Done(x) => { self.loading = false; match x { Ok(resp) => { if let Some(errors) = resp.errors { self.notifications_dispatch.reduce_mut(|notifs| { for e in errors { notifs.push(stores::Notification::danger(Some( components::notification::NotificationMessage::GraphQLError( e, ), ))); } }); false } else { self.repositories = resp .data .unwrap() .user_by_name .repositories .into_iter() .map(|repo| Repository { name: repo.name, url: repo.url, }) .collect(); true } } Err(e) => { self.notifications_dispatch.reduce_mut(|notifs| { notifs.push(stores::Notification::danger(Some( components::notification::NotificationMessage::Text(vec![ e.to_string() ]), ))); }); false } } } } } fn view(&self, ctx: &Context) -> Html { let name = &ctx.props().name; html! { <> { name }
if self.loading {
} else {
>() } />
}
} } }